diff --git a/include/nlohmann/json_view.hpp b/include/nlohmann/json_view.hpp index 071c14904..cabe297c9 100644 --- a/include/nlohmann/json_view.hpp +++ b/include/nlohmann/json_view.hpp @@ -1313,7 +1313,7 @@ class basic_json_document /// member is set (added if missing), an array element assigned, and "-" /// or the size of the array appends. A null parent becomes what /// basic_json's operator[](json_pointer) makes of it: an array for "-" - /// and for digits (padded with nulls up to the index), an object otherwise. + /// and for array indices (padded with nulls up to the index), an object otherwise. template view_type set(const json_pointer& ptr, V&& value) { @@ -1329,7 +1329,11 @@ class basic_json_document { return push_back(parent, std::forward(value)); } - const bool digits = std::all_of(token.begin(), token.end(), [](const char c) + // (a token that cannot be an array index, such as "01" or "", names an + // object member, as in basic_json) + const bool digits = !token.empty() + && (token.size() == 1 || token[0] != '0') + && std::all_of(token.begin(), token.end(), [](const char c) { return c >= '0' && c <= '9'; }); diff --git a/single_include/nlohmann/json_view.hpp b/single_include/nlohmann/json_view.hpp index e611ff540..b8173cb19 100644 --- a/single_include/nlohmann/json_view.hpp +++ b/single_include/nlohmann/json_view.hpp @@ -9067,7 +9067,7 @@ class basic_json_document /// member is set (added if missing), an array element assigned, and "-" /// or the size of the array appends. A null parent becomes what /// basic_json's operator[](json_pointer) makes of it: an array for "-" - /// and for digits (padded with nulls up to the index), an object otherwise. + /// and for array indices (padded with nulls up to the index), an object otherwise. template view_type set(const json_pointer& ptr, V&& value) { @@ -9083,7 +9083,11 @@ class basic_json_document { return push_back(parent, std::forward(value)); } - const bool digits = std::all_of(token.begin(), token.end(), [](const char c) + // (a token that cannot be an array index, such as "01" or "", names an + // object member, as in basic_json) + const bool digits = !token.empty() + && (token.size() == 1 || token[0] != '0') + && std::all_of(token.begin(), token.end(), [](const char c) { return c >= '0' && c <= '9'; }); diff --git a/tests/src/unit-json_pointer.cpp b/tests/src/unit-json_pointer.cpp index 1a4e726ed..b28ac4023 100644 --- a/tests/src/unit-json_pointer.cpp +++ b/tests/src/unit-json_pointer.cpp @@ -1122,17 +1122,17 @@ TEST_CASE("flatten of structured values") // the same for other keys that are not valid array indices CHECK_THROWS_WITH_AS(json({{"/a/0", 1}, {"/a/1a", 2}}).unflatten(), - "[json.exception.out_of_range.404] unresolved reference token '1a'", json::out_of_range&); + "[json.exception.out_of_range.404] unresolved reference token '1a'", json::out_of_range&); CHECK_THROWS_WITH_AS(json({{"/a/0", 1}, {"/a/-", 2}}).unflatten(), - "[json.exception.out_of_range.404] unresolved reference token '-'", json::out_of_range&); + "[json.exception.out_of_range.404] unresolved reference token '-'", json::out_of_range&); } SECTION("unflatten with the empty token among array indices") { CHECK_THROWS_WITH_AS(json({{"/a/0", 1}, {"/a/", 2}}).unflatten(), - "[json.exception.out_of_range.404] unresolved reference token ''", json::out_of_range&); + "[json.exception.out_of_range.404] unresolved reference token ''", json::out_of_range&); CHECK_THROWS_WITH_AS(json({{"/a/0", 1}, {"/a/1", 2}, {"/a/", 3}}).unflatten(), - "[json.exception.out_of_range.404] unresolved reference token ''", json::out_of_range&); + "[json.exception.out_of_range.404] unresolved reference token ''", json::out_of_range&); // without an index "0", the empty token is an ordinary object key CHECK(json({{"/a/", 2}}).unflatten() == json({{"a", {{"", 2}}}}));