From 6eb5329ec3589a03b3d66a214396a02487b310b0 Mon Sep 17 00:00:00 2001 From: Hudson00 Date: Thu, 16 Dec 2021 20:24:02 -0500 Subject: [PATCH] Fix patch::add creating nonexistent parents The previous behavior was not in accordance with RFC6902. Add unit test. Fixes #3134. --- include/nlohmann/json.hpp | 3 ++- single_include/nlohmann/json.hpp | 3 ++- tests/src/unit-json_patch.cpp | 10 ++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 24812fde5..002663686 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4683,7 +4683,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // get reference to parent of JSON pointer ptr const auto last_path = ptr.back(); ptr.pop_back(); - basic_json& parent = result[ptr]; + // parent must exist when performing patch add per RFC6902 specs + basic_json& parent = result.at(ptr); switch (parent.m_type) { diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 3341f0286..2ddf76c48 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -23527,7 +23527,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // get reference to parent of JSON pointer ptr const auto last_path = ptr.back(); ptr.pop_back(); - basic_json& parent = result[ptr]; + // parent must exist when performing patch add per RFC6902 specs + basic_json& parent = result.at(ptr); switch (parent.m_type) { diff --git a/tests/src/unit-json_patch.cpp b/tests/src/unit-json_patch.cpp index cdb287a9e..6e5d27571 100644 --- a/tests/src/unit-json_patch.cpp +++ b/tests/src/unit-json_patch.cpp @@ -60,6 +60,16 @@ TEST_CASE("JSON patch") // because "a" does not exist. CHECK_THROWS_WITH_AS(doc2.patch(patch), "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&); + + json doc3 = R"({ "a": {} })"_json; + json patch2 = R"([{ "op": "add", "path": "/a/b/c", "value": 1 }])"_json; + + // should cause an error because "b" does not exist in doc3 +#if JSON_DIAGNOSTICS + CHECK_THROWS_WITH_AS(doc3.patch(patch2), "[json.exception.out_of_range.403] (/a) key 'b' not found", json::out_of_range&); +#else + CHECK_THROWS_WITH_AS(doc3.patch(patch2), "[json.exception.out_of_range.403] key 'b' not found", json::out_of_range&); +#endif } SECTION("4.2 remove")