From 359c889ed2b269e9baf925fe4a6ec1bd9bdaa7f5 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 27 Oct 2026 14:36:57 +0100 Subject: [PATCH] Fix JSON_DIAGNOSTICS test crash and clang-tidy hit in patch_inplace self-aliasing The spare-capacity test reallocated non-empty elements through get_ref(), which leaves stale parent pointers under JSON_DIAGNOSTICS; reserve while the array is empty instead. Suppress performance-unnecessary-copy-initialization for the copy that is needed because *this is modified. Signed-off-by: Niels Lohmann --- include/nlohmann/json.hpp | 1 + single_include/nlohmann/json.hpp | 1 + tests/src/unit-json_patch.cpp | 11 +++++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index c715a8a61..2606323fc 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -6954,6 +6954,7 @@ public: // a copy when a value is applied as patch to itself if (JSON_HEDLEY_UNLIKELY(&json_patch == this)) { + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization): *this is modified below const basic_json json_patch_copy = json_patch; patch_inplace(json_patch_copy); return; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index f500c68ec..6bfff31d2 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -43256,6 +43256,7 @@ public: // a copy when a value is applied as patch to itself if (JSON_HEDLEY_UNLIKELY(&json_patch == this)) { + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization): *this is modified below const basic_json json_patch_copy = json_patch; patch_inplace(json_patch_copy); return; diff --git a/tests/src/unit-json_patch.cpp b/tests/src/unit-json_patch.cpp index 37962f4b9..c9d351185 100644 --- a/tests/src/unit-json_patch.cpp +++ b/tests/src/unit-json_patch.cpp @@ -847,8 +847,8 @@ TEST_CASE("JSON patch") SECTION("copy operations without spare capacity") { + // a copy has exactly as much capacity as elements json doc = copy_ops; - doc.get_ref().shrink_to_fit(); CHECK(doc.patch(doc) == expected_copies); doc.patch_inplace(doc); @@ -857,8 +857,15 @@ TEST_CASE("JSON patch") SECTION("copy operations with spare capacity") { - json doc = copy_ops; + // reserve while the array is empty: reallocating non-empty + // elements behind the library's back leaves stale parent + // pointers with JSON_DIAGNOSTICS + json doc = json::array(); doc.get_ref().reserve(100); + for (int i = 0; i < 5; ++i) + { + doc.push_back(copy_op); + } CHECK(doc.patch(doc) == expected_copies); doc.patch_inplace(doc);