Rapidjson的断言IsObject()随机失败,但不应

时间:2019-11-28 08:43:56

标签: c++ rapidjson

我们面临一个问题,即RAPIDJSON_ASSERT(IsObject())调用的MemberEnd()调用的HasMember()失败了。但是,rapidjson::Value被其他逻辑保证是一个对象。

这是代码段:

const std::string str = "{\"outer_key\":{\"inner_key\":\"value\", \"foo\":\"bar\"}}";
rapidjson::Document doc;
if (doc.Parse(str.c_str()).HasParseError()) {
    return -1;
}

rapidjson::Value::MemberIterator it = doc.FindMember("outer_key");
// make sure the member is of Object type
if (it == doc.MemberEnd() || !it->value.IsObject()) {
    return -1;
}

rapidjson::Value* p_json;
p_json = &(it->value);

rapidjson::Document new_doc;
rapidjson::Document::AllocatorType& new_doc_allocator = new_doc.GetAllocator();
// if SOME_FLAG is set and "outer_key" exists in the input JSON string,
// use "outer_key"'s value so that `new_doc` will have other properties such as `foo` for free.
if (SOME_FLAG && p_json != NULL) {
    new_doc.CopyFrom(*p_json, new_doc_allocator);

    // The value of "inner_key" will be re-added later, so remove it for now.
    // assert(IsObject()) fails here and core is dumped.
    if (new_doc.HasMember("inner_key")) {
        new_doc.RemoveMember("inner_key");
    }
} else {
    // Otherwise, start from an empty object.
    new_doc.SetObject();
}

// Add "inner_key" for both cases above.
const std::string new_value_str = "new_value";
new_doc.AddMember("inner_key", rapidjson::StringRef(new_value_str.c_str()), new_doc_allocator);

我们怀疑new_doc.CopyFrom(*p_json, new_doc_allocator);行是罪魁祸首,但对于Rapidjson来说是新的,因此不确定使用new_doc_allocator*p_json复制到{{ 1}}。

奇怪的是,此问题仅在少数请求在线发生。我们提取了输入的JSON字符串,检查它是否有效,但无法离线重现故障。

如果有人可以指出我们做错了什么地方,那就太好了。预先感谢。

0 个答案:

没有答案