-
-
Notifications
You must be signed in to change notification settings - Fork 190
Description
Describe the bug
When using a std::variant with std::unordered_map types mixed with std::string (amongst others) as its types, deserialisation via
jsoncons::decode_json<...>(...); can throw an uncatchable exception, and the application will terminate with terminate called after throwing an instance of 'jsoncons::json_runtime_error<std::domain_error, void>' what(): Not an object. The can is because the variant types order matters. If i push the std::unordered_map to the back of the variant, it will correctly parse data.
The "Not an object" seems to come from jsoncons trying to interpret a JSON string as object ("" vs {}) - although i am not really sure. (I know of the case where it is not possible to distinguish an string enum and a string value, depending on order, see #257).
Expected behavior:
-correctly detect and distinguish "" versus {} inside a variant type using std::string and std::unordered_map when decoding JSON strings
-throw a catchable exception
Current behavior:
Throws an uncatchable exception and thus terminates.
Please consider following example code, where parsing sJson1 will throw and will not be caught by the exception handler (i also tried catching (...), to no avail). When parsing sJson2 it works as expected.
#include <jsoncons/json.hpp>
#include <stdio.h>
#include <unordered_map>
#include <vector>
#include <string>
//////////////////////////////////////////////////////////////////////////////
typedef std::variant<
std::unordered_map<std::string, std::string>,
std::unordered_map<std::string, std::unordered_map<std::string, std::string>>,
std::string,
std::vector<std::string>,
int64_t,
std::vector<int64_t>,
double,
std::vector<double>,
bool,
std::vector<bool>
>
VARIANTTYPE;
//////////////////////////////////////////////////////////////////////////////
class SerialisableClass
{
public:
SerialisableClass()=default;
std::string m_sStr;
VARIANTTYPE m_data;
};
JSONCONS_ALL_MEMBER_NAME_TRAITS(SerialisableClass,
(m_sStr, "str"),
(m_data, "data")
)
//////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
std::string sJson1 = R"(
{
"str": "string_value1",
"data": "string_value2"
}
)";
std::string sJson2 = R"(
{
"str": "string_value",
"data": {
"key1": "value1"
}
}
)";
try
{
SerialisableClass sclass = jsoncons::decode_json<SerialisableClass>(sJson1);
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////
Compiler/OS:
-
Compiler: g++ 13.3.0-6ubuntu2~24.04
-
Architecture (e.g. x86, x64) x64, WSL2
-
Operating system: ubuntu 24.04 inside WSL2
-
Build command used:
g++ -g -fexceptions -Wall -Wextra -pedantic -fPIC -I ../jsoncons/include/ main2.cpp -o main2 -
Compiler: cl.exe 19.29.30159 for x64
-
Architecture (e.g. x86, x64) x64
-
Operating system: Windows 10
-
Build command used:
cl.exe /W4 /std:c++17 /Zi /EHa /nologo /MD /I../jsoncons/include/ /FeC:\code\enef\main2.exe C:\code\enef\main2.cpp
What jsoncons library version?
- Latest release 1.4.0
- Other release ______
- master
Side note: Thank you so much for an awesome OSS library!