libidav/davqlparser.c

changeset 122
9a016d5fa9e7
parent 121
eea36bf5ffe2
child 125
5e2576b08680
--- 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 {

mercurial