# HG changeset patch # User Mike Becker # Date 1432897945 -7200 # Node ID 9a016d5fa9e77e7d8cc3131147ce70ea9adc52e7 # Parent eea36bf5ffe201e7fcf2adb79b70d8952ba19fed secured malloc / calloc calls diff -r eea36bf5ffe2 -r 9a016d5fa9e7 libidav/davqlparser.c --- a/libidav/davqlparser.c Fri May 29 12:29:01 2015 +0200 +++ b/libidav/davqlparser.c Fri May 29 13:12:25 2015 +0200 @@ -419,6 +419,17 @@ ln, pn).ptr; } +#define dqlsec_alloc_failed(ptr, stmt) \ + if (!(ptr)) { \ + (stmt)->errorcode = DAVQL_ERROR_OUT_OF_MEMORY; \ + return 0; \ + } +#define dqlsec_malloc(stmt, ptr, type) ptr = malloc(sizeof(type)); \ + dqlsec_alloc_failed(ptr, stmt); +#define dqlsec_mallocz(stmt, ptr, type) ptr = calloc(1, sizeof(type)); \ + dqlsec_alloc_failed(ptr, stmt); + + // special symbols are single tokens - the % sign MUST NOT be a special symbol static const char *special_token_symbols = ",()+-*/&|^~=!<>"; @@ -494,6 +505,8 @@ } static UcxList* dav_parse_tokenize(sstr_t src) { +#define alloc_token token = malloc(sizeof(DavQLToken));\ + if(!token) {ucx_list_free(tokens); return NULL;} UcxList *tokens = NULL; DavQLToken *token = NULL; @@ -513,7 +526,7 @@ if (token) { tokens = dav_parse_add_token(tokens, token); } - token = malloc(sizeof(DavQLToken)); + alloc_token token->value.ptr = src.ptr + i; token->value.length = 1; } else { @@ -535,7 +548,7 @@ token = NULL; } // add special symbol as single token to list - token = malloc(sizeof(DavQLToken)); + alloc_token token->value.ptr = src.ptr + i; token->value.length = 1; tokens = dav_parse_add_token(tokens, token); @@ -544,7 +557,7 @@ } else { // if this is a new token, create memory for it if (!token) { - token = malloc(sizeof(DavQLToken)); + alloc_token token->value.ptr = src.ptr + i; token->value.length = 0; } @@ -557,10 +570,11 @@ tokens = dav_parse_add_token(tokens, token); } - DavQLToken *endtoken = malloc(sizeof(DavQLToken)); - endtoken->tokenclass = DAVQL_TOKEN_END; - endtoken->value = S(""); - return ucx_list_append(tokens, endtoken); + alloc_token + token->tokenclass = DAVQL_TOKEN_END; + token->value = S(""); + return ucx_list_append(tokens, token); +#undef alloc_token } static void dav_free_expression(DavQLExpression *expr) { @@ -640,9 +654,9 @@ if (expr->op == DAVQL_NOOP) { memcpy(expr, &left, sizeof(DavQLExpression)); } else { - expr->left = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->left, DavQLExpression); memcpy(expr->left, &left, sizeof(DavQLExpression)); - expr->right = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->right, DavQLExpression); memcpy(expr->right, &right, sizeof(DavQLExpression)); expr->srctext.ptr = expr->left->srctext.ptr; @@ -714,12 +728,12 @@ /* we have more arguments, so put the current argument to the * left subtree and create a new node to the right */ - arglist->left = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, arglist->left, DavQLExpression); memcpy(arglist->left, &arg, sizeof(DavQLExpression)); arglist->srctext.ptr = arg.srctext.ptr; arglist->op = DAVQL_ARGLIST; arglist->type = DAVQL_FUNCCALL; - arglist->right = calloc(1, sizeof(DavQLExpression)); + dqlsec_mallocz(stmt, arglist->right, DavQLExpression); arglist = arglist->right; } else { // this was the last argument, so write it to the current node @@ -749,7 +763,7 @@ expr->type = DAVQL_FUNCCALL; expr->op = DAVQL_CALL; - expr->left = calloc(1, sizeof(DavQLExpression)); + dqlsec_mallocz(stmt, expr->left, DavQLExpression); expr->left->type = DAVQL_IDENTIFIER; expr->left->srctext = token_sstr(token); expr->right = NULL; @@ -764,7 +778,7 @@ } if (argtokens) { token = ucx_list_get(token, argtokens); - expr->right = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->right, DavQLExpression); memcpy(expr->right, &arg, sizeof(DavQLExpression)); } else { // arg list may be empty @@ -801,7 +815,7 @@ case '-': expr->op = DAVQL_SUB; break; case '~': expr->op = DAVQL_NEG; break; } - expr->left = calloc(1, sizeof(DavQLExpression)); + dqlsec_mallocz(stmt, expr->left, DavQLExpression); atom = expr->left; total_consumed++; token = token->next; @@ -898,7 +912,8 @@ int total_consumed = 0, consumed; // RULE: Expression, " as ", Identifier; - DavQLExpression *expr = calloc(1, sizeof(DavQLExpression)); + DavQLExpression *expr; + dqlsec_mallocz(stmt, expr, DavQLExpression); consumed = dav_parse_expression(stmt, token, expr); if (stmt->errorcode) { dav_free_expression(expr); @@ -939,8 +954,9 @@ // RULE: "-" if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "-")) { - DavQLField *field = malloc(sizeof(DavQLField)); - field->expr = calloc(1, sizeof(DavQLExpression)); + DavQLField *field; + dqlsec_malloc(stmt, field, DavQLField); + dqlsec_mallocz(stmt, field->expr, DavQLExpression); field->expr->type = DAVQL_IDENTIFIER; field->expr->srctext = field->name = token_sstr(token); stmt->fields = ucx_list_append(stmt->fields, field); @@ -949,8 +965,9 @@ // RULE: "*", {",", NamedExpression} if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "*")) { - DavQLField *field = malloc(sizeof(DavQLField)); - field->expr = calloc(1, sizeof(DavQLExpression)); + DavQLField *field; + dqlsec_malloc(stmt, field, DavQLField); + dqlsec_mallocz(stmt, field->expr, DavQLExpression); field->expr->type = DAVQL_IDENTIFIER; field->expr->srctext = field->name = token_sstr(token); stmt->fields = ucx_list_append(stmt->fields, field); @@ -967,7 +984,8 @@ DavQLField localfield; consumed = dav_parse_named_field(stmt, token, &localfield); if (!stmt->errorcode && consumed) { - DavQLField *field = malloc(sizeof(DavQLField)); + DavQLField *field; + dqlsec_malloc(stmt, field, DavQLField); memcpy(field, &localfield, sizeof(DavQLField)); stmt->fields = ucx_list_append(stmt->fields, field); } @@ -987,7 +1005,8 @@ DavQLField localfield; consumed = dav_parse_named_field(stmt, token, &localfield); if (consumed) { - DavQLField *field = malloc(sizeof(DavQLField)); + DavQLField *field; + dqlsec_malloc(stmt, field, DavQLField); memcpy(field, &localfield, sizeof(DavQLField)); stmt->fields = ucx_list_append(stmt->fields, field); token = ucx_list_get(token, consumed); @@ -997,8 +1016,9 @@ && (token_is(token->next, DAVQL_TOKEN_COMMA) || tokenvalue_is(token->next, "from"))) { - DavQLField *field = malloc(sizeof(DavQLField)); - field->expr = calloc(1, sizeof(DavQLExpression)); + DavQLField *field; + dqlsec_malloc(stmt, field, DavQLField); + dqlsec_mallocz(stmt, field->expr, DavQLExpression); field->expr->type = DAVQL_IDENTIFIER; field->expr->srctext = field->name = token_sstr(token); stmt->fields = ucx_list_append(stmt->fields, field); @@ -1061,9 +1081,9 @@ if (token_is(token, DAVQL_TOKEN_STRING)) { expr->op = tokenvalue_is(optok, "like") ? DAVQL_LIKE : DAVQL_UNLIKE; - expr->left = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->left, DavQLExpression); memcpy(expr->left, &bexpr, sizeof(DavQLExpression)); - expr->right = calloc(1, sizeof(DavQLExpression)); + dqlsec_mallocz(stmt, expr->right, DavQLExpression); expr->right->type = DAVQL_STRING; expr->right->srctext = token_sstr(token); @@ -1118,9 +1138,9 @@ } total_consumed += consumed; - expr->left = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->left, DavQLExpression); memcpy(expr->left, &bexpr, sizeof(DavQLExpression)); - expr->right = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->right, DavQLExpression); memcpy(expr->right, &rexpr, sizeof(DavQLExpression)); return total_consumed; @@ -1142,7 +1162,7 @@ if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "not")) { expr->type = DAVQL_LOGICAL; expr->op = DAVQL_NOT; - expr->left = calloc(1, sizeof(DavQLExpression)); + dqlsec_mallocz(stmt, expr->left, DavQLExpression); expr->srctext = token_sstr(token); token = token->next; @@ -1243,9 +1263,9 @@ total_consumed += consumed; token = ucx_list_get(token, consumed); - expr->left = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->left, DavQLExpression); memcpy(expr->left, &left, sizeof(DavQLExpression)); - expr->right = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, expr->right, DavQLExpression); memcpy(expr->right, &right, sizeof(DavQLExpression)); } } else { @@ -1263,7 +1283,7 @@ } static int dav_parse_where_clause(DavQLStatement *stmt, UcxList *token) { - stmt->where = calloc(1, sizeof(DavQLExpression)); + dqlsec_mallocz(stmt, stmt->where, DavQLExpression); return dav_parse_logical_expr(stmt, token, stmt->where); } @@ -1281,7 +1301,8 @@ stmt->depth = DAV_DEPTH_INFINITY; token = token->next; total_consumed++; } else { - DavQLExpression *depthexpr = calloc(1, sizeof(DavQLExpression)); + DavQLExpression *depthexpr; + dqlsec_mallocz(stmt, depthexpr, DavQLExpression); int consumed = dav_parse_expression(stmt, token, depthexpr); @@ -1292,6 +1313,11 @@ } else { sstr_t depthstr = depthexpr->srctext; char *conv = malloc(depthstr.length+1); + if (!conv) { + dav_free_expression(depthexpr); + stmt->errorcode = DAVQL_ERROR_OUT_OF_MEMORY; + return 0; + } char *chk; memcpy(conv, depthstr.ptr, depthstr.length); conv[depthstr.length] = '\0'; @@ -1334,7 +1360,7 @@ return 0; } - crit->column = malloc(sizeof(DavQLExpression)); + dqlsec_malloc(stmt, crit->column, DavQLExpression); memcpy(crit->column, &expr, sizeof(DavQLExpression)); token = ucx_list_get(token, consumed); @@ -1370,7 +1396,8 @@ token = ucx_list_get(token, consumed); total_consumed += consumed; - DavQLOrderCriterion *criterion = malloc(sizeof(DavQLOrderCriterion)); + DavQLOrderCriterion *criterion; + dqlsec_malloc(stmt, criterion, DavQLOrderCriterion); memcpy(criterion, &crit, sizeof(DavQLOrderCriterion)); stmt->orderby = ucx_list_append(stmt->orderby, criterion); @@ -1540,7 +1567,7 @@ stmt->errormessage = strdup(_error_invalid); } - if (stmt->errorcode = DAVQL_ERROR_OUT_OF_MEMORY) { + if (stmt->errorcode == DAVQL_ERROR_OUT_OF_MEMORY) { stmt->type = DAVQL_ERROR; stmt->errormessage = oommsg; } else {