3
0
mirror of https://github.com/larvit/adf-codec.git synced 2026-11-12 19:58:28 +01:00

Answer prose round 1: 0 🔴, 9 🟡; the retry paragraph, the guarantees, the changelog and the code-list entry each say one thing once, the engine-limit message names what it covers, the persona line excepts engine-limit by the maintainer's call, and the error row's split is filed as item 111

This commit is contained in:
2026-10-13 19:49:53 +02:00
parent 7217a2b7f1
commit fc5d5c7e5d
11 changed files with 46 additions and 40 deletions
+1 -2
View File
@@ -70,8 +70,7 @@ test('refuses text past V8\'s longest string', () => {
assert.equal(markdown(result), tooLong)
})
// One escape past the most entries V8's Set holds.
test('escapes more characters in a line than a Set holds', () => {
test('escapes more characters in a line than V8\'s Set holds', () => {
const stars = '*'.repeat(2 ** 24 + 1)
assert.equal(markdown(adfToLosslessMarkdown(document(paragraph({ text: stars, type: 'text' })))), `${'\\*'.repeat(2 ** 24 + 1)}\n`)
})
+1 -1
View File
@@ -123,7 +123,7 @@ export function commonMarkSpelling(node: AdfNode, path: ConvertErrorPath, depth:
return success(readable.value.spelling !== 'directive')
}
// Only an asked node's spelling is kept, and reading it drops it: the walk above spells the node into its own text, so no level of a subtree holds that text twice.
// Only an `asked` call keeps a spelling, and any read drops it: the ancestor that reads it spells it into its own text, so no two levels hold that text.
function readableBlock(node: AdfNode, path: ConvertErrorPath, depth: number, writing: Writing, caller: 'asked' | 'walked'): Result<EmittedBlock> | undefined {
const { memo } = writing
const kept = memo?.get(node)
+2 -2
View File
@@ -37,7 +37,7 @@ type Escapings = (index: number) => InlineEscaping | undefined
// Where a segment's first character landed in the output.
type PlacedSegment = { segment: InlineSegment; start: number }
// The run's escapable characters, or its characters before `end`.
// Which of a run's characters escape: every escapable one, or every one before `end`.
type RunEscapes = { end: number; escapable: false } | { escapable: true }
type EscapeWalk = {
@@ -111,7 +111,7 @@ function escape(segments: readonly InlineSegment[], container: LineContainer, cl
}
function backslashed(segments: readonly InlineSegment[], scan: string, escaped: Uint8Array): { output: string; placed: PlacedSegment[] } {
// Joined a few thousand pieces at a time: an array element per escape would cost more than the character it escapes.
// The output joins 4096 pieces at a time: an array element per escape would cost more than the character it escapes.
const chunks: string[] = []
let pieces: string[] = []
let from = 0
+2 -2
View File
@@ -27,7 +27,7 @@ test('refuses a string past the bound as too long on every engine, and any other
assert.deepEqual(withinEngineLimits(thrown('RangeError', 'Invalid string length')), tooLong())
assert.deepEqual(withinEngineLimits(thrown('InternalError', 'allocation size overflow')), tooLong())
assert.deepEqual(withinEngineLimits(thrown('RangeError', 'Out of memory')), {
error: { code: 'engine-limit', message: 'the conversion passed this JavaScript engine\'s longest string or array, or ran it out of memory (Out of memory)', path: [] },
error: { code: 'engine-limit', message: 'the conversion passed a limit of this JavaScript engine on a string, array, Map or Set, or ran it out of memory (Out of memory)', path: [] },
ok: false,
})
const code = (message: string): string | undefined => {
@@ -43,7 +43,7 @@ test('refuses a string past the bound as too long on every engine, and any other
withinEngineLimits(() => {
throw 'out of memory'
}),
{ error: { code: 'engine-limit', message: 'the conversion passed this JavaScript engine\'s longest string or array, or ran it out of memory (out of memory)', path: [] }, ok: false },
{ error: { code: 'engine-limit', message: 'the conversion passed a limit of this JavaScript engine on a string, array, Map or Set, or ran it out of memory (out of memory)', path: [] }, ok: false },
)
assert.deepEqual(
withinEngineLimits(() => success('x')),
+2 -2
View File
@@ -3,7 +3,7 @@ import { failure, success, type Result } from '../result.ts'
// V8's longest string, refused on every engine so a document converts alike everywhere (docs/decisions.md §Markdown past V8's longest string is refused on every engine).
export const longestMarkdown = 2 ** 29 - 24
// Measured on Firefox 155, Node 24 and Bun 1.4, and SpiderMonkey's array length from its js.msg. SpiderMonkey's overflow and V8's string overflow both mean a string past longestMarkdown; the others name an engine's own limit or its memory running short.
// Measured on Firefox 155, Node 24 and Bun 1.4; SpiderMonkey's `invalid array length` is taken from its js.msg. SpiderMonkey's overflow and V8's string overflow both mean a string past longestMarkdown; the others name an engine's own limit or its memory running short.
const pastLongestString = ['InternalError: allocation size overflow', 'RangeError: Invalid string length']
const pastEngineLimit = [
'RangeError: Array buffer allocation failed',
@@ -50,5 +50,5 @@ export function withinEngineLimits<T>(convert: () => Result<T>): Result<T> {
}
function engineLimit<T>(thrown: string): Result<T> {
return failure('engine-limit', `the conversion passed this JavaScript engine's longest string or array, or ran it out of memory (${thrown})`, [])
return failure('engine-limit', `the conversion passed a limit of this JavaScript engine on a string, array, Map or Set, or ran it out of memory (${thrown})`, [])
}
+1 -1
View File
@@ -341,7 +341,7 @@ test('refuses the directive form of a blockquote opening with a code span', () =
assert.equal(content(losslessMarkdownToAdf('!adf:blockquote\n` `` `\n!adf:/blockquote\n')), 'unsupported-node-shape: blockquote takes the CommonMark spelling, not the directive form')
})
// Some 1000 characters short of V8's longest string, which the quote's `> ` on each of its 600 lines passes; reading that much outlasts Bun's 5 s default timeout.
// The input is some 1000 characters short of V8's longest string; the `> ` the quote adds to each of its 600 lines passes it. Reading this much outlasts Bun's 5 s default timeout.
test('refuses a blockquote directive whose CommonMark spelling would pass V8\'s longest string', { timeout: 120_000 }, () => {
const fence = `\`\`\`\n${`${'a'.repeat(894_782)}\n`.repeat(300)}\`\`\`\n`
assert.equal(