From c7f6349e14eeff5ae442c26ffdff2e26f7140808 Mon Sep 17 00:00:00 2001 From: xsren <285808407@qq.com> Date: Thu, 10 Oct 2024 10:35:29 +0800 Subject: [PATCH] tsnprintf --- include/os/osString.h | 7 ++--- source/libs/command/src/command.c | 16 +++++++----- source/libs/function/src/tudf.c | 2 +- source/os/src/osString.c | 15 +++++++++++ source/os/test/osStringTests.cpp | 43 +++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 10 deletions(-) diff --git a/include/os/osString.h b/include/os/osString.h index b184e7efdb..5c6b5b06cf 100644 --- a/include/os/osString.h +++ b/include/os/osString.h @@ -59,12 +59,13 @@ typedef enum { M2C = 0, C2M } ConvType; #endif -#define tstrncpy(dst, src, size) \ - do { \ +#define tstrncpy(dst, src, size) \ + do { \ (void)strncpy((dst), (src), (size)); \ - (dst)[(size)-1] = 0; \ + (dst)[(size) - 1] = 0; \ } while (0) +int64_t tsnprintf(char *dst, int64_t size, const char *format, ...); #define TAOS_STRCPY(_dst, _src) ((void)strcpy(_dst, _src)) #define TAOS_STRNCPY(_dst, _src, _size) ((void)strncpy(_dst, _src, _size)) #define TAOS_STRCAT(_dst, _src) ((void)strcat(_dst, _src)) diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 1ab568905f..dac14de678 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -510,20 +510,24 @@ void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) { #define LTYPE_LEN (32 + 60) // 60 byte for compress info char type[LTYPE_LEN]; snprintf(type, LTYPE_LEN, "%s", tDataTypes[pSchema->type].name); + int typeLen = strlen(type); if (TSDB_DATA_TYPE_VARCHAR == pSchema->type || TSDB_DATA_TYPE_VARBINARY == pSchema->type || TSDB_DATA_TYPE_GEOMETRY == pSchema->type) { - snprintf(type + strlen(type), LTYPE_LEN - strlen(type), "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); + snprintf(type + typeLen, LTYPE_LEN - typeLen, "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); } else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) { - snprintf(type + strlen(type), LTYPE_LEN - strlen(type), "(%d)", + snprintf(type + typeLen, LTYPE_LEN - typeLen, "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)); } if (useCompress(pCfg->tableType) && pCfg->pSchemaExt) { - snprintf(type + strlen(type), LTYPE_LEN - strlen(type), " ENCODE \'%s\'", + typeLen = strlen(type); + snprintf(type + typeLen, LTYPE_LEN - typeLen, " ENCODE \'%s\'", columnEncodeStr(COMPRESS_L1_TYPE_U32(pCfg->pSchemaExt[i].compress))); - snprintf(type + strlen(type), LTYPE_LEN - strlen(type), " COMPRESS \'%s\'", + typeLen = strlen(type); + snprintf(type + typeLen, LTYPE_LEN - typeLen, " COMPRESS \'%s\'", columnCompressStr(COMPRESS_L2_TYPE_U32(pCfg->pSchemaExt[i].compress))); - snprintf(type + strlen(type), LTYPE_LEN - strlen(type), " LEVEL \'%s\'", + typeLen = strlen(type); + snprintf(type + typeLen, LTYPE_LEN - typeLen, " LEVEL \'%s\'", columnLevelStr(COMPRESS_L2_TYPE_LEVEL_U32(pCfg->pSchemaExt[i].compress))); } if (!(pSchema->flags & COL_IS_KEY)) { @@ -694,7 +698,7 @@ void appendTableOptions(char* buf, int32_t* len, SDbCfgInfo* pDbCfg, STableCfg* if (nSma < pCfg->numOfColumns && nSma > 0) { bool smaOn = false; - *len += snprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len), + *len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len), " SMA("); for (int32_t i = 0; i < pCfg->numOfColumns; ++i) { if (IS_BSMA_ON(pCfg->pSchemas + i)) { diff --git a/source/libs/function/src/tudf.c b/source/libs/function/src/tudf.c index 3a0cff7cf3..7496cc492c 100644 --- a/source/libs/function/src/tudf.c +++ b/source/libs/function/src/tudf.c @@ -143,7 +143,7 @@ static int32_t udfSpawnUdfd(SUdfdData *pData) { char udfdPathLdLib[1024] = {0}; size_t udfdLdLibPathLen = strlen(tsUdfdLdLibPath); - tstrncpy(udfdPathLdLib, tsUdfdLdLibPath, sizeof(udfdPathLdLib) < sizeof(tsUdfdLdLibPath) ? sizeof(udfdPathLdLib) : sizeof(tsUdfdLdLibPath)); + tstrncpy(udfdPathLdLib, tsUdfdLdLibPath, sizeof(udfdPathLdLib)); udfdPathLdLib[udfdLdLibPathLen] = ':'; tstrncpy(udfdPathLdLib + udfdLdLibPathLen + 1, pathTaosdLdLib, sizeof(udfdPathLdLib) - udfdLdLibPathLen - 1); diff --git a/source/os/src/osString.c b/source/os/src/osString.c index d265ed510a..16e28f78b2 100644 --- a/source/os/src/osString.c +++ b/source/os/src/osString.c @@ -710,3 +710,18 @@ int32_t taosAscii2Hex(const char *z, uint32_t n, void **data, uint32_t *size) { return 0; } + +int64_t tsnprintf(char *dst, int64_t size, const char *format, ...) { + if (size <= 0 || size > SIZE_MAX) return 0; + + int64_t ret; + va_list args; + va_start(args, format); + ret = vsnprintf(dst, size, format, args); + va_end(args ); + if (ret >= size) { + return size - 1; + } else { + return ret; + } +} diff --git a/source/os/test/osStringTests.cpp b/source/os/test/osStringTests.cpp index 9565e568fb..03cab70f30 100644 --- a/source/os/test/osStringTests.cpp +++ b/source/os/test/osStringTests.cpp @@ -14,6 +14,7 @@ */ #include +#include #include #pragma GCC diagnostic push @@ -111,3 +112,45 @@ TEST(osStringTests, osUcs4lenTests2) { TdUcs4 ucs4_3[] = {'C', 'h', 'i', 'n', 'a', 0x4E2D, 0x6587, '\0'}; EXPECT_EQ(taosUcs4len(ucs4_3), 7); } + +TEST(osStringTests, ostsnprintfTests) { + char buffer[50] = {0}; + int64_t ret; + + ret = tsnprintf(buffer, sizeof(buffer), "Hello, %s!", "World"); + EXPECT_EQ(ret, 13); + EXPECT_STREQ(buffer, "Hello, World!"); + + memset(buffer, 0, sizeof(buffer)); + ret = tsnprintf(buffer, 10, "Hello, %s!", "World"); + EXPECT_EQ(ret, 9); + EXPECT_EQ(strncmp(buffer, "Hello, Wo", 9), 0); + + memset(buffer, 0, sizeof(buffer)); + ret = tsnprintf(buffer, 10, "Hello%s", "World"); + EXPECT_EQ(ret, 9); + EXPECT_EQ(strncmp(buffer, "Hello, Wo", 9), 0); + + memset(buffer, 0, sizeof(buffer)); + ret = tsnprintf(buffer, 0, "Hello, %s!", "World"); + EXPECT_EQ(ret, 0); + + memset(buffer, 0, sizeof(buffer)); + ret = tsnprintf(buffer, SIZE_MAX + 1, "Hello, %s!", "World"); + EXPECT_EQ(ret, 0); + + memset(buffer, 0, sizeof(buffer)); + ret = tsnprintf(buffer, sizeof(buffer), ""); + EXPECT_EQ(ret, 0); + EXPECT_STREQ(buffer, ""); + + memset(buffer, 0, sizeof(buffer)); + ret = tsnprintf(buffer, sizeof(buffer), "Number: %d", 42); + EXPECT_EQ(ret, 10); + EXPECT_STREQ(buffer, "Number: 42"); + + memset(buffer, 0, sizeof(buffer)); + ret = tsnprintf(buffer, sizeof(buffer), "Float: %.2f", 3.14); + EXPECT_EQ(ret, 11); + EXPECT_STREQ(buffer, "Float: 3.14"); +}