From 40d32e16b0a743bc9946467ad2e93bca0c290c17 Mon Sep 17 00:00:00 2001 From: wangjiaming Date: Mon, 17 Mar 2025 14:13:03 +0800 Subject: [PATCH] fix(TS-6117): fix drop table name with star crash (#30204) --- source/libs/parser/src/parUtil.c | 62 ++++++++++++++++++++++-------- tests/system-test/1-insert/drop.py | 9 +++++ 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 0cda428487..b48aece8e5 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -596,8 +596,8 @@ int32_t getVnodeSysTableTargetName(int32_t acctId, SNode* pWhere, SName* pName) static int32_t userAuthToString(int32_t acctId, const char* pUser, const char* pDb, const char* pTable, AUTH_TYPE type, char* pStr, bool isView) { - return snprintf(pStr, USER_AUTH_KEY_MAX_LEN, "%s*%d*%s*%s*%d*%d", pUser, acctId, pDb, - (NULL == pTable || '\0' == pTable[0]) ? "``" : pTable, type, isView); + return snprintf(pStr, USER_AUTH_KEY_MAX_LEN, "`%s`*%d*`%s`*`%s`*%d*%d", pUser, acctId, pDb, + (NULL == pTable || '\0' == pTable[0]) ? "" : pTable, type, isView); } static int32_t getIntegerFromAuthStr(const char* pStart, char** pNext) { @@ -613,6 +613,30 @@ static int32_t getIntegerFromAuthStr(const char* pStart, char** pNext) { return taosStr2Int32(buf, NULL, 10); } +static int32_t getBackQuotedStringFromAuthStr(const char* pStart, char* pStr, uint32_t dstLen, char** pNext) { + const char* pBeginQuote = strchr(pStart, '`'); + if (!pBeginQuote) { + qWarn("failed to get string from auth string, %s, should be quoted with `", pStart); + return TSDB_CODE_INVALID_PARA; + } + const char* pEndQuote = strchr(pBeginQuote + 1, '`'); + if (!pEndQuote) { + qWarn("failed to get string from auth string, %s, should be quoted with `", pStart); + return TSDB_CODE_INVALID_PARA; + } + + pStr[0] = '\0'; + strncpy(pStr, pBeginQuote + 1, TMIN(dstLen, pEndQuote - pBeginQuote - 1)); + + char* pSeperator = strchr(pEndQuote + 1, '*'); + if (!pSeperator) { + *pNext = NULL; + } else { + *pNext = ++pSeperator; + } + return 0; +} + static void getStringFromAuthStr(const char* pStart, char* pStr, uint32_t dstLen, char** pNext) { char* p = strchr(pStart, '*'); if (NULL == p) { @@ -627,19 +651,26 @@ static void getStringFromAuthStr(const char* pStart, char* pStr, uint32_t dstLen } } -static void stringToUserAuth(const char* pStr, int32_t len, SUserAuthInfo* pUserAuth) { +static int32_t stringToUserAuth(const char* pStr, int32_t len, SUserAuthInfo* pUserAuth) { char* p = NULL; - getStringFromAuthStr(pStr, pUserAuth->user, TSDB_USER_LEN, &p); - pUserAuth->tbName.acctId = getIntegerFromAuthStr(p, &p); - getStringFromAuthStr(p, pUserAuth->tbName.dbname, TSDB_DB_NAME_LEN, &p); - getStringFromAuthStr(p, pUserAuth->tbName.tname, TSDB_TABLE_NAME_LEN, &p); - if (pUserAuth->tbName.tname[0]) { - pUserAuth->tbName.type = TSDB_TABLE_NAME_T; - } else { - pUserAuth->tbName.type = TSDB_DB_NAME_T; + int32_t code = getBackQuotedStringFromAuthStr(pStr, pUserAuth->user, TSDB_USER_LEN, &p); + if (code == TSDB_CODE_SUCCESS) { + pUserAuth->tbName.acctId = getIntegerFromAuthStr(p, &p); + code = getBackQuotedStringFromAuthStr(p, pUserAuth->tbName.dbname, TSDB_DB_NAME_LEN, &p); } - pUserAuth->type = getIntegerFromAuthStr(p, &p); - pUserAuth->isView = getIntegerFromAuthStr(p, &p); + if (code == TSDB_CODE_SUCCESS) { + code = getBackQuotedStringFromAuthStr(p, pUserAuth->tbName.tname, TSDB_TABLE_NAME_LEN, &p); + } + if (code == TSDB_CODE_SUCCESS) { + if (pUserAuth->tbName.tname[0]) { + pUserAuth->tbName.type = TSDB_TABLE_NAME_T; + } else { + pUserAuth->tbName.type = TSDB_DB_NAME_T; + } + pUserAuth->type = getIntegerFromAuthStr(p, &p); + pUserAuth->isView = getIntegerFromAuthStr(p, &p); + } + return code; } static int32_t buildTableReq(SHashObj* pTablesHash, SArray** pTables) { @@ -740,8 +771,9 @@ static int32_t buildUserAuthReq(SHashObj* pUserAuthHash, SArray** pUserAuth) { char key[USER_AUTH_KEY_MAX_LEN] = {0}; strncpy(key, pKey, len); SUserAuthInfo userAuth = {0}; - stringToUserAuth(key, len, &userAuth); - if (NULL == taosArrayPush(*pUserAuth, &userAuth)) { + int32_t code = stringToUserAuth(key, len, &userAuth); + if (TSDB_CODE_SUCCESS != code) terrno = code; + if (code != 0 || NULL == taosArrayPush(*pUserAuth, &userAuth)) { taosHashCancelIterate(pUserAuthHash, p); taosArrayDestroy(*pUserAuth); *pUserAuth = NULL; diff --git a/tests/system-test/1-insert/drop.py b/tests/system-test/1-insert/drop.py index ad9f6c9be6..22a24f31f2 100644 --- a/tests/system-test/1-insert/drop.py +++ b/tests/system-test/1-insert/drop.py @@ -299,7 +299,16 @@ class TDTestCase: tdSql.query(f'select * from information_schema.ins_streams where stream_name = "{stream_name}"') tdSql.checkEqual(tdSql.queryResult[0][4],f'create stream {stream_name} trigger at_once ignore expired 0 into stb1 as select * from tb') tdSql.execute(f'drop database {self.dbname}') + def test_table_name_with_star(self): + dbname = "test_tbname_with_star" + tbname = 's_*cszl01_207602da' + tdSql.execute(f'create database {dbname} replica 1 wal_retention_period 3600') + tdSql.execute(f'create table {dbname}.`{tbname}` (ts timestamp, c1 int)', queryTimes=1, show=1) + tdSql.execute(f"drop table {dbname}.`{tbname}`") + tdSql.execute(f"drop database {dbname}") + def run(self): + self.test_table_name_with_star() self.drop_ntb_check() self.drop_stb_ctb_check() self.drop_stable_with_check()