diff --git a/src/client/src/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index e6e0cf6b4d..61d9e5a785 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -1391,6 +1391,105 @@ static bool isTimeStamp(char *pVal, uint16_t len, SMLTimeStampType *tsType) { return false; } +static bool convertStrToNumber(TAOS_SML_KV *pVal, char*str) { + errno = 0; + uint8_t type = pVal->type; + int16_t length = pVal->length; + int64_t val_s; + uint64_t val_u; + double val_d; + + if (IS_FLOAT_TYPE(type)) { + val_d = strtod(str, NULL); + } else { + if (IS_SIGNED_NUMERIC_TYPE(type)) { + val_s = strtoll(str, NULL, 10); + } else { + val_u = strtoull(str, NULL, 10); + } + } + + if (errno == ERANGE) { + tscError("Converted number out of range"); + return false; + } + + switch (type) { + case TSDB_DATA_TYPE_TINYINT: + if (!IS_VALID_TINYINT(val_s)) { + return false; + } + pVal->value = calloc(length, 1); + *(int8_t *)(pVal->value) = (int8_t)val_s; + break; + case TSDB_DATA_TYPE_UTINYINT: + if (!IS_VALID_UTINYINT(val_u)) { + return false; + } + pVal->value = calloc(length, 1); + *(uint8_t *)(pVal->value) = (uint8_t)val_u; + break; + case TSDB_DATA_TYPE_SMALLINT: + if (!IS_VALID_SMALLINT(val_s)) { + return false; + } + pVal->value = calloc(length, 1); + *(int16_t *)(pVal->value) = (int16_t)val_s; + break; + case TSDB_DATA_TYPE_USMALLINT: + if (!IS_VALID_USMALLINT(val_u)) { + return false; + } + pVal->value = calloc(length, 1); + *(uint16_t *)(pVal->value) = (uint16_t)val_u; + break; + case TSDB_DATA_TYPE_INT: + if (!IS_VALID_INT(val_s)) { + return false; + } + pVal->value = calloc(length, 1); + *(int32_t *)(pVal->value) = (int32_t)val_s; + break; + case TSDB_DATA_TYPE_UINT: + if (!IS_VALID_UINT(val_u)) { + return false; + } + pVal->value = calloc(length, 1); + *(uint32_t *)(pVal->value) = (uint32_t)val_u; + break; + case TSDB_DATA_TYPE_BIGINT: + if (!IS_VALID_BIGINT(val_s)) { + return false; + } + pVal->value = calloc(length, 1); + *(int64_t *)(pVal->value) = (int64_t)val_s; + break; + case TSDB_DATA_TYPE_UBIGINT: + if (!IS_VALID_UBIGINT(val_u)) { + return false; + } + pVal->value = calloc(length, 1); + *(uint64_t *)(pVal->value) = (uint64_t)val_u; + break; + case TSDB_DATA_TYPE_FLOAT: + if (!IS_VALID_FLOAT(val_d)) { + return false; + } + pVal->value = calloc(length, 1); + *(float *)(pVal->value) = (float)val_d; + break; + case TSDB_DATA_TYPE_DOUBLE: + if (!IS_VALID_DOUBLE(val_d)) { + return false; + } + pVal->value = calloc(length, 1); + *(double *)(pVal->value) = (double)val_d; + break; + default: + return false; + } + return true; +} //len does not include '\0' from value. static bool convertSmlValueType(TAOS_SML_KV *pVal, char *value, uint16_t len) { @@ -1403,97 +1502,72 @@ static bool convertSmlValueType(TAOS_SML_KV *pVal, char *value, pVal->type = TSDB_DATA_TYPE_TINYINT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 2] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - int8_t val = (int8_t)strtoll(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); return true; } if (isTinyUint(value, len)) { pVal->type = TSDB_DATA_TYPE_UTINYINT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 2] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - uint8_t val = (uint8_t)strtoul(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); return true; } if (isSmallInt(value, len)) { pVal->type = TSDB_DATA_TYPE_SMALLINT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - int16_t val = (int16_t)strtoll(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); return true; } if (isSmallUint(value, len)) { pVal->type = TSDB_DATA_TYPE_USMALLINT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - uint16_t val = (uint16_t)strtoul(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); - //memcpy(pVal->value, &val, pVal->length); return true; } if (isInt(value, len)) { pVal->type = TSDB_DATA_TYPE_INT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - int32_t val = (int32_t)strtoll(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); return true; } if (isUint(value, len)) { pVal->type = TSDB_DATA_TYPE_UINT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - uint32_t val = (uint32_t)strtoul(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); return true; } if (isBigInt(value, len)) { pVal->type = TSDB_DATA_TYPE_BIGINT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - int64_t val = (int64_t)strtoll(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); return true; } if (isBigUint(value, len)) { pVal->type = TSDB_DATA_TYPE_UBIGINT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidInteger(value)) { + if (!isValidInteger(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - uint64_t val = (uint64_t)strtoul(value, NULL, 10); - memcpy(pVal->value, &val, pVal->length); return true; } //floating number @@ -1501,24 +1575,18 @@ static bool convertSmlValueType(TAOS_SML_KV *pVal, char *value, pVal->type = TSDB_DATA_TYPE_FLOAT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidFloat(value)) { + if (!isValidFloat(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - float val = (float)strtold(value, NULL); - memcpy(pVal->value, &val, pVal->length); return true; } if (isDouble(value, len)) { pVal->type = TSDB_DATA_TYPE_DOUBLE; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; value[len - 3] = '\0'; - if (!isValidFloat(value)) { + if (!isValidFloat(value) || !convertStrToNumber(pVal, value)) { return false; } - pVal->value = calloc(pVal->length, 1); - double val = (double)strtold(value, NULL); - memcpy(pVal->value, &val, pVal->length); return true; } //binary @@ -1552,9 +1620,9 @@ static bool convertSmlValueType(TAOS_SML_KV *pVal, char *value, if (isValidInteger(value) || isValidFloat(value)) { pVal->type = TSDB_DATA_TYPE_FLOAT; pVal->length = (int16_t)tDataTypes[pVal->type].bytes; - pVal->value = calloc(pVal->length, 1); - float val = (float)strtold(value, NULL); - memcpy(pVal->value, &val, pVal->length); + if (!convertStrToNumber(pVal, value)) { + return false; + } return true; } return false; @@ -1728,6 +1796,7 @@ static bool parseSmlValue(TAOS_SML_KV *pKV, const char **index, if (!convertSmlValueType(pKV, value, len)) { //free previous alocated key field free(pKV->key); + pKV->key = NULL; free(value); return TSDB_CODE_TSC_LINE_SYNTAX_ERROR; } diff --git a/src/inc/ttype.h b/src/inc/ttype.h index 6e436bd23d..fcd2651c70 100644 --- a/src/inc/ttype.h +++ b/src/inc/ttype.h @@ -138,6 +138,8 @@ typedef struct { #define IS_VALID_USMALLINT(_t) ((_t) >= 0 && (_t) < UINT16_MAX) #define IS_VALID_UINT(_t) ((_t) >= 0 && (_t) < UINT32_MAX) #define IS_VALID_UBIGINT(_t) ((_t) >= 0 && (_t) < UINT64_MAX) +#define IS_VALID_FLOAT(_t) ((_t) >= -FLT_MAX && (_t) <= FLT_MAX) +#define IS_VALID_DOUBLE(_t) ((_t) >= -DBL_MAX && (_t) <= DBL_MAX) static FORCE_INLINE bool isNull(const char *val, int32_t type) { switch (type) { diff --git a/src/util/src/tstrbuild.c b/src/util/src/tstrbuild.c index 61a6d67952..eec21d1835 100644 --- a/src/util/src/tstrbuild.c +++ b/src/util/src/tstrbuild.c @@ -69,12 +69,12 @@ void taosStringBuilderAppendNull(SStringBuilder* sb) { taosStringBuilderAppendSt void taosStringBuilderAppendInteger(SStringBuilder* sb, int64_t v) { char buf[64]; - size_t len = sprintf(buf, "%" PRId64, v); - taosStringBuilderAppendStringLen(sb, buf, len); + size_t len = snprintf(buf, sizeof(buf), "%" PRId64, v); + taosStringBuilderAppendStringLen(sb, buf, MIN(len, sizeof(buf))); } void taosStringBuilderAppendDouble(SStringBuilder* sb, double v) { - char buf[64]; - size_t len = sprintf(buf, "%.9lf", v); - taosStringBuilderAppendStringLen(sb, buf, len); + char buf[512]; + size_t len = snprintf(buf, sizeof(buf), "%.9lf", v); + taosStringBuilderAppendStringLen(sb, buf, MIN(len, sizeof(buf))); }