[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);
|
||||
char * httpGetCmdsString(HttpContext *pContext, int32_t pos);
|
||||
|
||||
int32_t httpCheckAllocEscapeSql(char *oldSql, char **newSql);
|
||||
void httpCheckFreeEscapedSql(char *oldSql, char *newSql);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -176,6 +176,20 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
|||
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) {
|
||||
cJSON* query = cJSON_GetArrayItem(root, i);
|
||||
if (query == NULL) continue;
|
||||
|
@ -186,7 +200,14 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
|||
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) {
|
||||
httpWarn("context:%p, fd:%d, user:%s, refId buffer is full", pContext, pContext->fd, pContext->user);
|
||||
break;
|
||||
|
@ -195,7 +216,11 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
|||
cJSON* alias = cJSON_GetObjectItem(query, "alias");
|
||||
int32_t aliasBuffer = -1;
|
||||
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) {
|
||||
httpWarn("context:%p, fd:%d, user:%s, alias buffer is full", pContext, pContext->fd, pContext->user);
|
||||
break;
|
||||
|
@ -211,7 +236,11 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
|||
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) {
|
||||
httpWarn("context:%p, fd:%d, user:%s, sql buffer is full", pContext, pContext->fd, pContext->user);
|
||||
break;
|
||||
|
@ -237,6 +266,8 @@ bool gcProcessQueryRequest(HttpContext* pContext) {
|
|||
}
|
||||
}
|
||||
|
||||
#undef ESCAPE_ERROR_PROC
|
||||
|
||||
pContext->reqType = HTTP_REQTYPE_MULTI_SQL;
|
||||
pContext->encodeMethod = &gcQueryMethod;
|
||||
pContext->multiCmds->pos = 0;
|
||||
|
|
|
@ -423,3 +423,65 @@ void httpProcessRequest(HttpContext *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
|
||||
for (int32_t i = 0; i < orderTagsLen; ++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)
|
||||
stable_cmd->tagValues[i] = table_cmd->tagValues[i] = httpAddToSqlCmdBuffer(pContext, "'%s'", tag->valuestring);
|
||||
|
|
Loading…
Reference in New Issue