diff --git a/desktop/src/components/markdown/MarkdownRenderer.test.tsx b/desktop/src/components/markdown/MarkdownRenderer.test.tsx index 164897b4..7b53e9e4 100644 --- a/desktop/src/components/markdown/MarkdownRenderer.test.tsx +++ b/desktop/src/components/markdown/MarkdownRenderer.test.tsx @@ -263,6 +263,45 @@ describe('MarkdownRenderer', () => { expect(link).toHaveAttribute('rel', expect.stringContaining('noopener')) }) + it('strips style tags from assistant text before injecting markdown html', () => { + const { container } = render( + ', + '', + '', + '', + '', + '', + '', + 'unsafe preview content', + '', + ].join('\n')} + />, + ) + + expect(container.querySelector('style')).not.toBeInTheDocument() + expect(container).not.toHaveTextContent('overflow: hidden') + expect(screen.getByText(/开始构建完整的 Web Linux 桌面环境/)).toBeInTheDocument() + }) + + it('strips inline style attributes from assistant markdown html', () => { + const { container } = render( + assistant text'} + />, + ) + + const injectedDiv = screen.getByText('assistant text') + expect(injectedDiv).toBeInTheDocument() + expect(injectedDiv).not.toHaveAttribute('style') + expect(container.innerHTML).not.toContain('position: fixed') + }) + it('lets callers intercept markdown link clicks', () => { const onLinkClick = vi.fn().mockReturnValue(true) render( diff --git a/desktop/src/components/markdown/MarkdownRenderer.tsx b/desktop/src/components/markdown/MarkdownRenderer.tsx index 3226940f..37de1b82 100644 --- a/desktop/src/components/markdown/MarkdownRenderer.tsx +++ b/desktop/src/components/markdown/MarkdownRenderer.tsx @@ -39,6 +39,12 @@ const MERMAID_DIAGRAM_START = /^(graph|flowchart|sequenceDiagram|classDiagram|st const CODE_FENCE_START = /^ {0,3}(`{3,}|~{3,})/ const MATH_RENDER_CACHE_LIMIT = 200 const mathRenderCache = new Map() +const MARKDOWN_SANITIZE_CONFIG = { + ADD_TAGS: ['use'], + ADD_ATTR: ['xlink:href'], + FORBID_TAGS: ['style'], + FORBID_ATTR: ['style'], +} function normalizeCodeLanguage(language: string | undefined): string | undefined { const normalized = language?.trim().split(/\s+/)[0]?.toLowerCase() @@ -267,10 +273,7 @@ function renderMath(block: MathBlock): string { } function enhanceMarkdownHtml(html: string, mathBlocks: MathBlock[]): string { - const cleanHtml = DOMPurify.sanitize(html, { - ADD_TAGS: ['use'], - ADD_ATTR: ['xlink:href'], - }) + const cleanHtml = DOMPurify.sanitize(html, MARKDOWN_SANITIZE_CONFIG) const needsDomEnhancement = mathBlocks.length > 0 || /<(?:a|table)\b/i.test(cleanHtml) if (!needsDomEnhancement) {