mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
perf: validate mobile review table delimiters by cell (#20317)
This commit is contained in:
@@ -30,8 +30,6 @@ const HEADING = /^(#{1,6})\s+(.*)$/
|
||||
const FENCE = /^```/
|
||||
// Captures the fence info string (language) on the opening fence, e.g. ```mermaid.
|
||||
const FENCE_OPEN = /^```\s*([^\s`]*)/
|
||||
// A GFM table delimiter row: cells of dashes with optional leading/trailing colons.
|
||||
const TABLE_DELIM = /^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/
|
||||
const QUOTE = /^>\s?(.*)$/
|
||||
const HR = /^(?:---+|\*\*\*+|___+)\s*$/
|
||||
const UNORDERED = /^\s*[-*+]\s+(.*)$/
|
||||
@@ -114,7 +112,7 @@ function parseLines(content: string): MarkdownBlock[] {
|
||||
|
||||
// GFM pipe table: a header row immediately followed by a delimiter row.
|
||||
// Requires the delimiter row so plain prose with a stray `|` isn't captured.
|
||||
if (line.includes('|') && i + 1 < lines.length && TABLE_DELIM.test(lines[i + 1])) {
|
||||
if (line.includes('|') && i + 1 < lines.length && isTableDelimiter(lines[i + 1])) {
|
||||
flushParagraph()
|
||||
const headers = splitTableRow(line)
|
||||
const align = parseAlignRow(lines[i + 1])
|
||||
@@ -217,6 +215,10 @@ function splitTableRow(line: string): string[] {
|
||||
return cells
|
||||
}
|
||||
|
||||
function isTableDelimiter(line: string): boolean {
|
||||
return splitTableRow(line).every((cell) => /^:?-+:?$/.test(cell))
|
||||
}
|
||||
|
||||
// Reads alignment from a delimiter row's colons: `:--` left, `:-:` center, `--:` right.
|
||||
function parseAlignRow(line: string): CellAlign[] {
|
||||
return splitTableRow(line).map((spec) => {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { runInNewContext } from 'node:vm'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { parseMarkdownBlocks } from './markdown-blocks'
|
||||
|
||||
const ORIGINAL_DELIMITER = /^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/
|
||||
|
||||
function isParsedTable(delimiter: string): boolean {
|
||||
return parseMarkdownBlocks(`a|b\n${delimiter}`)[0]?.kind === 'table'
|
||||
}
|
||||
|
||||
describe('review Markdown table delimiter cost', () => {
|
||||
it.each([
|
||||
{ name: 'leading whitespace', delimiter: ' '.repeat(60_000) + 'x' },
|
||||
{ name: 'trailing cell whitespace', delimiter: '-|-' + ' '.repeat(60_000) + 'x' }
|
||||
])('rejects $name without backtracking', ({ delimiter }) => {
|
||||
// Interrupt synchronous regex regressions instead of hanging the test worker.
|
||||
const blocks = runInNewContext(
|
||||
'parse(input)',
|
||||
{ parse: parseMarkdownBlocks, input: `a|b\n${delimiter}` },
|
||||
{ timeout: 250 }
|
||||
)
|
||||
expect(blocks).toEqual([{ kind: 'paragraph', text: `a|b\n${delimiter}` }])
|
||||
})
|
||||
|
||||
it('preserves the original delimiter grammar over generated rows', () => {
|
||||
const parts = ['', '-', '--', ':', ':-:', ':--', '--:', '|', ' ', '\t', '\r', '\\|', 'x']
|
||||
for (const left of parts) {
|
||||
for (const middle of parts) {
|
||||
for (const right of parts) {
|
||||
const row = left + middle + right
|
||||
expect(isParsedTable(row), JSON.stringify(row)).toBe(ORIGINAL_DELIMITER.test(row))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user