diff --git a/frameworks/libs/distributeddb/common/include/db_common.h b/frameworks/libs/distributeddb/common/include/db_common.h index 225fffcf77e62cd9b099e68da15479df96b27c6a..aca9546ebd1905fa32faa191e01a90518b481d9e 100644 --- a/frameworks/libs/distributeddb/common/include/db_common.h +++ b/frameworks/libs/distributeddb/common/include/db_common.h @@ -67,6 +67,8 @@ public: const std::string &nextPattern); static bool IsSameCipher(CipherType srcType, CipherType inputType); + + static bool CheckIsAlnumAndUnderscore(const std::string &text); }; // Define short macro substitute for original long expression for convenience of using diff --git a/frameworks/libs/distributeddb/common/src/db_common.cpp b/frameworks/libs/distributeddb/common/src/db_common.cpp index a3459ec3f1c8c309f545f31374c7fa48b79d51f8..9b51158ddca8d18a7a384cf5d725d05afb549883 100644 --- a/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -395,4 +395,12 @@ bool DBCommon::IsSameCipher(CipherType srcType, CipherType inputType) } return false; } + +bool DBCommon::CheckIsAlnumAndUnderscore(const std::string &text) +{ + auto iter = std::find_if_not(text.begin(), text.end(), [](char c) { + return (std::isalnum(c) || c == '_'); + }); + return iter == text.end(); +} } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/common/src/param_check_utils.cpp b/frameworks/libs/distributeddb/common/src/param_check_utils.cpp index e7a94aac223bf15250f33f7f8bf8a51acf1d9e19..1cb41e1de5d9059e4029098f49c5cbc5e7707dc9 100644 --- a/frameworks/libs/distributeddb/common/src/param_check_utils.cpp +++ b/frameworks/libs/distributeddb/common/src/param_check_utils.cpp @@ -15,6 +15,7 @@ #include "param_check_utils.h" +#include "db_common.h" #include "db_errno.h" #include "platform_specific.h" #include "log_print.h" @@ -199,10 +200,7 @@ uint8_t ParamCheckUtils::GetValidCompressionRate(uint8_t compressionRate) bool ParamCheckUtils::CheckRelationalTableName(const std::string &tableName) { - auto iter = std::find_if_not(tableName.begin(), tableName.end(), [](char c) { - return (std::isalnum(c) || c == '_'); - }); - if (iter != tableName.end()) { + if (!DBCommon::CheckIsAlnumAndUnderscore(tableName)) { return false; } return tableName.compare(0, DBConstant::SYSTEM_TABLE_PREFIX.size(), DBConstant::SYSTEM_TABLE_PREFIX) != 0; diff --git a/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp b/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp index ba8b1c976e5fba289dc81c287c86de4f77fbcb01..fa8936ca51627ad6b8e70de4efb111a87767b120 100644 --- a/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp +++ b/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp @@ -353,6 +353,10 @@ int RelationalSchemaObject::ParseCheckTableName(const JsonObject &inJsonObject, int errCode = GetMemberFromJsonObject(inJsonObject, "NAME", FieldType::LEAF_FIELD_STRING, true, fieldValue); if (errCode == E_OK) { + if (!DBCommon::CheckIsAlnumAndUnderscore(fieldValue.stringValue)) { + LOGE("[RelationalSchema][Parse] Invalid characters in table name, err=%d.", errCode); + return -E_SCHEMA_PARSE_FAIL; + } resultTable.SetTableName(fieldValue.stringValue); } return errCode; @@ -381,6 +385,11 @@ int RelationalSchemaObject::ParseCheckTableDefine(const JsonObject &inJsonObject return errCode; } + if (!DBCommon::CheckIsAlnumAndUnderscore(field.first[1])) { + LOGE("[RelationalSchema][Parse] Invalid characters in field name, err=%d.", errCode); + return -E_SCHEMA_PARSE_FAIL; + } + FieldInfo fieldInfo; fieldInfo.SetFieldName(field.first[1]); // 1 : table name element in path errCode = ParseCheckTableFieldInfo(fieldObj, field.first, fieldInfo); diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp index 3aadddf38f4d5767006f69b1abd13708ab00ed4e..09beed32c883839e4f4f5248dea232dbb31cea7f 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp @@ -111,10 +111,11 @@ std::string CollaborationLogTableManager::GetPrimaryKeySql(const TableInfo &tabl return "PRIMARY KEY(hash_key)"; } -std::string CollaborationLogTableManager::GetIndexSql(const TableInfo &table) +void CollaborationLogTableManager::GetIndexSql(const TableInfo &table, std::vector &schema) { - return SqliteLogTableManager::GetIndexSql(table) + - "CREATE INDEX IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + "datakey_index ON " + GetLogTableName(table) + - "(data_key);"; + SqliteLogTableManager::GetIndexSql(table, schema); + std::string dataKeyIndex = "CREATE INDEX IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + "datakey_index ON " + + GetLogTableName(table) + "(data_key);"; + schema.emplace_back(dataKeyIndex); } } \ No newline at end of file diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.h b/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.h index dc3d3f5514cbedcf958fedd13d9a956d1e6a35a6..c5bea74f1a4a26140934ff79f36819daecbd066f 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.h @@ -30,7 +30,7 @@ private: bool IsCollaborationWithoutKey(const TableInfo &table); std::string GetPrimaryKeySql(const TableInfo &table) override; - std::string GetIndexSql(const TableInfo &table) override; + void GetIndexSql(const TableInfo &table, std::vector &schema) override; std::string GetInsertTrigger(const TableInfo &table, const std::string &identity) override; std::string GetUpdateTrigger(const TableInfo &table, const std::string &identity) override; diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp index 1325697b6edb6c2d33944daf9b86928ef215bee0..4badb1b3154b8e6f0d18f505e1ffd895c7c516a0 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp @@ -25,7 +25,7 @@ int SqliteLogTableManager::AddRelationalLogTableTrigger(sqlite3 *db, const Table for (const auto &sql : sqls) { int errCode = SQLiteUtils::ExecuteRawSQL(db, sql); if (errCode != E_OK) { - LOGE("[SQLite] execute create log trigger sql failed, errCode=%d", errCode); + LOGE("[LogTableManager] execute create log trigger sql failed, errCode=%d", errCode); return errCode; } } @@ -35,9 +35,9 @@ int SqliteLogTableManager::AddRelationalLogTableTrigger(sqlite3 *db, const Table int SqliteLogTableManager::CreateRelationalLogTable(sqlite3 *db, const TableInfo &table) { const std::string tableName = GetLogTableName(table); - std::string primaryKey = GetPrimaryKeySql(table) + ");"; + std::string primaryKey = GetPrimaryKeySql(table); - std::string sql = + std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + tableName + "(" \ "data_key INT NOT NULL," \ "device BLOB," \ @@ -46,17 +46,32 @@ int SqliteLogTableManager::CreateRelationalLogTable(sqlite3 *db, const TableInfo "wtimestamp INT NOT NULL," \ "flag INT NOT NULL," \ "hash_key BLOB NOT NULL," \ - + primaryKey; - sql += GetIndexSql(table); - return SQLiteUtils::ExecuteRawSQL(db, sql); + + primaryKey + ");"; + std::vector logTableSchema; + logTableSchema.emplace_back(createTableSql); + GetIndexSql(table, logTableSchema); + + for (const auto &sql : logTableSchema) { + int errCode = SQLiteUtils::ExecuteRawSQL(db, sql); + if (errCode != E_OK) { + LOGE("[LogTableManager] execute create log table schema failed, errCode=%d", errCode); + return errCode; + } + } + return E_OK; } -std::string SqliteLogTableManager::GetIndexSql(const TableInfo &table) +void SqliteLogTableManager::GetIndexSql(const TableInfo &table, std::vector &schema) { const std::string tableName = GetLogTableName(table); - return "CREATE INDEX IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + "time_flag_index ON " + tableName + - "(timestamp, flag);" \ - "CREATE INDEX IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + "hashkey_index ON " + tableName + "(hash_key);"; + + std::string indexTimestampFlag = "CREATE INDEX IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + + "time_flag_index ON " + tableName + "(timestamp, flag);"; + schema.emplace_back(indexTimestampFlag); + + std::string indexHashkey = "CREATE INDEX IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + + "hashkey_index ON " + tableName + "(hash_key);"; + schema.emplace_back(indexHashkey); } std::string SqliteLogTableManager::GetLogTableName(const TableInfo &table) const diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.h b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.h index d20c67513e92cdce581ea4b34d8eb2e40c3683a8..d792bbe1956a21482226498de92f4211f3a01b83 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.h @@ -34,7 +34,7 @@ public: int CreateRelationalLogTable(sqlite3 *db, const TableInfo &table); protected: - virtual std::string GetIndexSql(const TableInfo &table); + virtual void GetIndexSql(const TableInfo &table, std::vector &schema); std::string GetLogTableName(const TableInfo &table) const; private: diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_data_storage.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_data_storage.cpp index 6255829e3fa8dc6d3f6e28a47ab6eea3692e3d07..de3344c48afe3b1b27d4e20fa3e4d8bc90898151 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_data_storage.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_data_storage.cpp @@ -37,8 +37,10 @@ namespace { const std::string CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS version_data(key BLOB, value BLOB, oper_flag INTEGER, version INTEGER, " \ "timestamp INTEGER, ori_timestamp INTEGER, hash_key BLOB, " \ - "PRIMARY key(hash_key, version));" \ - "CREATE INDEX IF NOT EXISTS version_index ON version_data (version);" \ + "PRIMARY key(hash_key, version));"; + const std::string CREATE_TABLE_VERSION_INDEX_SQL = + "CREATE INDEX IF NOT EXISTS version_index ON version_data (version);"; + const std::string CREATE_TABLE_FLAG_INDEX_SQL = "CREATE INDEX IF NOT EXISTS flag_index ON version_data (oper_flag);"; const std::size_t MAX_READ_CONNECT_NUM = 16; @@ -95,6 +97,8 @@ int SQLiteMultiVerDataStorage::Open(const Property &property) DBConstant::MULTI_VER_DATA_STORE + DBConstant::SQLITE_DB_EXTENSION; std::vector tableVect; tableVect.push_back(CREATE_TABLE_SQL); + tableVect.push_back(CREATE_TABLE_VERSION_INDEX_SQL); + tableVect.push_back(CREATE_TABLE_FLAG_INDEX_SQL); OpenDbProperties option = {uri_, property.isNeedCreate, false, tableVect, property.cipherType, property.passwd}; sqlite3 *db = nullptr; diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp index 37bcfe7da8a03092bfb7592181619e9751769dfb..1d4ef5b16a02f0a3c01cdab5f98f095b8147989f 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp @@ -37,9 +37,13 @@ namespace DistributedDB { const std::string SQLiteMultiVerTransaction::CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS version_data(key BLOB, value BLOB, oper_flag INTEGER, version INTEGER, " \ "timestamp INTEGER, ori_timestamp INTEGER, hash_key BLOB, " \ - "PRIMARY key(hash_key, version));" \ - "CREATE INDEX IF NOT EXISTS version_index ON version_data (version);" \ - "CREATE INDEX IF NOT EXISTS flag_index ON version_data (oper_flag);"; + "PRIMARY key(hash_key, version));"; + + const std::string SQLiteMultiVerTransaction::CREATE_TABLE_VERSION_INDEX_SQL = + "CREATE INDEX IF NOT EXISTS version_index ON version_data (version);"; + + const std::string SQLiteMultiVerTransaction::CREATE_TABLE_FLAG_INDEX_SQL = + "CREATE INDEX IF NOT EXISTS flag_index ON version_data (oper_flag);"; const std::string SQLiteMultiVerTransaction::SELECT_ONE_SQL = "SELECT oper_flag, key, value FROM version_data WHERE hash_key=? AND (timestamp>? OR (timestamp=? AND rowid>=?)) " \ @@ -138,6 +142,8 @@ int SQLiteMultiVerTransaction::Initialize(const std::string &uri, { std::vector tableVect; tableVect.push_back(CREATE_TABLE_SQL); + tableVect.push_back(CREATE_TABLE_VERSION_INDEX_SQL); + tableVect.push_back(CREATE_TABLE_FLAG_INDEX_SQL); OpenDbProperties option = {uri, true, false, tableVect, type, passwd}; int errCode = SQLiteUtils::OpenDatabase(option, db_); if (errCode != E_OK) { diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.h b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.h index bee608f78697d991b6f54cb1f8fce778af106edd..26d88682b42bf261aa64c452f4f48caaecd453cd 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.h @@ -165,6 +165,8 @@ private: int GetPrePutValues(const Version &versionInfo, Timestamp timestamp, std::vector &values) const; static const std::string CREATE_TABLE_SQL; + static const std::string CREATE_TABLE_VERSION_INDEX_SQL; + static const std::string CREATE_TABLE_FLAG_INDEX_SQL; static const std::string SELECT_ONE_SQL; // select the rowid static const std::string SELECT_BATCH_SQL; // select the rowid and the key static const std::string SELECT_HASH_ENTRY_SQL; // select the data according the hash key diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp index f0ff27eed147d72f26fe62507bd738f525fcdefd..3dd7bc99124c43458cf9de4e954092c10af914ff 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp @@ -52,10 +52,16 @@ namespace { "key BLOB PRIMARY KEY NOT NULL," \ "value BLOB);"; - const std::string CREATE_SYNC_TABLE_INDEX_SQL = - "CREATE INDEX IF NOT EXISTS key_index ON sync_data (key, flag);" \ - "CREATE INDEX IF NOT EXISTS time_index ON sync_data (timestamp);" \ - "CREATE INDEX IF NOT EXISTS dev_index ON sync_data (device);" \ + const std::string CREATE_SYNC_TABLE_INDEX_SQL_KEY_INDEX = + "CREATE INDEX IF NOT EXISTS key_index ON sync_data (key, flag);"; + + const std::string CREATE_SYNC_TABLE_INDEX_SQL_TIME_INDEX = + "CREATE INDEX IF NOT EXISTS time_index ON sync_data (timestamp);"; + + const std::string CREATE_SYNC_TABLE_INDEX_SQL_DEV_INDEX = + "CREATE INDEX IF NOT EXISTS dev_index ON sync_data (device);"; + + const std::string CREATE_SYNC_TABLE_INDEX_SQL_LOCAL_HASHKEY_INDEX = "CREATE INDEX IF NOT EXISTS local_hashkey_index ON local_data (hash_key);"; const std::string DROP_META_TABLE_SQL = "DROP TABLE IF EXISTS main.meta_data;"; @@ -151,14 +157,20 @@ void SQLiteSingleVerDatabaseUpgrader::SetUpgradeSqls(int version, std::vector indexes; while (true) { errCode = SQLiteUtils::StepWithRetry(stmt, false); if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { std::string indexSql; (void)GetColumnTextValue(stmt, 0, indexSql); - sql += indexSql; + indexes.emplace_back(indexSql); continue; } if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { @@ -1428,9 +1433,12 @@ int SQLiteUtils::CloneIndexes(sqlite3 *db, const std::string &oriTableName, cons if (errCode != E_OK) { return errCode; } - errCode = SQLiteUtils::ExecuteRawSQL(db, sql); - if (errCode != E_OK) { - LOGE("[SQLite] execute create table sql failed"); + + for (const auto &it : indexes) { + errCode = SQLiteUtils::ExecuteRawSQL(db, it); + if (errCode != E_OK) { + LOGE("[SQLite] execute clone index sql failed"); + } } return errCode; } diff --git a/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp index 84f358559c170acd8571b8e6cf9a371e7f722fc2..8f943acff280648bd4d540f2b6900dfeba79339a 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp @@ -213,6 +213,7 @@ namespace { const std::string TABLE_DEFINE_STR_NAME = R""("NAME": "FIRST",)""; const std::string TABLE_DEFINE_STR_NAME_INVALID = R"("NAME": 123,)"; + const std::string TABLE_DEFINE_STR_NAME_INVALID_CHARACTER = R"("NAME": "t1; --",)"; const std::string TABLE_DEFINE_STR_FIELDS = R""("DEFINE": { "field_name1": { "COLUMN_ID":1, @@ -233,6 +234,12 @@ namespace { "NOT_NULL": true, "DEFAULT": "abcd" }},)""; + const std::string TABLE_DEFINE_STR_FIELDS_INVALID_CHARACTER = R""("DEFINE": { + "1 = 1; --": { + "COLUMN_ID":1, + "NOT_NULL": true, + "DEFAULT": "abcd" + }},)""; const std::string TABLE_DEFINE_STR_KEY = R""("PRIMARY_KEY": "field_name1")""; const std::string TABLE_DEFINE_BOOL_KEY_INVALID = R""("PRIMARY_KEY": false)""; const std::string TABLE_DEFINE_BOOL_ARRAY_KEY_INVALID = R""("PRIMARY_KEY": [false, true, true])""; @@ -384,6 +391,16 @@ HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest003, errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr05 + "]")); EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL); + std::string invalidTableStr07 = "{" + TABLE_DEFINE_STR_NAME_INVALID_CHARACTER + TABLE_DEFINE_STR_FIELDS + + TABLE_DEFINE_STR_KEY + "}"; + errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr07 + "]")); + EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL); + + std::string invalidTableStr08 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS_INVALID_CHARACTER + + TABLE_DEFINE_STR_KEY + "}"; + errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr08 + "]")); + EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL); + errCode = schemaObj.ParseFromSchemaString(""); EXPECT_EQ(errCode, -E_INVALID_ARGS); } diff --git a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index 2b3c5162224de6bf82b36af7d180edb47a49fbe0..c9284cb0f1573d9abafe00cd20e0bcb6a5e288f0 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -73,6 +73,8 @@ namespace { const std::string INSERT_SYNC_DATA_SQL = "INSERT OR REPLACE INTO sync_data (key, timestamp, flag, hash_key) " "VALUES('KEY', 123456789, 1, 'HASH_KEY');"; + + const std::string INVALID_TABLE_FIELD_SQL = "create table if not exists t1 ('1 = 1; --' int primary key, b blob)"; } class DistributedDBInterfacesRelationalTest : public testing::Test { @@ -333,6 +335,9 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalStoreTest005, TestSize EXPECT_EQ(delegate->CreateDistributedTable("Handle-J@^."), INVALID_ARGS); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, INVALID_TABLE_FIELD_SQL), SQLITE_OK); + EXPECT_EQ(delegate->CreateDistributedTable("t1"), NOT_SUPPORT); + /** * @tc.steps:step4. Close store * @tc.expected: step4. Return OK.