diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp index 2140e70d525ef7e95d081d0d4998eba4d3c7de32..8b17915985e9a29cde9706665278d851f0978ad3 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp @@ -143,34 +143,50 @@ int CheckCommon::CheckDocument(JsonObject &documentObj, bool &isIdExist) return E_OK; } -int CheckCommon::CheckUpdata(JsonObject &updataObj, std::vector> &path) +int SplitFieldName(const std::string &fieldName, std::vector &allFieldsName) { - if (updataObj.GetDeep() > JSON_DEEP_MAX) { - GLOGE("projectionObj's json deep is deeper than JSON_DEEP_MAX"); - return -E_INVALID_ARGS; - } - for (size_t i = 0; i < path.size(); i++) { - if (path[i].empty()) { - return -E_INVALID_JSON_FORMAT; + std::string tempParseName; + std::string priFieldName = fieldName; + for (size_t j = 0; j < priFieldName.size(); j++) { + if (priFieldName[j] != '.') { + tempParseName += priFieldName[j]; } - for (size_t j = 0; j < path[i].size(); j++) { - if (path[i][j].empty()) { + if (priFieldName[j] == '.' || j == priFieldName.size() - 1) { + if ((j > 0 && priFieldName[j] == '.' && priFieldName[j - 1] == '.') || + (priFieldName[j] == '.' && j == priFieldName.size() - 1)) { return -E_INVALID_ARGS; } - for (auto oneChar : path[i][j]) { + allFieldsName.emplace_back(tempParseName); + tempParseName.clear(); + } + } + return E_OK; +} + +int CheckCommon::CheckUpdata(JsonObject &updataObj) +{ + JsonObject jsonTemp = updataObj.GetChild(); + size_t maxDeep = 0; + while (!jsonTemp.IsNull()) { + std::vector allFieldsName; + int errCode = SplitFieldName(jsonTemp.GetItemField(), allFieldsName); + if (errCode != E_OK) { + return errCode; + } + for (const auto &fieldName : allFieldsName) { + for (auto oneChar : fieldName) { if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + GLOGE("updata fieldName is illegal"); return -E_INVALID_ARGS; } } } - if (!path[i].empty() && !path[i][0].empty() && isdigit(path[i][0][0])) { - return -E_INVALID_ARGS; - } - } - for (const auto &singlePath : path) { - if (singlePath.size() > JSON_DEEP_MAX) { + maxDeep = std::max(allFieldsName.size() + jsonTemp.GetDeep(), maxDeep); + if (maxDeep > JSON_DEEP_MAX) { + GLOGE("document's json deep is deeper than JSON_DEEP_MAX"); return -E_INVALID_ARGS; } + jsonTemp = jsonTemp.GetNext(); } bool isIdExist = true; CheckIdFormat(updataObj, isIdExist); @@ -198,7 +214,7 @@ int CheckCommon::CheckProjection(JsonObject &projectionObj, std::vector> &filterPath, bool &isIdExist); static int CheckIdFormat(JsonObject &data, bool &isIdExisit); static int CheckDocument(JsonObject &document, bool &isIdExist); - static int CheckUpdata(JsonObject &updata, std::vector> &path); + static int CheckUpdata(JsonObject &updata); static int CheckProjection(JsonObject &projectionObj, std::vector> &path); }; using Key = std::vector; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp index 01ca996cd2365e7a0ba0056fb89be5415af69c50..83dac352cad366aa5118b9e6b90b47bcb58e496a 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp @@ -157,13 +157,7 @@ int UpdateArgsCheck(const std::string &collection, const std::string &filter, co return errCode; } if (update != "{}") { - std::vector> allPath; - allPath = JsonCommon::ParsePath(updateObj, errCode); - if (errCode != E_OK) { - GLOGE("updateObj ParsePath failed"); - return errCode; - } - errCode = CheckCommon::CheckUpdata(updateObj, allPath); + errCode = CheckCommon::CheckUpdata(updateObj); if (errCode != E_OK) { GLOGE("Updata format is illegal"); return errCode; @@ -439,12 +433,7 @@ int UpsertDocumentFormatCheck(const std::string &document, JsonObject &documentO { int errCode = E_OK; if (document != "{}") { - std::vector> allPath; - allPath = JsonCommon::ParsePath(documentObj, errCode); - if (errCode != E_OK) { - return errCode; - } - errCode = CheckCommon::CheckUpdata(documentObj, allPath); + errCode = CheckCommon::CheckUpdata(documentObj); if (errCode != E_OK) { GLOGE("UpsertDocument document format is illegal"); return errCode; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h index 4f5efa4a0d6b2dc8354759843a2b19582df55f4b..c3d7a612e60f141fee22683c2024691a97bbdd53 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h @@ -101,8 +101,8 @@ public: private: JsonObject(); int Init(const std::string &str, bool isFilter = false); - int CheckJsonRepeatField(cJSON *object); - int CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType); + int CheckJsonRepeatField(cJSON *object, bool isFirstFloor); + int CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor); int GetDeep(cJSON *cjson); int CheckNumber(cJSON *cjson, int &errCode); cJSON *cjson_ = nullptr; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp index 5130029da576bbe319298ca47b0b22f2340eb80f..4265ab101e3ece68f453f31e05a10ba1cb006773 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp @@ -183,7 +183,8 @@ int JsonObject::Init(const std::string &str, bool isFilter) return -E_INVALID_ARGS; } if (!isFilter) { - ret = CheckJsonRepeatField(cjson_); + bool isFirstFloor = true; + ret = CheckJsonRepeatField(cjson_, isFirstFloor); if (ret != E_OK) { return ret; } @@ -191,7 +192,7 @@ int JsonObject::Init(const std::string &str, bool isFilter) return E_OK; } -int JsonObject::CheckJsonRepeatField(cJSON *object) +int JsonObject::CheckJsonRepeatField(cJSON *object, bool isFirstFloor) { if (object == nullptr) { return -E_INVALID_ARGS; @@ -204,7 +205,7 @@ int JsonObject::CheckJsonRepeatField(cJSON *object) std::set fieldSet; cJSON *subObj = object->child; while (subObj != nullptr) { - ret = CheckSubObj(fieldSet, subObj, type); + ret = CheckSubObj(fieldSet, subObj, type, isFirstFloor); if (ret != E_OK) { break; } @@ -213,7 +214,7 @@ int JsonObject::CheckJsonRepeatField(cJSON *object) return ret; } -int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType) +int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor) { if (subObj == nullptr) { return -E_INVALID_ARGS; @@ -221,9 +222,20 @@ int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int std::string fieldName; if (subObj->string != nullptr) { fieldName = subObj->string; + if (!isFirstFloor) { + for (auto oneChar : fieldName) { + if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + return -E_INVALID_ARGS; + } + } + } + if (!fieldName.empty() && isdigit(fieldName[0])) { + return -E_INVALID_ARGS; + } } + isFirstFloor = false; if (parentType == cJSON_Array) { - return CheckJsonRepeatField(subObj); + return CheckJsonRepeatField(subObj, isFirstFloor); } if (fieldName.empty()) { return -E_INVALID_JSON_FORMAT; @@ -233,7 +245,7 @@ int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int } else { return -E_INVALID_JSON_FORMAT; } - return CheckJsonRepeatField(subObj); + return CheckJsonRepeatField(subObj, isFirstFloor); } std::string JsonObject::Print() const diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp index 264a4e9a1bd2580964cfa28a298ba1705f27e863..c065640bd5c87ecab1ca57221030337bc02df177 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp @@ -147,25 +147,6 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest005, TestSize.Level0) EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); } -HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest006, TestSize.Level0) -{ - std::string document = R""({"name":{"first":"Tno", "last":"moray"}})""; - std::string updateDoc = R""({"name":{"midle.AA":"GG"}})""; - - int errCode = E_OK; - JsonObject src = JsonObject::Parse(document, errCode); - EXPECT_EQ(errCode, E_OK); - JsonObject add = JsonObject::Parse(updateDoc, errCode); - EXPECT_EQ(errCode, E_OK); - - EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); - GLOGD("result: %s", src.Print().c_str()); - - JsonObject itemCase = src.FindItem({ "name", "midle.AA" }, errCode); - EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); -} - HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest007, TestSize.Level0) { std::string document = R""({"name":{"first":["XX", "CC"], "last":"moray"}})"";