1
0
mirror of https://github.com/nlohmann/json.git synced 2026-07-21 19:23:03 +04:00

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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAYM1qhSA2FDaDcGfPW3fG
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-07-21 07:27:08 +00:00
parent bb4c522858
commit 45c47ef921
+12 -8
View File
@@ -445,16 +445,20 @@ TEST_CASE("serialization of strings (bulk fast path)")
CHECK(json::parse(obj.dump()) == obj); CHECK(json::parse(obj.dump()) == obj);
CHECK(json::parse(obj.dump(2)) == obj); CHECK(json::parse(obj.dump(2)) == obj);
// deep nesting emits >1024 consecutive single-character writes, forcing // an array of many empty strings emits a long run of single-character
// the write buffer to flush mid-run // writes ('"', '"', ',') at shallow nesting depth, so the write buffer
json nested = json::array(); // fills and flushes mid-run without the deep recursion that would
for (int i = 0; i < 1100; ++i) // 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(); const std::string out2 = many_empty.dump();
CHECK(out2.substr(0, 1100) == std::string(1100, '[')); CHECK(out2.size() > 1024); // spans multiple write-buffer flushes
CHECK(json::parse(out2) == nested); CHECK(out2.front() == '[');
CHECK(out2.back() == ']');
CHECK(json::parse(out2) == many_empty);
} }
SECTION("invalid UTF-8 handling is unaffected by the fast path") SECTION("invalid UTF-8 handling is unaffected by the fast path")