Commit 5e96c8c
committed
Recover round-trip for associative keys with non-varname characters
`isExplodedPairBoundary` was using RFC 6570 varname rules (`isVarcharAt`
plus the point-continuation logic in `readPairKeyEnd`) to detect the
start of the next exploded associative entry. Associative keys are
emitted through `encodeValue` on the expansion side, so the legal key
character set is the full unreserved/reserved alphabet, not just
varname characters. Round-trip matches against keys like `b-c`, `~x`,
or any key containing `-`, `!`, `~`, etc. silently failed: the
boundary detector skipped past the next separator and the entire tail
of the body was treated as one value, leaving the round-trip check to
reject the only decomposition the matcher had reached.
Switch the boundary check to a value-driven scan: at each separator,
walk forward until the next `=` (boundary) or the next separator
(no boundary). The detector still fires only at separator positions,
so an `=` inside an `allowReserved` value cannot be mistaken for a
key/value split. The now-unused `readPairKeyEnd` helper and the
`isVarcharAt` import are removed.
Adds a regression test covering `{keys*}` against `a=1,b-c=2`, plus a
companion test that pins the parser's rejection of the seven actual
1-byte control characters (NUL/SOH/TAB/LF/CR/US/DEL) via
`String.fromCodePoint`. The CTL test documents the boundary that the
`wrong.json` fixture *names* but does not exercise (since JSON parses
the double-escaped `` sequences in those fixtures to 6-character
backslash strings, not control bytes).
Reported in PR #758
(CodeRabbit, 2026-05-11).
Assisted-by: Claude Opus 4.7 (1M context)1 parent c611249 commit 5e96c8c
2 files changed
Lines changed: 38 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
351 | 351 | | |
352 | 352 | | |
353 | 353 | | |
354 | | - | |
355 | | - | |
356 | | - | |
357 | | - | |
358 | | - | |
359 | | - | |
360 | | - | |
361 | | - | |
362 | | - | |
363 | | - | |
364 | | - | |
365 | | - | |
366 | | - | |
367 | | - | |
368 | | - | |
369 | | - | |
370 | | - | |
371 | | - | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
372 | 357 | | |
373 | | - | |
374 | | - | |
| 358 | + | |
| 359 | + | |
375 | 360 | | |
376 | 361 | | |
377 | 362 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
129 | 129 | | |
130 | 130 | | |
131 | 131 | | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
0 commit comments