avoid runtime error for double to int64_t conversion

This commit is contained in:
wangjiaming0909 2024-09-12 14:57:03 +08:00
parent 19e95c126c
commit 49e2f1f0a4
2 changed files with 34 additions and 8 deletions

View File

@ -23,14 +23,16 @@
#define UNIT_ONE_PEBIBYTE (UNIT_ONE_TEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
#define UNIT_ONE_EXBIBYTE (UNIT_ONE_PEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
static int32_t parseCfgIntWithUnit(const char* str, double* res) {
double val, temp = (double)INT64_MAX;
static int32_t parseCfgIntWithUnit(const char* str, int64_t* res) {
double val = 0, temp = (double)INT64_MAX;
char* endPtr;
bool useDouble = false;
errno = 0;
val = taosStr2Int64(str, &endPtr, 0);
int64_t int64Val = taosStr2Int64(str, &endPtr, 0);
if (*endPtr == '.' || errno == ERANGE) {
errno = 0;
val = taosStr2Double(str, &endPtr);
useDouble = true;
}
if (endPtr == str || errno == ERANGE || isnan(val)) {
return terrno = TSDB_CODE_INVALID_CFG_VALUE;
@ -67,23 +69,33 @@ static int32_t parseCfgIntWithUnit(const char* str, double* res) {
default:
return terrno = TSDB_CODE_INVALID_CFG_VALUE;
}
endPtr++;
if ((val > 0 && val > temp) || (val < 0 && val < -temp)) {
return terrno = TSDB_CODE_OUT_OF_RANGE;
}
endPtr++;
val *= factor;
int64Val *= factor;
}
while (isspace((unsigned char)*endPtr)) endPtr++;
if (*endPtr) {
return terrno = TSDB_CODE_INVALID_CFG_VALUE;
}
val = rint(val);
*res = val;
if (useDouble) {
val = rint(val);
if ((val > 0 && val >= (double)INT64_MAX) || (val < 0 && val <= (double)INT64_MIN)) {
return terrno = TSDB_CODE_OUT_OF_RANGE;
} else {
*res = (int64_t)val;
}
} else {
*res = int64Val;
}
return TSDB_CODE_SUCCESS;
}
int32_t taosStrHumanToInt64(const char* str, int64_t* out) {
double res;
int64_t res;
int32_t code = parseCfgIntWithUnit(str, &res);
if (code == TSDB_CODE_SUCCESS) *out = (int64_t)res;
return code;
@ -109,7 +121,7 @@ void taosInt64ToHumanStr(int64_t val, char* outStr) {
#endif
int32_t taosStrHumanToInt32(const char* str, int32_t* out) {
double res;
int64_t res;
int32_t code = parseCfgIntWithUnit(str, &res);
if (code == TSDB_CODE_SUCCESS) {
if (res < INT32_MIN || res > INT32_MAX) {

View File

@ -284,6 +284,20 @@ class TDTestCase:
for error_val in error_vals:
tdSql.error(f'ALTER DNODE 1 "{var}" "{error_val}"')
var = 'randErrorDivisor'
vals = ['9223372036854775807', '9223372036854775807.1', '9223372036854775806', '9223372036854775808', '9223372036854775808.1', '9223372036854775807.0', '9223372036854775806.1']
expected_vals = ['9223372036854775807', 'err', '9223372036854775806', 'err', 'err', 'err', 'err']
for val_str, expected_val in zip(vals, expected_vals):
sql = f'ALTER dnode 1 "{var}" "{val_str}"'
if expected_val == 'err':
tdSql.error(sql)
else:
tdSql.execute(sql, queryTimes=1)
actual_val = self.get_variable(var, False)
if expected_val != actual_val:
tdLog.exit(f"failed to set local {var} to {expected_val} actually {actual_val}")
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)