未验证 提交 5ae3eeee 编写于 作者: S Shengliang Guan 提交者: GitHub

Merge pull request #18212 from taosdata/fix/TD-20456

fix(query): [ASAN] fix time precision conversion overflow
...@@ -436,21 +436,24 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre ...@@ -436,21 +436,24 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre
ASSERT(toPrecision == TSDB_TIME_PRECISION_MILLI || toPrecision == TSDB_TIME_PRECISION_MICRO || ASSERT(toPrecision == TSDB_TIME_PRECISION_MILLI || toPrecision == TSDB_TIME_PRECISION_MICRO ||
toPrecision == TSDB_TIME_PRECISION_NANO); toPrecision == TSDB_TIME_PRECISION_NANO);
double tempResult = (double)utime;
switch (fromPrecision) { switch (fromPrecision) {
case TSDB_TIME_PRECISION_MILLI: { case TSDB_TIME_PRECISION_MILLI: {
switch (toPrecision) { switch (toPrecision) {
case TSDB_TIME_PRECISION_MILLI: case TSDB_TIME_PRECISION_MILLI:
return utime; return utime;
case TSDB_TIME_PRECISION_MICRO: case TSDB_TIME_PRECISION_MICRO:
tempResult *= 1000; if (utime > INT64_MAX / 1000) {
utime *= 1000; return INT64_MAX;
goto end_; }
return utime * 1000;
case TSDB_TIME_PRECISION_NANO: case TSDB_TIME_PRECISION_NANO:
tempResult *= 1000000; if (utime > INT64_MAX / 1000000) {
utime *= 1000000; return INT64_MAX;
goto end_; }
return utime * 1000000;
default:
ASSERT(0);
return utime;
} }
} // end from milli } // end from milli
case TSDB_TIME_PRECISION_MICRO: { case TSDB_TIME_PRECISION_MICRO: {
...@@ -460,9 +463,13 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre ...@@ -460,9 +463,13 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre
case TSDB_TIME_PRECISION_MICRO: case TSDB_TIME_PRECISION_MICRO:
return utime; return utime;
case TSDB_TIME_PRECISION_NANO: case TSDB_TIME_PRECISION_NANO:
tempResult *= 1000; if (utime > INT64_MAX / 1000) {
utime *= 1000; return INT64_MAX;
goto end_; }
return utime * 1000;
default:
ASSERT(0);
return utime;
} }
} // end from micro } // end from micro
case TSDB_TIME_PRECISION_NANO: { case TSDB_TIME_PRECISION_NANO: {
...@@ -473,17 +480,17 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre ...@@ -473,17 +480,17 @@ int64_t convertTimePrecision(int64_t utime, int32_t fromPrecision, int32_t toPre
return utime / 1000; return utime / 1000;
case TSDB_TIME_PRECISION_NANO: case TSDB_TIME_PRECISION_NANO:
return utime; return utime;
default:
ASSERT(0);
return utime;
} }
} // end from nano } // end from nano
default: { default: {
assert(0); ASSERT(0);
return utime; // only to pass windows compilation return utime; // only to pass windows compilation
} }
} // end switch fromPrecision } // end switch fromPrecision
end_:
if (tempResult >= (double)INT64_MAX) return INT64_MAX;
if (tempResult <= (double)INT64_MIN) return INT64_MIN; // INT64_MIN means NULL
return utime; return utime;
} }
...@@ -599,18 +606,33 @@ int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec ...@@ -599,18 +606,33 @@ int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec
static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision) { static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision) {
switch (unit) { switch (unit) {
case 's': case 's':
if (val > INT64_MAX / MILLISECOND_PER_SECOND) {
return -1;
}
(*result) = convertTimePrecision(val * MILLISECOND_PER_SECOND, TSDB_TIME_PRECISION_MILLI, timePrecision); (*result) = convertTimePrecision(val * MILLISECOND_PER_SECOND, TSDB_TIME_PRECISION_MILLI, timePrecision);
break; break;
case 'm': case 'm':
if (val > INT64_MAX / MILLISECOND_PER_MINUTE) {
return -1;
}
(*result) = convertTimePrecision(val * MILLISECOND_PER_MINUTE, TSDB_TIME_PRECISION_MILLI, timePrecision); (*result) = convertTimePrecision(val * MILLISECOND_PER_MINUTE, TSDB_TIME_PRECISION_MILLI, timePrecision);
break; break;
case 'h': case 'h':
if (val > INT64_MAX / MILLISECOND_PER_MINUTE) {
return -1;
}
(*result) = convertTimePrecision(val * MILLISECOND_PER_HOUR, TSDB_TIME_PRECISION_MILLI, timePrecision); (*result) = convertTimePrecision(val * MILLISECOND_PER_HOUR, TSDB_TIME_PRECISION_MILLI, timePrecision);
break; break;
case 'd': case 'd':
if (val > INT64_MAX / MILLISECOND_PER_DAY) {
return -1;
}
(*result) = convertTimePrecision(val * MILLISECOND_PER_DAY, TSDB_TIME_PRECISION_MILLI, timePrecision); (*result) = convertTimePrecision(val * MILLISECOND_PER_DAY, TSDB_TIME_PRECISION_MILLI, timePrecision);
break; break;
case 'w': case 'w':
if (val > INT64_MAX / MILLISECOND_PER_WEEK) {
return -1;
}
(*result) = convertTimePrecision(val * MILLISECOND_PER_WEEK, TSDB_TIME_PRECISION_MILLI, timePrecision); (*result) = convertTimePrecision(val * MILLISECOND_PER_WEEK, TSDB_TIME_PRECISION_MILLI, timePrecision);
break; break;
case 'a': case 'a':
...@@ -650,7 +672,7 @@ int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* dura ...@@ -650,7 +672,7 @@ int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* dura
/* get the basic numeric value */ /* get the basic numeric value */
int64_t timestamp = taosStr2Int64(token, &endPtr, 10); int64_t timestamp = taosStr2Int64(token, &endPtr, 10);
if (errno != 0) { if (timestamp < 0 || errno != 0) {
return -1; return -1;
} }
...@@ -668,7 +690,7 @@ int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* durati ...@@ -668,7 +690,7 @@ int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* durati
/* get the basic numeric value */ /* get the basic numeric value */
*duration = taosStr2Int64(token, NULL, 10); *duration = taosStr2Int64(token, NULL, 10);
if (errno != 0) { if (*duration < 0 || errno != 0) {
return -1; return -1;
} }
......
...@@ -917,6 +917,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -917,6 +917,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
int32_t startIndex; int32_t startIndex;
if (numOfParams != 4) { if (numOfParams != 4) {
snprintf(errMsg, msgLen, "%s", msg1); snprintf(errMsg, msgLen, "%s", msg1);
cJSON_Delete(binDesc);
return false; return false;
} }
...@@ -928,17 +929,20 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -928,17 +929,20 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
if (!cJSON_IsNumber(start) || !cJSON_IsNumber(count) || !cJSON_IsBool(infinity)) { if (!cJSON_IsNumber(start) || !cJSON_IsNumber(count) || !cJSON_IsBool(infinity)) {
snprintf(errMsg, msgLen, "%s", msg3); snprintf(errMsg, msgLen, "%s", msg3);
cJSON_Delete(binDesc);
return false; return false;
} }
if (count->valueint <= 0 || count->valueint > 1000) { // limit count to 1000 if (count->valueint <= 0 || count->valueint > 1000) { // limit count to 1000
snprintf(errMsg, msgLen, "%s", msg4); snprintf(errMsg, msgLen, "%s", msg4);
cJSON_Delete(binDesc);
return false; return false;
} }
if (isinf(start->valuedouble) || (width != NULL && isinf(width->valuedouble)) || if (isinf(start->valuedouble) || (width != NULL && isinf(width->valuedouble)) ||
(factor != NULL && isinf(factor->valuedouble)) || (count != NULL && isinf(count->valuedouble))) { (factor != NULL && isinf(factor->valuedouble)) || (count != NULL && isinf(count->valuedouble))) {
snprintf(errMsg, msgLen, "%s", msg5); snprintf(errMsg, msgLen, "%s", msg5);
cJSON_Delete(binDesc);
return false; return false;
} }
...@@ -957,6 +961,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -957,6 +961,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
if (width->valuedouble == 0) { if (width->valuedouble == 0) {
snprintf(errMsg, msgLen, "%s", msg6); snprintf(errMsg, msgLen, "%s", msg6);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
for (int i = 0; i < counter + 1; ++i) { for (int i = 0; i < counter + 1; ++i) {
...@@ -964,6 +969,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -964,6 +969,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
if (isinf(intervals[startIndex])) { if (isinf(intervals[startIndex])) {
snprintf(errMsg, msgLen, "%s", msg5); snprintf(errMsg, msgLen, "%s", msg5);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
startIndex++; startIndex++;
...@@ -973,11 +979,13 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -973,11 +979,13 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
if (start->valuedouble == 0) { if (start->valuedouble == 0) {
snprintf(errMsg, msgLen, "%s", msg7); snprintf(errMsg, msgLen, "%s", msg7);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
if (factor->valuedouble < 0 || factor->valuedouble == 0 || factor->valuedouble == 1) { if (factor->valuedouble < 0 || factor->valuedouble == 0 || factor->valuedouble == 1) {
snprintf(errMsg, msgLen, "%s", msg8); snprintf(errMsg, msgLen, "%s", msg8);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
for (int i = 0; i < counter + 1; ++i) { for (int i = 0; i < counter + 1; ++i) {
...@@ -985,6 +993,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -985,6 +993,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
if (isinf(intervals[startIndex])) { if (isinf(intervals[startIndex])) {
snprintf(errMsg, msgLen, "%s", msg5); snprintf(errMsg, msgLen, "%s", msg5);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
startIndex++; startIndex++;
...@@ -992,6 +1001,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -992,6 +1001,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
} else { } else {
snprintf(errMsg, msgLen, "%s", msg3); snprintf(errMsg, msgLen, "%s", msg3);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
...@@ -1007,6 +1017,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -1007,6 +1017,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
} else if (cJSON_IsArray(binDesc)) { /* user input bins */ } else if (cJSON_IsArray(binDesc)) { /* user input bins */
if (binType != USER_INPUT_BIN) { if (binType != USER_INPUT_BIN) {
snprintf(errMsg, msgLen, "%s", msg3); snprintf(errMsg, msgLen, "%s", msg3);
cJSON_Delete(binDesc);
return false; return false;
} }
numOfBins = cJSON_GetArraySize(binDesc); numOfBins = cJSON_GetArraySize(binDesc);
...@@ -1015,6 +1026,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -1015,6 +1026,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
if (bin == NULL) { if (bin == NULL) {
snprintf(errMsg, msgLen, "%s", msg3); snprintf(errMsg, msgLen, "%s", msg3);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
int i = 0; int i = 0;
...@@ -1023,11 +1035,13 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -1023,11 +1035,13 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
if (!cJSON_IsNumber(bin)) { if (!cJSON_IsNumber(bin)) {
snprintf(errMsg, msgLen, "%s", msg3); snprintf(errMsg, msgLen, "%s", msg3);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
if (i != 0 && intervals[i] <= intervals[i - 1]) { if (i != 0 && intervals[i] <= intervals[i - 1]) {
snprintf(errMsg, msgLen, "%s", msg3); snprintf(errMsg, msgLen, "%s", msg3);
taosMemoryFree(intervals); taosMemoryFree(intervals);
cJSON_Delete(binDesc);
return false; return false;
} }
bin = bin->next; bin = bin->next;
...@@ -1035,6 +1049,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err ...@@ -1035,6 +1049,7 @@ static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* err
} }
} else { } else {
snprintf(errMsg, msgLen, "%s", msg3); snprintf(errMsg, msgLen, "%s", msg3);
cJSON_Delete(binDesc);
return false; return false;
} }
...@@ -1465,10 +1480,15 @@ static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t ...@@ -1465,10 +1480,15 @@ static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t
// param1 // param1
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1); SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
SValueNode* pValue1 = (SValueNode*)pParamNode1;
if (QUERY_NODE_VALUE != nodeType(pParamNode1)) { if (QUERY_NODE_VALUE != nodeType(pParamNode1)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} }
if (pValue1->datum.i <= 0) {
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
}
SValueNode* pValue = (SValueNode*)pParamNode1; SValueNode* pValue = (SValueNode*)pParamNode1;
pValue->notReserved = true; pValue->notReserved = true;
......
...@@ -821,10 +821,10 @@ sql insert into tm0 values('2015-08-18T00:18:00Z', 2.126) ('2015-08-18T00:24:00Z ...@@ -821,10 +821,10 @@ sql insert into tm0 values('2015-08-18T00:18:00Z', 2.126) ('2015-08-18T00:24:00Z
sql_error select derivative(ts) from tm0; sql_error select derivative(ts) from tm0;
sql_error select derivative(k) from tm0; sql_error select derivative(k) from tm0;
sql select derivative(k, 0, 0) from tm0; sql_error select derivative(k, 0, 0) from tm0;
sql_error select derivative(k, 1, 911) from tm0; sql_error select derivative(k, 1, 911) from tm0;
sql_error select derivative(kx, 1s, 1) from tm0; sql_error select derivative(kx, 1s, 1) from tm0;
sql select derivative(k, -20s, 1) from tm0; sql_error select derivative(k, -20s, 1) from tm0;
sql select derivative(k, 20a, 0) from tm0; sql select derivative(k, 20a, 0) from tm0;
sql select derivative(k, 200a, 0) from tm0; sql select derivative(k, 200a, 0) from tm0;
sql select derivative(k, 999a, 0) from tm0; sql select derivative(k, 999a, 0) from tm0;
...@@ -932,10 +932,10 @@ sql insert into t0 values('2020-1-1 1:4:10', 10); ...@@ -932,10 +932,10 @@ sql insert into t0 values('2020-1-1 1:4:10', 10);
sql insert into t1 values('2020-1-1 1:1:2', 2); sql insert into t1 values('2020-1-1 1:1:2', 2);
print ===========================>td-4739 print ===========================>td-4739
#sql select diff(val) from (select derivative(k, 1s, 0) val from t1); sql select diff(val) from (select ts, derivative(k, 1s, 0) val from t1);
#if $rows != 0 then if $rows != 0 then
# return -1 return -1
#endi endi
sql insert into t1 values('2020-1-1 1:1:4', 20); sql insert into t1 values('2020-1-1 1:1:4', 20);
sql insert into t1 values('2020-1-1 1:1:6', 200); sql insert into t1 values('2020-1-1 1:1:6', 200);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册