[TD-5169]<fix>: fixed a potential crash bug
This commit is contained in:
parent
6dc159f852
commit
e174669808
|
@ -35,4 +35,7 @@ void httpTrimTableName(char *name);
|
||||||
int32_t httpShrinkTableName(HttpContext *pContext, int32_t pos, char *name);
|
int32_t httpShrinkTableName(HttpContext *pContext, int32_t pos, char *name);
|
||||||
char * httpGetCmdsString(HttpContext *pContext, int32_t pos);
|
char * httpGetCmdsString(HttpContext *pContext, int32_t pos);
|
||||||
|
|
||||||
|
int32_t httpCheckAllocEscapeSql(char *oldSql, char **newSql);
|
||||||
|
void httpCheckFreeEscapedSql(char *oldSql, char *newSql);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -176,6 +176,20 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ESCAPE_ERROR_PROC(code, context, root) \
|
||||||
|
do { \
|
||||||
|
if (code != 0) { \
|
||||||
|
if (code == 1) { \
|
||||||
|
httpSendErrorResp(context, TSDB_CODE_HTTP_GC_REQ_PARSE_ERROR); \
|
||||||
|
} else { \
|
||||||
|
httpSendErrorResp(context, TSDB_CODE_HTTP_NO_ENOUGH_MEMORY); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
cJSON_Delete(root); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
cJSON* query = cJSON_GetArrayItem(root, i);
|
cJSON* query = cJSON_GetArrayItem(root, i);
|
||||||
if (query == NULL) continue;
|
if (query == NULL) continue;
|
||||||
|
@ -186,7 +200,14 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t refIdBuffer = httpAddToSqlCmdBuffer(pContext, refId->valuestring);
|
char *newStr = NULL;
|
||||||
|
int32_t retCode = 0;
|
||||||
|
|
||||||
|
retCode = httpCheckAllocEscapeSql(refId->valuestring, &newStr);
|
||||||
|
ESCAPE_ERROR_PROC(retCode, pContext, root);
|
||||||
|
|
||||||
|
int32_t refIdBuffer = httpAddToSqlCmdBuffer(pContext, newStr);
|
||||||
|
httpCheckFreeEscapedSql(refId->valuestring, newStr);
|
||||||
if (refIdBuffer == -1) {
|
if (refIdBuffer == -1) {
|
||||||
httpWarn("context:%p, fd:%d, user:%s, refId buffer is full", pContext, pContext->fd, pContext->user);
|
httpWarn("context:%p, fd:%d, user:%s, refId buffer is full", pContext, pContext->fd, pContext->user);
|
||||||
break;
|
break;
|
||||||
|
@ -195,7 +216,11 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
||||||
cJSON* alias = cJSON_GetObjectItem(query, "alias");
|
cJSON* alias = cJSON_GetObjectItem(query, "alias");
|
||||||
int32_t aliasBuffer = -1;
|
int32_t aliasBuffer = -1;
|
||||||
if (!(alias == NULL || alias->valuestring == NULL || strlen(alias->valuestring) == 0)) {
|
if (!(alias == NULL || alias->valuestring == NULL || strlen(alias->valuestring) == 0)) {
|
||||||
aliasBuffer = httpAddToSqlCmdBuffer(pContext, alias->valuestring);
|
retCode = httpCheckAllocEscapeSql(alias->valuestring, &newStr);
|
||||||
|
ESCAPE_ERROR_PROC(retCode, pContext, root);
|
||||||
|
|
||||||
|
aliasBuffer = httpAddToSqlCmdBuffer(pContext, newStr);
|
||||||
|
httpCheckFreeEscapedSql(alias->valuestring, newStr);
|
||||||
if (aliasBuffer == -1) {
|
if (aliasBuffer == -1) {
|
||||||
httpWarn("context:%p, fd:%d, user:%s, alias buffer is full", pContext, pContext->fd, pContext->user);
|
httpWarn("context:%p, fd:%d, user:%s, alias buffer is full", pContext, pContext->fd, pContext->user);
|
||||||
break;
|
break;
|
||||||
|
@ -211,7 +236,11 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sqlBuffer = httpAddToSqlCmdBuffer(pContext, sql->valuestring);
|
retCode = httpCheckAllocEscapeSql(sql->valuestring, &newStr);
|
||||||
|
ESCAPE_ERROR_PROC(retCode, pContext, root);
|
||||||
|
|
||||||
|
int32_t sqlBuffer = httpAddToSqlCmdBuffer(pContext, newStr);
|
||||||
|
httpCheckFreeEscapedSql(sql->valuestring, newStr);
|
||||||
if (sqlBuffer == -1) {
|
if (sqlBuffer == -1) {
|
||||||
httpWarn("context:%p, fd:%d, user:%s, sql buffer is full", pContext, pContext->fd, pContext->user);
|
httpWarn("context:%p, fd:%d, user:%s, sql buffer is full", pContext, pContext->fd, pContext->user);
|
||||||
break;
|
break;
|
||||||
|
@ -237,6 +266,8 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef ESCAPE_ERROR_PROC
|
||||||
|
|
||||||
pContext->reqType = HTTP_REQTYPE_MULTI_SQL;
|
pContext->reqType = HTTP_REQTYPE_MULTI_SQL;
|
||||||
pContext->encodeMethod = &gcQueryMethod;
|
pContext->encodeMethod = &gcQueryMethod;
|
||||||
pContext->multiCmds->pos = 0;
|
pContext->multiCmds->pos = 0;
|
||||||
|
|
|
@ -423,3 +423,65 @@ void httpProcessRequest(HttpContext *pContext) {
|
||||||
httpExecCmd(pContext);
|
httpExecCmd(pContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t httpCheckAllocEscapeSql(char *oldSql, char **newSql)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
if (oldSql == NULL || newSql == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bad sql clause */
|
||||||
|
pos = strstr(oldSql, "%%");
|
||||||
|
if (pos) {
|
||||||
|
httpError("bad sql:%s", oldSql);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = strchr(oldSql, '%');
|
||||||
|
if (pos == NULL) {
|
||||||
|
httpDebug("sql:%s", oldSql);
|
||||||
|
*newSql = oldSql;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*newSql = (char *) calloc(1, (strlen(oldSql) << 1) + 1);
|
||||||
|
if (newSql == NULL) {
|
||||||
|
httpError("failed to allocate for new sql, old sql:%s", oldSql);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *src = oldSql;
|
||||||
|
char *dst = *newSql;
|
||||||
|
size_t sqlLen = strlen(src);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
memcpy(dst, src, pos - src + 1);
|
||||||
|
dst += pos - src + 1;
|
||||||
|
*dst++ = '%';
|
||||||
|
|
||||||
|
if (pos + 1 >= oldSql + sqlLen) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = ++pos;
|
||||||
|
pos = strchr(pos, '%');
|
||||||
|
if (pos == NULL) {
|
||||||
|
memcpy(dst, src, sqlLen - strlen(src));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpCheckFreeEscapedSql(char *oldSql, char *newSql)
|
||||||
|
{
|
||||||
|
if (oldSql && newSql) {
|
||||||
|
if (oldSql != newSql) {
|
||||||
|
free(newSql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -610,7 +610,22 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) {
|
||||||
// stable tag for detail
|
// stable tag for detail
|
||||||
for (int32_t i = 0; i < orderTagsLen; ++i) {
|
for (int32_t i = 0; i < orderTagsLen; ++i) {
|
||||||
cJSON *tag = orderedTags[i];
|
cJSON *tag = orderedTags[i];
|
||||||
stable_cmd->tagNames[i] = table_cmd->tagNames[i] = httpAddToSqlCmdBuffer(pContext, tag->string);
|
|
||||||
|
char *tagStr = NULL;
|
||||||
|
int32_t retCode = httpCheckAllocEscapeSql(tag->string, &tagStr);
|
||||||
|
if (retCode != 0) {
|
||||||
|
if (retCode == 1) {
|
||||||
|
httpSendErrorResp(pContext, TSDB_CODE_HTTP_TG_INVALID_JSON);
|
||||||
|
} else {
|
||||||
|
httpSendErrorResp(pContext, TSDB_CODE_HTTP_NO_ENOUGH_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
stable_cmd->tagNames[i] = table_cmd->tagNames[i] = httpAddToSqlCmdBuffer(pContext, tagStr);
|
||||||
|
|
||||||
|
httpCheckFreeEscapedSql(tag->string, tagStr);
|
||||||
|
|
||||||
if (tag->type == cJSON_String)
|
if (tag->type == cJSON_String)
|
||||||
stable_cmd->tagValues[i] = table_cmd->tagValues[i] = httpAddToSqlCmdBuffer(pContext, "'%s'", tag->valuestring);
|
stable_cmd->tagValues[i] = table_cmd->tagValues[i] = httpAddToSqlCmdBuffer(pContext, "'%s'", tag->valuestring);
|
||||||
|
|
Loading…
Reference in New Issue