fix(ui): sanitize markdown before chat DOM insertion

This commit is contained in:
William Valentin
2026-02-15 21:44:32 -08:00
parent 157e99ccb5
commit 22959ea3aa
5 changed files with 183 additions and 16 deletions
+4 -14
View File
@@ -5,7 +5,8 @@
* markdown-rendered responses, slash commands, and web search.
*/
/* global marked, hljs */
/* global hljs */
import { renderSafeMarkdown } from '../lib/markdown.js';
let _currentSession = null;
let _sending = false;
@@ -33,17 +34,6 @@ function escapeHtml(text) {
return div.innerHTML;
}
function renderMarkdown(text) {
try {
if (typeof marked !== 'undefined') {
return marked.parse(text);
}
} catch {
// Fall through to plain text
}
return `<p>${escapeHtml(text)}</p>`;
}
function highlightCode() {
if (typeof hljs !== 'undefined') {
document.querySelectorAll('.chat-messages pre code').forEach(block => {
@@ -60,7 +50,7 @@ function createMessageEl(role, content) {
div.className = `message ${role}`;
if (role === 'assistant' || role === 'system') {
div.innerHTML = renderMarkdown(content);
div.innerHTML = renderSafeMarkdown(content);
setTimeout(highlightCode, 0);
} else {
div.textContent = content;
@@ -607,7 +597,7 @@ async function sendMessage(client, overrideText) {
// Replace placeholder with actual response
placeholder.classList.remove('streaming-cursor');
const content = done?.content ?? done?.text ?? '(no response)';
placeholder.innerHTML = renderMarkdown(content);
placeholder.innerHTML = renderSafeMarkdown(content);
placeholder.appendChild(createMessageActions('assistant'));
setTimeout(highlightCode, 0);
} catch (err) {