我们面临一个问题,即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字符串,检查它是否有效,但无法离线重现故障。
如果有人可以指出我们做错了什么地方,那就太好了。预先感谢。