mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 11:48:29 +01:00
Answer security round 1: 0 🔴, 1 🟡 (0 misread); build the refusal's path in linear time
This commit is contained in:
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
import vm from 'node:vm'
|
||||
|
||||
import type { AdfDocument } from './document.ts'
|
||||
import type { AdfDocument, AdfNode } from './document.ts'
|
||||
import type { JsonValue } from '../json-value.ts'
|
||||
import { adfToHtml, adfToLosslessMarkdown, adfToPortableMarkdown } from '../index.ts'
|
||||
import { adfDocumentFault, isAdfDocument, writableContent } from './document.ts'
|
||||
@@ -158,3 +158,12 @@ test('writes a card holding no link mark, and a node type it does not know holdi
|
||||
const marked = { content: [{ attrs: { url: 'https://example.com/roadmap' }, marks: [comment], type: 'inlineCard' }, { marks: [link], type: 'futureInline' }], type: 'paragraph' }
|
||||
for (const write of [adfToHtml, adfToLosslessMarkdown, adfToPortableMarkdown]) assert.equal(write({ content: [marked], type: 'doc', version: 1 }).ok, true)
|
||||
})
|
||||
|
||||
test('names a link-marked card at any depth by its path alone, in time linear in the depth', () => {
|
||||
const depth = 100_000
|
||||
let node: AdfNode = { attrs: { url: 'https://example.com/' }, marks: [{ attrs: { href: 'https://example.com/' }, type: 'link' }], type: 'inlineCard' }
|
||||
for (let level = 0; level < depth; level += 1) node = { content: [node], type: 'panel' }
|
||||
const refused = writableContent({ content: [node], type: 'doc', version: 1 })
|
||||
assert.equal(!refused.ok && refused.error.path.length, 2 * (depth + 1))
|
||||
assert.deepEqual(!refused.ok && refused.error.path.slice(0, 4), ['content', 0, 'content', 0])
|
||||
})
|
||||
|
||||
+2
-1
@@ -154,7 +154,8 @@ function refusedShape(content: readonly AdfNode[]): Result<never> | undefined {
|
||||
for (let step = pending.pop(); step !== undefined; step = pending.pop()) {
|
||||
if (step.node.type === 'inlineCard' && nodeMarks(step.node).some(({ type }) => type === 'link')) {
|
||||
const path: (number | string)[] = []
|
||||
for (let up: Step | undefined = step; up !== undefined; up = up.parent) path.unshift('content', up.index)
|
||||
for (let up: Step | undefined = step; up !== undefined; up = up.parent) path.push(up.index, 'content')
|
||||
path.reverse()
|
||||
return failure('unsupported-node-shape', 'an inlineCard takes no link mark: this one holds one', path)
|
||||
}
|
||||
for (const child of nodeContent(step.node).map((node, index) => ({ index, node, parent: step })).reverse()) pending.push(child)
|
||||
|
||||
Reference in New Issue
Block a user