From 8c49afc1f47ddc5cd00e2f42ff13964d7e85dbf8 Mon Sep 17 00:00:00 2001 From: Bomin Zhang Date: Thu, 28 May 2020 16:15:24 +0800 Subject: [PATCH] fix incorrect length in nchar conversion --- src/client/src/tscSubquery.c | 5 ++++- src/util/inc/tutil.h | 2 +- src/util/src/tutil.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 3a205924bf..8c741dfdc8 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -1888,11 +1888,14 @@ static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pF /* string terminated char for binary data*/ memset(pRes->buffer[columnIndex], 0, pField->bytes + TSDB_NCHAR_SIZE); - if (taosUcs4ToMbs(pRes->tsrow[columnIndex], pField->bytes - VARSTR_HEADER_SIZE, pRes->buffer[columnIndex])) { + int32_t length = taosUcs4ToMbs(pRes->tsrow[columnIndex], pRes->length[columnIndex], pRes->buffer[columnIndex]); + if ( length >= 0 ) { pRes->tsrow[columnIndex] = pRes->buffer[columnIndex]; + pRes->length[columnIndex] = length; } else { tscError("%p charset:%s to %s. val:%ls convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, pRes->tsrow[columnIndex]); pRes->tsrow[columnIndex] = NULL; + pRes->length[columnIndex] = 0; } } } diff --git a/src/util/inc/tutil.h b/src/util/inc/tutil.h index 3a0a1920af..5dcb6e406f 100644 --- a/src/util/inc/tutil.h +++ b/src/util/inc/tutil.h @@ -145,7 +145,7 @@ bool taosMbsToUcs4(char *mbs, size_t mbs_len, char *ucs4, int32_t ucs4_max_len, int tasoUcs4Compare(void* f1_ucs4, void *f2_ucs4, int bytes); -bool taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs); +int32_t taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs); bool taosValidateEncodec(const char *encodec); diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c index 989273e051..2392560370 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -447,10 +447,10 @@ int tasoUcs4Compare(void* f1_ucs4, void *f2_ucs4, int bytes) { int32_t ucs4_max_len = bytes + 4; char *f1_mbs = calloc(bytes, 1); char *f2_mbs = calloc(bytes, 1); - if (!taosUcs4ToMbs(f1_ucs4, ucs4_max_len, f1_mbs)) { + if (taosUcs4ToMbs(f1_ucs4, ucs4_max_len, f1_mbs) < 0) { return -1; } - if (!taosUcs4ToMbs(f2_ucs4, ucs4_max_len, f2_mbs)) { + if (taosUcs4ToMbs(f2_ucs4, ucs4_max_len, f2_mbs) < 0) { return -1; } int32_t ret = strcmp(f1_mbs, f2_mbs); @@ -464,29 +464,29 @@ int tasoUcs4Compare(void* f1_ucs4, void *f2_ucs4, int bytes) { #endif } -bool taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs) { +int32_t taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs) { #ifdef USE_LIBICONV iconv_t cd = iconv_open(tsCharset, DEFAULT_UNICODE_ENCODEC); size_t ucs4_input_len = ucs4_max_len; size_t outLen = ucs4_max_len; if (iconv(cd, (char **)&ucs4, &ucs4_input_len, &mbs, &outLen) == -1) { iconv_close(cd); - return false; + return -1; } iconv_close(cd); - return true; + return (int32_t)(ucs4_max_len - outLen); #else mbstate_t state = {0}; int32_t len = (int32_t) wcsnrtombs(NULL, (const wchar_t **) &ucs4, ucs4_max_len / 4, 0, &state); if (len < 0) { - return false; + return -1; } memset(&state, 0, sizeof(state)); len = wcsnrtombs(mbs, (const wchar_t **) &ucs4, ucs4_max_len / 4, (size_t) len, &state); if (len < 0) { - return false; + return -1; } - return true; + return len; #endif } -- GitLab