fix(ui): harden TeX delimiter parsing

This commit is contained in:
fz
2026-08-05 15:06:38 +08:00
parent 3b86568577
commit 7c90422f34
8 changed files with 118 additions and 17 deletions

View File

@@ -207,6 +207,13 @@ describe('MarkdownText', () => {
source: '\\(\\frac{1}{5}\n+\\frac{1}{7}\\)',
math: 1,
display: 0,
value: '\\frac{1}{5}\n+\\frac{1}{7}',
},
{
source: '\\[a\\\\\nb\\]',
math: 1,
display: 1,
value: 'a\\\\\nb',
},
{
source: '> \\[\n> \\frac{1}{5}\n> \\]',
@@ -225,6 +232,9 @@ describe('MarkdownText', () => {
expect(rendered.container.querySelectorAll('.katex')).toHaveLength(item.math)
expect(rendered.container.querySelectorAll('.katex-display')).toHaveLength(item.display)
expect(rendered.container.querySelector('.katex-error')).toBeNull()
if ('value' in item) {
expect(rendered.container.querySelector('annotation')?.textContent).toBe(item.value)
}
rendered.unmount()
}
@@ -239,8 +249,10 @@ describe('MarkdownText', () => {
const sources = [
'$$\n\\theta\n$$',
'$$$\\theta$$$',
'$$a$b\nc',
' \\[\n \\theta\n \\]',
'\\(\\theta',
'\\[\n\\[',
'> \\[\nnot a quoted continuation\n\\]',
]
@@ -251,6 +263,29 @@ describe('MarkdownText', () => {
}
})
it('renders escaped dollars and even backslash pairs before closing fences', () => {
const source = [
String.raw`$$100\$$$`,
'',
String.raw`\(a\\\)`,
'',
String.raw`\[b\\\]`,
].join('\n')
const { container } = render(<MarkdownText text={source} />)
const values = [...container.querySelectorAll('annotation')].map(node => node.textContent)
expect(values).toEqual([String.raw`100\$`, String.raw`a\\`, String.raw`b\\`])
expect(container.querySelector('.katex-error')).toBeNull()
})
it('bounds fallback work for repeated unclosed backslash delimiters', () => {
const startedAt = performance.now()
const { container } = render(<MarkdownText text={'\\(x '.repeat(6_400)} />)
expect(performance.now() - startedAt).toBeLessThan(1_000)
expect(container.querySelector('.katex')).toBeNull()
})
it('leaves TeX-looking fenced code literal', () => {
const source = '```tex\n\\[\\frac{1}{5}\\]\n$$x \\tag{1}$$\n```'
const { container } = render(<MarkdownText text={source} />)