Create objects for pointer tokens that cannot be array indices - #5358
Draft
nlohmann wants to merge 1 commit into
Draft
Create objects for pointer tokens that cannot be array indices#5358nlohmann wants to merge 1 commit into
nlohmann wants to merge 1 commit into
Conversation
When operator[](json_pointer) traverses a level that does not exist yet, the null value is turned into an array or an object depending on the reference token. The check only tested whether all characters are digits, so tokens that can never be a valid array index selected an array and then failed: - "01" (and any other token with a leading '0') threw parse_error.106 - the empty token threw out_of_range.404 Both tokens are valid object keys, and both work when the level already exists as an object, so creating the level changed the outcome. Test the token against the RFC 6901, Sect. 4 grammar for array indices instead, so that such tokens create an object. This only affects pointers that threw before. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
nlohmann
force-pushed
the
fix/json_pointer_create_object_5357
branch
from
August 4, 2026 06:52
da15b59 to
db1d098
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
This is a draft to support the discussion in #5357 — not a change that is ready to merge. It implements one of several possible answers so we have something concrete to talk about. See "Open questions" below.
Fixes #5357 (discussed in #5356, related to #4446).
Problem
When
operator[](json_pointer)traverses an intermediate level that does not exist yet, thenullvalue has to be turned into either an array or an object. The rule injson_pointer::get_unchecked()was "all characters are digits → array, otherwise object".That predicate is looser than what actually counts as an array index (RFC 6901, Sect. 4: a nonempty sequence of digits without a leading
0). So tokens that can never be a valid array index still selected an array, and the subsequent index conversion then failed:Both
01and""are perfectly valid object keys, and both work if the level already exists as an object:So whether the pointer worked depended on whether the level had been created beforehand.
unflatten()(which goes throughget_and_create(), a different rule) already produced the object form for the same key.Change
Test the reference token against the RFC 6901 grammar for array indices instead of "is all digits". Tokens that cannot be an array index now create an object, which is what they would resolve to on an existing object.
null/0,/2,/-,/foo/0/0/one/01parse_error.106{"01": …}/(empty token)out_of_range.404{"": …}Breaking changes
No breaking API changes. No signature, type, or macro changes.
Behavior changes only in cases that previously always threw: a pointer token matching
0[0-9]+or the empty token, applied to anullvalue via the non-constoperator[]. Any program that got a value out of such a pointer before still gets the same value; only programs relying on theparse_error.106/out_of_range.404exception in this specific situation would notice. Existing arrays are untouched —j["/01"_json_pointer]on{1,2,3}still throwsparse_error.106.Open questions (why this is a draft)
get_and_create()(used byunflatten()) still uses a third rule: only the token"0"starts an array, sojson{{"/foo/1", 1}}.unflatten()yields{"foo":{"1":1}}(object) whilej["/foo/1"_json_pointer]yields an array. Aligning those two would be a genuine breaking change, so it is deliberately not part of this PR. Should it be a separate v4 item?404into a success, which is arguably a bigger surprise than the01case. Happy to drop it if we only want the reported issue fixed.Also in this PR
unit-json_pointer.cppcovering array-index tokens, non-index tokens, and that creating a level now gives the same result as reusing an existing one.operator[]documentation note about creating intermediate levels now states the rule in terms of valid array indices and mentions the01/ empty-token cases.Drafted by Claude Code.