nlohmann / json

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

very accidental: SIGABRT when parsing json string with allow_exceptions=false #4234

Open Johnny-Martin opened 7 months ago

Johnny-Martin commented 7 months ago

Description

Hi guys, we are useing nlohmann for json processing with version 3.7.3.

This library works perfect for most of the time. We alway disable the exceptions when parsing:

auto json = nlohmann::json::parse(str, nullptr, false);

This works perfect but we received a few crash report and the dump shows that nlohmann::json::parse crashed for SIGABRT.

/apex/com.android.runtime/lib64/bionic/libc.so pc 0000000000037c94 (abort+180) [arm64-v8a]
/apex/com.android.runtime/lib64/bionic/libc.so pc 0000000000001000 (free+96) [arm64-v8a]
libCrashSight.so pc 00000000000388c0 (std::logic_error::~logic_error()+48) [arm64-v8a] [4.2.7(424)]
include/json.hpp:1864
nlohmann::detail::parser<nlohmann::basic_json<std::__ndk1::map, std::__ndk1::vector, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, bool, long, unsigned long, double, std::__ndk1::allocator, nlohmann::adl_serializer> >::parse(bool, nlohmann::basic_json<std::__ndk1::map, std::__ndk1::vector, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, bool, long, unsigned long, double, std::__ndk1::allocator, nlohmann::adl_serializer>&)
ld-temp.o:?
nlohmann::basic_json<std::__ndk1::map, std::__ndk1::vector, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, bool, long, unsigned long, double, std::__ndk1::allocator, nlohmann::adl_serializer>::parse(nlohmann::detail::input_adapter&&, std::__ndk1::function<bool (int, nlohmann::detail::parser<nlohmann::basic_json<std::__ndk1::map, std::__ndk1::vector, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, bool, long, unsigned long, double, std::__ndk1::allocator, nlohmann::adl_serializer> >::parse_event_t, nlohmann::basic_json<std::__ndk1::map, std::__ndk1::vector, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, bool, long, unsigned long, double, std::__ndk1::allocator, nlohmann::adl_serializer>&)>, bool)
include/json.hpp:20750

image

image

Unfortunatelly, we can't get more information from the user because of some security policy.

Reproduction steps

The probability of this crash is very low and we tried to reproduce it for many times but all failed.

Expected vs. actual results

Since we have disabled the exceptions with allow_exceptions=false, so just do not crash the application when parsing json string.

Minimal code example

No response

Error messages

No response

Compiler and operating system

Android application packed by Unreal Engine 4.27

Library version

3.7.3

Validation

nlohmann commented 7 months ago

Can you please try the latest version?

Johnny-Martin commented 7 months ago

Hi nlohmann, thanks for your reply. I'am afraid we can't just upgrade to the latest version before we figure out the rootcause. Our product is a SDK, not an application. We offerd this SDK to our customer and the customer develop the final application with the SDK. Upgrade to latest version maybe fix this crash, and maybe not, we can't tell our customer that the crash MAYBE fixd.

I did some troubleshooting and I would be very greatful if you can give me some advise.

class parser{
....
 void parse(const bool strict, BasicJsonType& result)
{
            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
            sax_parse_internal(&sdp);
.......
}
.......
bool sax_parse_internal(SAX* sax)
{
        ........
        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
        {
             return sax->parse_error(m_lexer.get_position(),
                                                    m_lexer.get_token_string(),
                                                    parse_error::create(101, m_lexer.get_position(),
                                                    exception_message(token_type::value_string, "object key")));
        }

If the allow_exceptions of parser object is specfied to false, can we just omit the parse_error::create when error occured in sax_parse_internal?

nlohmann commented 7 months ago

The reason I asked is that we do not provide support for older versions, and 3.7.3 is over 4 years old.

Nevertheless, the issue seems not to be actually throwing an exception, but rather creating an exception object (or logic_error). Can you please check if you can create a json::parse_error object (or logic_error object) with your setup? There was a similar bug in MSVC which broke when exception objects were created when exceptions were switched off.

Johnny-Martin commented 7 months ago

Thanks for you advise, I tried in my device and create json::parse_error object million times, it's totally OK.

nlohmann commented 7 months ago

Not sure what to do now. I would still assume it's not a library issue, but rather an issue in the used STL.

Johnny-Martin commented 7 months ago

You are right, may be we can discuss with the customer and take an A/B test for the latest version and the current version, see if it works.

nlohmann commented 7 months ago

I won't expect much since we did not touch that part in a while (which is the reason I think it's fine). How often does the signal occur?