You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Stack overflow in std::hash<basic_json> and update(j, true) on deeply nested values #5545
Two more operations recurse once per nesting level with no bound. Both crash the process (SIGSEGV) on a value that parse() accepts without complaint, because the parser is iterative:
std::hash<basic_json> (detail::hash in include/nlohmann/detail/hash.hpp) hashes each element by calling itself.
update(j, true) merges nested objects by calling update(it.value(), true) on each child object.
These are the same class of bug as #5387 (copy, comparison), #5392 (binary writers) and #5393 (diff, merge_patch, flatten), but neither is covered by those issues.
Reproduction steps
#include<nlohmann/json.hpp>
#include<string>using json = nlohmann::json;
intmain()
{
std::string text;
for (int i = 0; i < 50000; ++i) text += "{\"a\":";
text += "1" + std::string(50000, '}');
const json j = json::parse(text); // fine: the parser is iterative
std::hash<json>{}(j); // SIGSEGV
json target = json::parse(text);
target.update(json::parse(text), true); // SIGSEGV
}
Expected vs. actual results
Expected: a hash value, and a merged object. Actual: both crash, with no exception to catch. On develop (f751547a8, clang -O2, 8 MiB stack), each first crashes at 50,000 levels of nested objects; 25,000 still works. A smaller stack lowers the threshold proportionally.
std::hash<json> is reachable from untrusted input wherever a parsed value is used as a key in an unordered container.
Compiler and operating system
Apple clang 21, macOS; not compiler-specific.
Library version
develop at f751547a8
Validation
The bug also occurs if the latest version from the develop branch is used.
Activity
Merge deeply nested objects without recursing per nesting level
Merge deeply nested objects without recursing per nesting level
Hash deeply nested values without recursing per nesting level (#5546)
Merge deeply nested objects without recursing per nesting level (#5547)