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

Round-trip JSON keys holding a backslash, quote or control character, and generate them in the properties

This commit is contained in:
2026-10-08 12:15:16 +02:00
committed by Lillem4n
parent 8d1c75fa8b
commit bfe26dd438
4 changed files with 68 additions and 14 deletions
@@ -0,0 +1,53 @@
{
"content": [
{
"attrs": {
"extensionKey": "toc",
"extensionType": "com.atlassian.confluence.macro.core",
"parameters": {
"back\\slash": 1,
"nested\\": {
"in\\\"ner": true
},
"nul\u0000": 2,
"say \"hi\"": 3,
"tab\tand\u001fus": 4
}
},
"type": "extension"
},
{
"attrs": {
"back\\slash": 1,
"nul\u0000": 2,
"say \"hi\"": 3,
"tab\tand\u001fus": 4
},
"type": "unknownBlock"
},
{
"content": [
{
"text": "See ",
"type": "text"
},
{
"attrs": {
"back\\slash": 1,
"nul\u0000": 2,
"say \"hi\"": 3,
"tab\tand\u001fus": 4
},
"type": "unknownInline"
},
{
"text": " now.",
"type": "text"
}
],
"type": "paragraph"
}
],
"type": "doc",
"version": 1
}
@@ -0,0 +1,14 @@
!adf:extension {extensionKey=toc extensionType="com.atlassian.confluence.macro.core" parameters="{\"back\\\\slash\":1,\"nested\\\\\":{\"in\\\\\\\"ner\":true},\"nul\\u0000\":2,\"say \\\"hi\\\"\":3,\"tab\\tand\\u001fus\":4}"}
```adf:unknownBlock
{
"attrs": {
"back\\slash": 1,
"nul\u0000": 2,
"say \"hi\"": 3,
"tab\tand\u001fus": 4
}
}
```
See !adf:carry{json="{\"attrs\":{\"back\\\\slash\":1,\"nul\\u0000\":2,\"say \\\"hi\\\"\":3,\"tab\\tand\\u001fus\":4},\"type\":\"unknownInline\"}"} now.
+1 -4
View File
@@ -43,10 +43,7 @@ const numberValue = fc.oneof(
{ arbitrary: fc.constant(-0), weight: 1 },
)
// V8's JSON.parse returns a wrong key after parsing a key holding an escaped backslash (https://issues.chromium.org/issues/521080746); Bun is unaffected.
const keyPiece = fc
.oneof({ arbitrary: markdownPieces, weight: 4 }, { arbitrary: fc.string({ maxLength: 1, minLength: 1, unit: 'grapheme' }), weight: 1 })
.filter((piece) => !/[\\"\x00-\x1f]/.test(piece))
const keyPiece = fc.oneof({ arbitrary: markdownPieces, weight: 4 }, { arbitrary: fc.string({ maxLength: 1, minLength: 1, unit: 'grapheme' }), weight: 1 })
export const jsonKey = fc.string({ maxLength: 8, unit: keyPiece })
export const { jsonValue } = fc.letrec<{ jsonValue: JsonValue }>((tie) => ({
-10
View File
@@ -24,7 +24,6 @@
| ID | Release | Exempt | Item | R | S | A | G | Goals | Score |
|---|---|---|---|---|---|---|---|---|---|
| 64 | 0.2.0 | defect | **Read back unchanged on V8 every JSON key the emitter writes, with a fixture whose key holds `\`, `"` or a control character.** | 4 | 4 | 6 | 8 | 1, 8 | 23.0 |
| 43 | 0.2.0 | decision | **Give each markdown input its own reader, strict to its own standard.** | 6 | 7 | 8 | 9 | 4, 5 | 20.3 |
| 65 | 0.2.0 | defect | **Read an image not alone in its paragraph as its alt text linked to its URL, and a titled image alone in its paragraph as the image captioned with its title.** | 5 | 5 | 7 | 7 | 4, 5, 7 | 17.1 |
| 49 | 0.2.0 | | **Read a list whose bullet or ordered delimiter changes as two lists, in both readers, and retire `!adf:listBreak`.** | 4 | 5 | 5 | 8 | 4, 5 | 15.5 |
@@ -64,15 +63,6 @@
## Details
### 64. Read back unchanged on V8 every JSON key the emitter writes, with a fixture whose key holds `\`, `"` or a control character.
`property-harness.ts` strips `\`, `"` and control characters from generated JSON keys, citing V8's
`JSON.parse` returning a wrong key for an escaped backslash. The library reads `json` attributes
(`directive-syntax.ts`) and both carries (`opaque-carry.ts`) through that `JSON.parse`, so on Node,
Deno and Chrome the round-trip would refuse its own output or read back a different key; the fixture
tells which. Confirm with a fixture first; then read JSON with our own parser or record the gap with
an ending item. Found by the README-goals audit, 2026-10-03.
### 43. Give each markdown input its own reader, strict to its own standard.
Today `markdownToAdf` reads CommonMark and the lossless flavour as one input: text shaped like a