Skip to content

fix(json): reject backtick as hex digit in \u escapes#3678

Draft
tonyfettes wants to merge 1 commit into
moonbitlang:mainfrom
tonyfettes:fix/json-lex-hex-backtick
Draft

fix(json): reject backtick as hex digit in \u escapes#3678
tonyfettes wants to merge 1 commit into
moonbitlang:mainfrom
tonyfettes:fix/json-lex-hex-backtick

Conversation

@tonyfettes

Copy link
Copy Markdown
Contributor

Summary

@json.parse accepts backtick as hex digit 9 in \uXXXX escapes: the invalid JSON "\ubcd"parses successfully to"\u{9BCD}" ("鯍") instead of raising ParseError`.

The hex letter branch of ParseContext::lex_hex_digits case-folds with c & ~32 and then only checks the upper bound:

let d = (c.to_int() & (32).lnot()) - 'A'.to_int() + 10
if d > 15 { ctx.invalid_char(shift=-1) }

Backtick (0x60) folds to '@' (0x40), yielding d == 9, which passes d > 15. It is the only character in the codespace with this property (0x41–0x5F fold to themselves; of 0x60–0x7F only 0x60 lands below 'A' after folding). Fix: also reject d < 10, since every valid letter digit folds into 10–15.

Changes

  • json/lex_string.mbt: add the missing lower-bound check (d < 10 || d > 15) with a comment explaining the backtick case.
  • json/lex_string_test.mbt: regression tests — \u`bcd, \u@bcd, \u1G23, \u1g23 now raise InvalidChar, and boundary digits (0/9/a/f/A/F) still parse.

No public API change (pkg.generated.mbti untouched).

Testing

  • moon test json — 174/174 passing
  • moon fmt / moon info — clean

🤖 Generated with Claude Code

The hex letter branch of lex_hex_digits case-folds with `c & ~32` and
only checks the upper bound `d > 15`. Backtick (0x60) folds to '@'
(0x40), yielding d == 9, so it slipped through as hex digit 9: the
invalid JSON `"\u`bcd"` parsed successfully as U+9BCD instead of
raising ParseError. It is the only character in the codespace with
this property; add the missing lower-bound check `d < 10`.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant