Skip to content

fix(schema_engine): follow ECMA-262 semantics in pattern - #136

Open
jd-lara wants to merge 1 commit into
JuliaComputing:mainfrom
QXT-Energy:jd/ecma-262-patterns
Open

jd-lara wants to merge 1 commit into
JuliaComputing:mainfrom
QXT-Energy:jd/ecma-262-patterns

Conversation

@jd-lara

@jd-lara jd-lara commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Summary

JSON Schema defines pattern and patternProperties as ECMA-262 regular expressions.
_ecma_regex compiles them with Julia's default PCRE options. Those include UCP and
lack DOLLAR_ENDONLY, so several ECMA-262 rules did not hold:

Pattern Input ECMA-262 Before
^abc$ "abc\n" no match match ($ before a trailing newline)
^\d$ "߀" (NKO digit zero) no match match (UCP)
^\w$ "é" no match match (UCP)
^\s$ U+FEFF, U+2029 match no match
^\p{digit}+$ "߀" match compile error

The official suite's optional/ecmascript-regex.json covers these cases, but it did not
run.

Changes (src/schema_engine/dialects.jl)

  • Compile with DOLLAR_ENDONLY and without UCP. $ matches only at the end, and \d,
    \w and \b are ASCII, as in ECMA-262. \p{…} still matches Unicode properties,
    because it needs only UTF mode.
  • Translate \s and \S to the ECMA-262 white-space set: tab, vertical tab, form feed,
    every Zs, U+FEFF, and the line terminators LF, CR, U+2028 and U+2029. Julia compiles
    with ALT_BSUX, so the code points use the \uhhhh form.
  • Add Unicode's extra General_Category aliases to ECMA_GENERAL_CATEGORIES: digit,
    cntrl, punct and Combining_Mark.

Limit: inside a character class, [\S] keeps PCRE's ASCII meaning, because PCRE
cannot remove a set from inside a class. \s inside a class is translated.

Tests

  • test/schema_engine/official.jl also runs optional/ecmascript-regex.json for each
    draft (2020-12, 2019-09, 7, 6, 4) when OPENAPI_SCHEMA_SUITE=all. Before this change,
    the 2020-12 file stops with a compile error at \p{digit}. The other cases also fail:
    \d, \D, \w, \W, \s, \S. After it, all 74 tests pass for each draft.
  • test/schema_engine/compiled.jl has unit tests that run by default: the trailing
    newline, ASCII \d and \w, Unicode \s (also inside a class), \p{digit} and
    \p{Letter}.

OPENAPI_SCHEMA_SUITE=all julia --project=. -e 'using Pkg; Pkg.test()': "OpenAPI tests
passed". 12061 passes, 0 failures, 0 errors. Official JSON Schema suite: 10624 of 10624.

Context

This PR is independent of #135 (date-time-local). Both come from the Sienna SDK
(Sienna-Platform/SiennaSchemas#109), which relies on pattern for RFC 3339 timestamps.
Without DOLLAR_ENDONLY, "2030-01-01T00:00:00\n" passes a ^…$ timestamp pattern.

JSON Schema defines `pattern` and `patternProperties` as ECMA-262
regular expressions. Julia compiles PCRE with UCP and without
DOLLAR_ENDONLY, so `$` matched before a trailing newline and `\d`,
`\w` matched Unicode digits and letters.

- Compile with DOLLAR_ENDONLY and without UCP: `$` matches only at the
  end, and `\d`, `\w`, `\b` are ASCII.
- Translate `\s` and `\S` to ECMA-262 white space: tab, vertical tab,
  form feed, every Zs, U+FEFF, and the line terminators.
- Map Unicode's extra General_Category aliases (digit, cntrl, punct,
  Combining_Mark).
- Run optional/ecmascript-regex.json from the official suite for each
  draft, and add unit tests that run by default.

This branch has not been deployed

No deployments
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