Tencent / rapidjson

A fast JSON parser/generator for C++ with both SAX/DOM style API
http://rapidjson.org/
Other
14.25k stars 3.53k forks source link

Crashing while traversing parsed document (master) #1931

Open srikumarkp opened 3 years ago

srikumarkp commented 3 years ago

Library crashing while traversing the DOM from the request below:

include "rapidjson/document.h"

include "rapidjson/writer.h"

include "rapidjson/stringbuffer.h"

std::string request = R"( { "id": "test_id", "site": { "id": "42", "domain": "www.zypmedia.com", "page": "http://www.zypmedia.com/about-us", "publisher": { "id": "TEST_pub_id", "name": "TEST_pub_name", "cat": ["IAB3-1"], "domain": "zypmedia.com" } }, "device": {"ip": "1.2.3.4"} })";

Snippet: Document d; if (d.Parse(request.c_str()).HasParseError()) return ;

 for (auto it = d.MemberBegin(); it != d.MemberEnd(); ++it)
 {

 }
srikumarkp commented 3 years ago

std::string request = R"( { "id": "test_id", "site": { "id": "42", "domain": "www.zypmedia.com", "page": "http://www.zypmedia.com/about-us", "publisher": { "id": "TEST_pub_id", "name": "TEST_pub_name", "cat": ["IAB3-1"], "domain": "zypmedia.com" } }, "device": {"ip": "1.2.3.4"}, })";

This works except it is not valid json.

dinomight commented 3 years ago

I went ahead and tried to replicate this issue with the following test based on your original post:

TYPED_TEST(DocumentMove, IterationCrashTest)
{
    typedef TypeParam Allocator;
    typedef GenericDocument<UTF8<>, Allocator> D;

    std::string input = R"json(
        {
            "id": "test_id",
            "site": {
                "id": "42",
                "domain": "www.zypmedia.com",
                "page": "http://www.zypmedia.com/about-us",
                "publisher": {
                    "id": "TEST_pub_id",
                    "name": "TEST_pub_name",
                    "cat": ["IAB3-1"],
                    "domain": "zypmedia.com"
                }
            },
            "device": {"id": "1.2.3.4"}
        }
    )json";

    D a;
    a.Parse(input.c_str());
    EXPECT_FALSE(a.HasParseError());
    auto it = a.MemberBegin();
    EXPECT_EQ("id", std::string(it->name.GetString()));
    EXPECT_EQ("test_id", std::string(it->value.GetString()));
    ++it;
    EXPECT_EQ("site", std::string(it->name.GetString()));
    EXPECT_TRUE(it->value.IsObject());
    ++it;
    EXPECT_EQ("device", std::string(it->name.GetString()));
    EXPECT_TRUE(it->value.IsObject());
}

Test passes in release and debug with both the memory pool and straight CRT allocators under MSVC 19.29 (16.11). Do you have more information on your end as far as what compiler and target platform you are using? Have you tried debugging to the crash location to see where in rapidjson it's tripping up? Can you also describe what's different in your working example compared to the first one? I can't find the difference, but I'm wondering if you are just returning before iteration if the text is not valid JSON.