From 45c47ef9218dc3a9857fbe4384687faa621d72e8 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 21 Jul 2026 07:27:08 +0000 Subject: [PATCH] Avoid deep recursion in serialization write-buffer test The "many small structural writes exceed the write buffer" subcase built a 1100-deep nested array and dumped it to force >1024 consecutive single-character writes through put_char (exercising the write buffer's flush-when-full branch). dump() recurses per nesting level, so on MSVC debug builds (smaller default stack, larger frames) this overflowed the stack and crashed test-serialization; Linux/macOS have enough headroom to hide it. Replace the nesting with a flat array of 500 empty strings. Each element emits '"', '"', ',' via put_char, so the dump is a long run of single-character writes (1501 bytes > the 1024-byte buffer) at nesting depth two, hitting the same flush branch without deep recursion. Library code is unchanged. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01XAYM1qhSA2FDaDcGfPW3fG Signed-off-by: Niels Lohmann --- tests/src/unit-serialization.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/src/unit-serialization.cpp b/tests/src/unit-serialization.cpp index 983782dcf..1d34e8002 100644 --- a/tests/src/unit-serialization.cpp +++ b/tests/src/unit-serialization.cpp @@ -445,16 +445,20 @@ TEST_CASE("serialization of strings (bulk fast path)") CHECK(json::parse(obj.dump()) == obj); CHECK(json::parse(obj.dump(2)) == obj); - // deep nesting emits >1024 consecutive single-character writes, forcing - // the write buffer to flush mid-run - json nested = json::array(); - for (int i = 0; i < 1100; ++i) + // an array of many empty strings emits a long run of single-character + // writes ('"', '"', ',') at shallow nesting depth, so the write buffer + // fills and flushes mid-run without the deep recursion that would + // overflow the stack on some debug builds + json many_empty = json::array(); + for (int i = 0; i < 500; ++i) { - nested = json::array({nested}); + many_empty.push_back(""); } - const std::string out2 = nested.dump(); - CHECK(out2.substr(0, 1100) == std::string(1100, '[')); - CHECK(json::parse(out2) == nested); + const std::string out2 = many_empty.dump(); + CHECK(out2.size() > 1024); // spans multiple write-buffer flushes + CHECK(out2.front() == '['); + CHECK(out2.back() == ']'); + CHECK(json::parse(out2) == many_empty); } SECTION("invalid UTF-8 handling is unaffected by the fast path")