Skip to content

fix: validate literal JSON property names consistently - #131

Open
fitchmultz wants to merge 5 commits into
sagold:mainfrom
fitchmultz:fix/own-json-properties
Open

fitchmultz wants to merge 5 commits into
sagold:mainfrom
fitchmultz:fix/own-json-properties

Conversation

@fitchmultz

@fitchmultz fitchmultz commented Sep 21, 2026 •

Copy link
Copy Markdown

Summary

Preserve literal JSON member names in validation, schema traversal, and references. On 11.6.2, ordinary undeclared __proto__, constructor, and toString members can throw or bypass validation; a declared __proto__ can disappear from compiled dictionaries. Unescaped schema keys can also resolve to a different location.

  • Use prototype-free property, definition, and dependency dictionaries and own-property lookups. Preserve those keys during merging and traversal.
  • Keep $defs and definitions separate when both are authored, including overlapping names. Retain the existing single-dictionary alias when only one spelling is present, without duplicate visits.
  • Build schema locations with the native JSON Pointer encoder. Resolve equivalent raw and percent-encoded pointer fragments consistently across all five drafts, including pattern properties and dependencies under root/nested identifiers. A literal percent-encoded-looking key remains distinct. Encoded slash separators are recognized before the native pointer parser decodes each token, including an encoded leading slash. Named-anchor fragments normalize percent-encoded unreserved characters using the existing uri-js normalizer; document identifiers and reserved anchor characters retain their distinctions.
  • Preserve missing-definition diagnostics and the existing shorthand reference API.
  • Default settings.propertyBlacklist to [], removing the implicit _id additional-property exemption. Callers can explicitly configure ["_id"] to retain that legacy behavior.

No input keys are prohibited or removed. Declared special names remain ordinary data. Reference handling stays in the library's native URI/reference owners; no alternate resolver or parser aliases are introduced. This is a member-name correctness correction, with no exploit claim.

Verification

Based on main 65578c185fc324ebf8fcc8f6e654e85cbfab4da8.

  • Final full unit/spec/in-process Bowtie suite: 8,847 passing, 12 existing pending.
  • Six encoded-pointer regressions fail against the prior implementation before target validation, distinguishing actual nested targets from misleading literal slash/percent/hash keys. Final CJS and ESM controls each pass 30 groups / 90 values; pointer cases cover all five drafts, uppercase/lowercase encoding, mixed encoded separators and single percent decoding.
  • Eight encoded-anchor regressions fail against their previous production implementation, before target validation. Final controls cover ordinary and dynamic anchors, local and registered remote documents, all five supported drafts, valid/wrong-type/wrong-value outcomes, and preservation of reserved/literal-percent/document-ID distinctions. Existing location, URI, diagnostics, merge, navigation and own-member tests are retained.
  • Independent review found a raw $ reference regression in an intermediate candidate. Before the correction, eight draft/keyword combinations failed; final source and built-runtime controls enforce positive, wrong-type, and wrong-value expectations. Parent rerun passes all 30 alias records and 14 preservation controls, including both merge orders and distinct document/anchor spellings.
  • Normal ESM/CJS/IIFE and declaration builds pass; attw reports no problems. Final CJS and ESM encoded-anchor checks each pass 28 schema groups / 84 values. Earlier direct and three-form runtime controls remain retained evidence for the unchanged member-name behavior.
  • Incremental-file lint and whitespace checks pass. Repository-wide diagnostics match the recorded unchanged baseline: 3 unused-import lint errors, 4 source-type diagnostics, 107 test-type diagnostics. Those full checks are not claimed green.
  • Source/test changes only; no dependency, lockfile, or generated distribution changes. Package commands use pnpm 10.34.5. No external Docker Bowtie, stress, or network demonstration was run.

The shared URI normalizer composes with #133's separate reference-scope and anonymous-root identity corrections; this PR preserves the existing empty-root branching behavior. Named-anchor normalization follows RFC 3986 §§2.3 and 6.2.2.2. Pointer fragments follow RFC 6901 §6: separators are decoded before token selection. Only fragments are normalized; literal percent sequences are decoded once and document paths remain unchanged.

@fitchmultz

Copy link
Copy Markdown
Author

Local verification is complete for 81d9359: 1,067 unit tests and 7,513 spec tests pass, plus the native build and CJS/ESM smoke checks. The upstream CI run is currently action_required with no jobs started; a maintainer needs to approve the fork workflow run.

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