Report one-character non-numeric array indices like longer ones (#5800)

* Report one-character non-numeric array indices like longer ones

A JSON pointer reference token that is not a number but has only one
character (e.g. "/a/x") was reported as out_of_range.404 ("unresolved
reference token"), because the "is not a number" check only ran for
tokens longer than one character; "/a/xy" got parse_error.109. Both now
throw parse_error.109. "-" and the empty token are still reported as
out_of_range.404. As a consequence, value(json_pointer, default) on an
array now throws for "/x" as it already did for "/xy".

Also document why ordered_map::erase's destroy/placement-new loop on
pair<const Key, T> is kept despite [basic.life]/8 before C++20.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Document the one-character array index change

Add 3.13.0 version-history entries to at, operator[], value, patch,
patch_inplace, and unflatten, and describe in exceptions.md which array
indices throw parse_error.109 and which out_of_range.404.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann authored and GitHub committed 2026-10-11 08:21:41 +02:00
1 parent 1649d9eda4
commit 2cca04ae6f
13 files changed
+95 -13

No files matched your search

+15
View File
@@ -1713,6 +1713,21 @@ TEST_CASE("JSON patch - move where 'from' is a proper prefix of 'path' (regressi
CHECK(doc.patch(patch) == R"({"b": 1})"_json);
}
SECTION("array index tokens that are not a number")
{
json const doc = R"({"a": [1, 2]})"_json;
// "-" cannot be removed and is reported as unresolved
json const patch_dash = {{{"op", "remove"}, {"path", "/a/-"}}};
CHECK_THROWS_WITH_AS(doc.patch(patch_dash), "[json.exception.out_of_range.404] unresolved reference token '-'", json::out_of_range&);
// a single character is reported like a longer token
json const patch_x = {{{"op", "remove"}, {"path", "/a/x"}}};
CHECK_THROWS_WITH_AS(doc.patch(patch_x), "[json.exception.parse_error.109] parse error: array index 'x' is not a number", json::parse_error&);
json const patch_xy = {{{"op", "remove"}, {"path", "/a/xy"}}};
CHECK_THROWS_WITH_AS(doc.patch(patch_xy), "[json.exception.parse_error.109] parse error: array index 'xy' is not a number", json::parse_error&);
}
SECTION("the array-append token '-' is an ordinary child token")
{
// "-" (append-to-array) addresses a location *inside* the array,