nlohmann / json

JSON for Modern C++
https://json.nlohmann.me
MIT License
42.97k stars 6.72k forks source link

JSON_DIAGNOSTICS trigger assertion #3915

Open xamix opened 1 year ago

xamix commented 1 year ago

Description

Hi,

I have activated the JSON_DIAGNOSTICS=1 globally in my project and ASSERTION are now fired at runtime. I tested it on with 3.10.5 and then with latest release 3.11.2.

I have done a minimal example to reproduce the assertion (see minimal code example below)

Is there something wrong with my code?

Reproduction steps

Run the minimal code example below

Expected vs. actual results

No ASSERTION should be triggered since without the JSON_DIAGNOSTICS enabled, all seem to work without any memory issues

Minimal code example

json j = json::object();
j["root"] = "root_str";

json jj = json::object();
jj["child"] = json::object();

// If do not push anything in object, then no assert will be produced
jj["child"]["prop1"] = "prop1_value";

// Push all properties of child in parent
j.insert(jj.at("child").begin(), jj.at("child").end());

// Here assert is generated when construct new json 
json k(j);

Error messages

nlohmann/json.hpp:19864: void nlohmann::json_abi_diag_v3_11_2::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> > >::assert_invariant(bool) const [ObjectType = std::map, ArrayType = std::vector, StringType = std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, BooleanType = bool, NumberIntegerType = long, NumberUnsignedType = unsigned long, NumberFloatType = double, AllocatorType = std::allocator, JSONSerializer = adl_serializer, BinaryType = std::vector<unsigned char, std::allocator<unsigned char> >]: Assertion `!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j) { return j.m_parent == this; })' failed.

Compiler and operating system

Clang-10 on Ubuntu 20.04

Library version

3.11.2

Validation

nlohmann commented 1 year ago

I can confirm the issue.

Romop5 commented 1 year ago

If I understood the code correctly, as of json k(j); the invariant is invalid for instance j due to function insert(it, it) missing a call to set_parents() after this line of code: https://github.com/nlohmann/json/blob/develop/include/nlohmann/json.hpp#L3408

Provided I got the meaning of the statement, during insertion, the properties are basically copied (inserted) to the underlying data structure ObjectType (being std::map for default nlohmann::json) and the copies keep the original parent (as no set_parents() is called during insertion).