-
-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Closed
Labels
documentationsolution: proposed fixa fix for the issue has been proposed and waits for confirmationa fix for the issue has been proposed and waits for confirmation
Milestone
Description
Description
The same program (code in case 1) produces the expected result using regular nlohmann::json, but crashes using nlohmann::ordered_json. A simple variant of this program (code in case 2) produces the expected result using json, but a different result with ordered_json.
Reproduction steps
Consider this input json file ("test.json"):
{
"number": 14,
"structure": {
"field1": 1,
"field2": 2
}
}
The 2 small programs listed into "Minimal code example" will work fine and produce the expected results when using my_json = nlohmann::json. However, if we change the type to nlohmann::ordered_json, the first program will crash and the second program will not add new_field as expected.
Expected vs. actual results
Expected result for case 1:
{
"number": 14,
"my_structures": {
"structure": {
"field1": 1
}
}
}
Expected result for case 2:
{
"number": 14,
"my_structures": {
"structure": {
"field1": 1,
"field2": 2,
"new_field": "new"
}
}
}
Minimal code example
// CASE 1: removing an old field
using my_json = nlohmann::json;
int main()
{
std::ifstream InputStream( "test.json" );
my_json Root = my_json::parse( InputStream );
// create new level at root
my_json& MyStructures = Root[ "my_structures" ];
// move structure into that new level
MyStructures[ "structure" ] = Root[ "structure" ];
Root.erase( "structure" );
// add new structure field
MyStructures[ "structure" ].erase( "field2" );
std::ofstream OutputStream( "converted.json" );
OutputStream << std::setw( 2 ) << Root << std::endl;
}
// CASE 2: adding a new field
using my_json = nlohmann::json;
int main()
{
std::ifstream InputStream( "test.json" );
my_json Root = my_json::parse( InputStream );
// create new level at root
my_json& MyStructures = Root[ "my_structures" ];
// move structure into that new level
MyStructures[ "structure" ] = Root[ "structure" ];
Root.erase( "structure" );
// add new structure field
MyStructures[ "structure" ][ "new_field" ] = "new";
std::ofstream OutputStream( "converted.json" );
OutputStream << std::setw( 2 ) << Root << std::endl;
}
Error messages
I am using the library as a single include, and for the crashing case an exception is being thrown at this point (line 21878):
private:
template < typename KeyType, detail::enable_if_t <
detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
size_type erase_internal(KeyType && key)
{
// this erase only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
-----> JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
}
return m_data.m_value.object->erase(std::forward<KeyType>(key));
}
The exception message is: [json.exception.type_error.307] cannot use erase() with null
Compiler and operating system
Windows 10, Microsoft Visual Studio Professional 2019 Version 16.11.24
Library version
Github at commit 7efe875
Validation
- The bug also occurs if the latest version from the
develop
branch is used. - I can successfully compile and run the unit tests.
Metadata
Metadata
Assignees
Labels
documentationsolution: proposed fixa fix for the issue has been proposed and waits for confirmationa fix for the issue has been proposed and waits for confirmation