简体   繁体   中英

rapidjson crashed when json value should be INT but send as string type

I have a C++ code that parses incoming json message using rapidjson.

The json message received contains one key:value pair ("userID": 100), where the value is an integer.

However, if the value is sent as a string '100', rapidjson crashed the whole program with the following error:

Invalid response: { "error": "ERR_RATE_LIMIT"}
trading: ../../include/rapidjson/document.h:1737: int rapidjson::GenericValue<Encoding, Allocator>::GetInt() const [with Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>]: Assertion `data_.f.flags & kIntFlag' failed.
/home/ray/dev/trading_execution/src/trading/trading.run.sh: line 39:  2518 Aborted                 (core dumped) ./trading 1234

I would expect rapidjson can handle this more gently than crashing the program.

Any suggestion how to deal with this situation? For example, is there a better way to handle the error?

Json message:

{
   "ctRequestId":   "cfa5511f-8c1a-492b-b81a-1462d03bbe99",
    "requestType":  "generic",  
    "userID":       100,                        
}

Code:

    userID          = getJSONInt(document,      "userID");      

    int getJSONInt(rapidjson::Document& document, const char* memberName)
    {
    int memberValue;

    try
    {
        if (document.HasMember(memberName))
        memberValue = document[memberName].GetInt();
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
    }

    return memberValue;
}

No expert of rapidjson, but according to the documentation ( http://rapidjson.org/md_doc_tutorial.html )

Note that, RapidJSON does not automatically convert values between JSON types. If a value is a string, it is invalid to call GetInt(), for example. In debug mode it will fail an assertion. In release mode, the behavior is undefined. In the following sections we discuss details about querying individual types.

If you look in the table in the section "Querying Number" of the linked document you can find some member function you can use to test the type before extracting it. In your case you might want to try IsInt()

Edit: for the particular use case IsUint/GetUint may be more appropriate as pointed out in the comments

Try this:

{
...,
...,
"UserId" : "100"  // note double quotes for 100
}

And if the value of "UserId" is string, then query it using GetString() query and not GetInt() to pass assertion test.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM