Tencent / rapidjson

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

rapidjson::Value::AddMember crashes on some keys #2287

Open rexkogitans opened 3 weeks ago

rexkogitans commented 3 weeks ago

Maybe there is something I do completely overcomplicated or even wrong, but since this function is working for nearly all values, I think it is not too wrong. However, when adding some values, it crashes. It does not depend on the inserted value, but on the inserted key. I found out, that rapidjson::Value::AddMember crashes with a key which contains a slash.

This is my function to add any value to the JSON data. Please note that this function is part of a huge application which is working fine except if const std::string *key is passed a string containing a slash:

rapidjson::Value *JSONDeskModel::addObjectNode(const std::vector<std::string> path, const std::string *key, const rapidjson::Value& newJSONValue) {
    /** Append to parentJSONValue **/
    rapidjson::Value *ret = nullptr;
    if (key == nullptr) {
        if (path.size() == 0) {
            this->newDocument();
            this->jsonRoot->CopyFrom(newJSONValue, this->jsonRoot->GetAllocator());
            ret = (rapidjson::Value *)&this->jsonRoot;
            this->validJSON = true;
        }
    } else {
        rapidjson::Value *parentJSONValue = this->getJSONValue(path);
        if (parentJSONValue != nullptr) {
            if (parentJSONValue->IsObject()) {
                rapidjson::Value localKey;
                localKey.SetString(key->c_str(), key->length(), this->jsonRoot->GetAllocator());
                if (!parentJSONValue->HasMember(localKey)) {
                    rapidjson::Value localNewJSONValue;
                    localNewJSONValue.CopyFrom(newJSONValue, this->jsonRoot->GetAllocator());
                    rapidjson::Value& pj = *((rapidjson::Value *)parentJSONValue);
                    pj.AddMember(localKey.Move(), localNewJSONValue.Move(), this->jsonRoot->GetAllocator());  // this is the offending line
                    rapidjson::Value::MemberIterator it = pj.FindMember(rapidjson::Value(key->c_str(), key->length(), this->jsonRoot->GetAllocator()));
                    ret = &it->value;
                    this->validJSON = true;
                }
            }
        }
    }
    return ret;
}

What am I missing here? How can I protect this function from crashing? It should either just fail and return nullptr, or just work. I already tried wrapping the offending line with a try ... catch block with no success, because it is a SIGSEGV which cannot be caught.

I put it here in the issues because maybe it is really a bug in RapidJSON.

Kind regards.