diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/executor/document/document_check.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/executor/document/document_check.cpp index d81d0c54a4005b0d636dc0181078d24ca9cf3924..94bb513813206761c168f3f6d0e591a0829109c3 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/executor/document/document_check.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/executor/document/document_check.cpp @@ -133,7 +133,7 @@ bool CheckCommon::CheckFilter(const std::string &filter, std::string &idStr, int return false; } - JsonObject filterObject = JsonObject::Parse(filter, errCode, true); + JsonObject filterObject = JsonObject::Parse(filter, errCode, true, true); if (errCode != E_OK) { GLOGE("Parse filter failed. %d", errCode); return false; @@ -256,14 +256,6 @@ int CheckCommon::CheckUpdata(JsonObject &updataObj, std::vector JSON_DEEP_MAX) { return -E_INVALID_ARGS;; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/document_store.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/document_store.cpp index d639dc21a335c00f04a4d07d396cf356e0c2fbfc..e880cbbd661104dbbf003fae261770014411f297 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/document_store.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/document_store.cpp @@ -159,7 +159,7 @@ int DocumentStore::UpdateDocument(const std::string &collection, const std::stri GLOGE("Check flags invalid."); return -E_INVALID_ARGS; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true); + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -251,7 +251,7 @@ int DocumentStore::UpsertDocument(const std::string &collection, const std::stri GLOGE("Check flags invalid."); return -E_INVALID_ARGS; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true); + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -404,7 +404,7 @@ int DocumentStore::DeleteDocument(const std::string &collection, const std::stri GLOGE("filter's length is too long"); return -E_OVER_LIMIT; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true); + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -460,7 +460,7 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string GLOGE("args length is too long"); return -E_OVER_LIMIT; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true); + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/result_set.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/result_set.cpp index bcd511a84d14ef5b2bfaf788aba903500ce8dd6e..9dc8a36054f5c183ba05149b08c5bc261522866a 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/result_set.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/interface/src/result_set.cpp @@ -59,7 +59,7 @@ int ResultSet::GetNext() if (!ifFiled_ && index_ == 0) { if (isOnlyId_) { int errCode = 0; - JsonObject filterObj = JsonObject::Parse(filter_, errCode, true); + JsonObject filterObj = JsonObject::Parse(filter_, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -88,7 +88,7 @@ int ResultSet::GetNext() int errCode = 0; auto coll = Collection(collectionName_, store_->GetExecutor(errCode)); std::vector> values; - JsonObject filterObj = JsonObject::Parse(filter_, errCode, true); + JsonObject filterObj = JsonObject::Parse(filter_, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -107,7 +107,7 @@ int ResultSet::GetNext() int errCode = 0; auto coll = Collection(collectionName_, store_->GetExecutor(errCode)); std::vector> values; - JsonObject filterObj = JsonObject::Parse(filter_, errCode, true); + JsonObject filterObj = JsonObject::Parse(filter_, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/include/json_object.h b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/include/json_object.h index f4ebbdd30742f5b8d4e85a84e20864d6b684296f..69fc3d4e06c6f3a477442cd94e28ac69a5bd7d5b 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/include/json_object.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/include/json_object.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "cJSON.h" @@ -60,7 +61,8 @@ using JsonFieldPath = std::vector; class JsonObject { public: - static JsonObject Parse(const std::string &jsonStr, int &errCode, bool caseSensitive = false); + static JsonObject Parse(const std::string &jsonStr, int &errCode, + bool caseSensitive = false, bool isFilter = false); bool operator==(const JsonObject& other) const; // If the two nodes exist with a different fieldName, then return 0. ~JsonObject(); @@ -104,11 +106,11 @@ public: private: JsonObject(); - int Init(const std::string &str); - + int Init(const std::string &str, bool isFilter = false); + int CheckJsonRepeatField(cJSON *object); + int CheckSubObj(std::set &filedSet, cJSON *subObj, int parentType); int GetDeep(cJSON *cjson); int CheckNumber(cJSON *cjson, int &errCode); - cJSON *cjson_ = nullptr; int jsonDeep_ = 0; bool isOwner_ = false; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/src/json_object.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/src/json_object.cpp index 8667b9da85c8f80c421cc3e07c23d2fbfcf26e2d..ed4d1169c68e7c5424bbd5121d448e90dbf19e4e 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/src/json_object.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/oh_adapter/src/json_object.cpp @@ -14,7 +14,6 @@ */ #include "json_object.h" - #include #include "doc_errno.h" @@ -103,10 +102,11 @@ bool ValueObject::operator==(const ValueObject &other) const return false; } -JsonObject JsonObject::Parse(const std::string &jsonStr, int &errCode, bool caseSensitive) +JsonObject JsonObject::Parse(const std::string &jsonStr, int &errCode, + bool caseSensitive, bool isFilter) { JsonObject obj; - errCode = obj.Init(jsonStr); + errCode = obj.Init(jsonStr, isFilter); obj.caseSensitive_ = caseSensitive; return obj; } @@ -191,7 +191,7 @@ int JsonObject::CheckNumber(cJSON *item, int &errCode) return E_OK; } -int JsonObject::Init(const std::string &str) +int JsonObject::Init(const std::string &str, bool isFilter) { const char *end = NULL; isOwner_ = true; @@ -212,6 +212,70 @@ int JsonObject::Init(const std::string &str) GLOGE("Int value is larger than double"); return -E_INVALID_ARGS; } + int errCode = E_OK; + if (!isFilter) { + ret = CheckJsonRepeatField(cjson_); + if (ret != E_OK) { + return ret; + } + } + return E_OK; +} + +int JsonObject::CheckJsonRepeatField(cJSON *object) +{ + if (object == nullptr) { + return -E_INVALID_ARGS; + } + int ret = E_OK; + int type = object->type; + if (type != cJSON_Object && type != cJSON_Array) { + return ret; + } + std::set filedSet; + cJSON *subObj = object->child; + while (subObj != nullptr) { + ret = CheckSubObj(filedSet, subObj, type); + if (ret != E_OK) { + break; + } + subObj = subObj->next; + } + return ret; +} + +int JsonObject::CheckSubObj(std::set &filedSet, cJSON *subObj, int parentType) +{ + if (subObj == nullptr) { + return -E_INVALID_ARGS; + } + int ret = E_OK; + std::string fieldName; + if (subObj->string != nullptr) { + fieldName = subObj->string; + } + if (parentType == cJSON_Array) { + ret = CheckJsonRepeatField(subObj); + if (ret != E_OK) { + return ret; + } + return E_OK; + } + if (fieldName.empty()) { + return -E_INVALID_JSON_FORMAT; + } + if (filedSet.find(fieldName) == filedSet.end()) { + filedSet.insert(fieldName); + } else { + ret = -E_INVALID_JSON_FORMAT; + } + if (ret != E_OK) { + return ret; + } + ret = CheckJsonRepeatField(subObj); + if (ret != E_OK) { + return ret; + } return E_OK; } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp index 5e256eb16f1ae04e9bdcd17a313d3336b8f46b99..4ee5921ce0d9a2ec139891c084377b2eafbf4083 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp @@ -180,7 +180,13 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest009, TestSize.Level0) HWTEST_F(DocumentDBDataTest, UpsertDataTest010, TestSize.Level0) { - int result = GRD_UpsertDoc(g_db, g_coll, R"({"_id" : "abcde"})", R"({"a00001":1, "a00001":2})", 0); + int result = GRD_UpsertDoc(g_db, g_coll, R"({"_id" : "abcde"})", R"({"a00001": {"A":1, "A":2}})", 0); + ASSERT_EQ(result, GRD_INVALID_FORMAT); +} + +HWTEST_F(DocumentDBDataTest, UpsertDataTest011, TestSize.Level0) +{ + int result = GRD_UpsertDoc(g_db, g_coll, R"({"_id" : "abcde"})", R"({"t1":{"t22":[1,{"t23":1, "t23":1},3 ,4]}})", 0); ASSERT_EQ(result, GRD_INVALID_FORMAT); } @@ -296,7 +302,7 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest009, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; std::string document = R""({"_id":"1234", "field1":{"c_field":{"cc_field":{"ccc_field":1}}}, "field2" : 2})""; - + EXPECT_EQ(GRD_InsertDoc(g_db, g_coll, document.c_str(), 0), GRD_OK); std::string updata = R""({"field1":1, "FIELD1":[1, true, 1.23456789, "hello world!", null]})"";