This commit is contained in:
nlohmann committed 2026-10-15 12:09:22 +00:00
1 parent dcc7a74a18
commit 98c9bea1d1
105 files changed
+537 -508

No files matched your search

+1 -5
View File
@@ -22,11 +22,7 @@ No built-in depth limit while parsing
Neither the parser nor the binary readers impose a limit on how deep the input may nest. An attacker can still exhaust memory (though not the call stack) with a sufficiently deep document. If you need to reject over-deep untrusted input outright, track the depth yourself, either with a [parser callback](https://json.nlohmann.me/features/parsing/parser_callbacks/#recipe-max-nesting-depth-via-a-callback) for the JSON parser, or by counting `start_object`/`start_array` and `end_object`/`end_array` calls in a [SAX handler](https://json.nlohmann.me/features/parsing/sax_interface/index.md) (for the JSON parser or a binary format alike) and throwing once your limit is exceeded.
Once a value has been parsed, operations that walk it recursively -- serializing it with [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md), hashing it, copying it, comparing two values with `==`, `<`, or (in C++20) `<=>`, merging with [`update`](https://json.nlohmann.me/api/basic_json/update/index.md), and applying a [`merge_patch`](https://json.nlohmann.me/api/basic_json/merge_patch/index.md) -- descend at most 128 levels on the call stack and continue below that with an explicit stack instead, so none of them can exhaust the stack either, however deeply the value is nested. Destroying a value (its destructor) never recurses at all, regardless of nesting depth, for the same reason.
Not every operation is bounded yet
[`diff`](https://json.nlohmann.me/api/basic_json/diff/index.md), [`flatten`](https://json.nlohmann.me/api/basic_json/flatten/index.md), and the binary writers (`to_cbor`, `to_msgpack`, ...) still recurse once per nesting level; this is called out as work in progress in the [assurance case](https://json.nlohmann.me/community/assurance_case/#secure-design). A value deep enough to matter for these operations would typically first have to survive parsing without hitting a self-imposed depth limit, as described above.
Once a value has been parsed, operations that walk it recursively -- serializing it with [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md), hashing it, copying it, comparing two values with `==`, `<`, or (in C++20) `<=>`, merging with [`update`](https://json.nlohmann.me/api/basic_json/update/index.md), applying a [`merge_patch`](https://json.nlohmann.me/api/basic_json/merge_patch/index.md), creating a patch with [`diff`](https://json.nlohmann.me/api/basic_json/diff/index.md) or [`merge_diff`](https://json.nlohmann.me/api/basic_json/merge_diff/index.md), [`flatten`](https://json.nlohmann.me/api/basic_json/flatten/index.md), and the binary writers (`to_cbor`, `to_msgpack`, ...) -- descend at most 128 levels on the call stack and continue below that with an explicit stack instead, so none of them can exhaust the stack either, however deeply the value is nested. Destroying a value (its destructor) never recurses at all, regardless of nesting depth, for the same reason.
## Input size