Changeset: 2f01d888e997 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2f01d888e997
Modified Files:
        monetdb5/modules/atoms/json.c
Branch: Jun2016
Log Message:

Properly check for errors.


diffs (truncated from 1173 to 300 lines):

diff --git a/monetdb5/modules/atoms/json.c b/monetdb5/modules/atoms/json.c
--- a/monetdb5/modules/atoms/json.c
+++ b/monetdb5/modules/atoms/json.c
@@ -69,7 +69,7 @@ JSONnewtree(int size)
        if (js == NULL)
                return NULL;
        js->elm = (JSONterm *) GDKzalloc(sizeof(JSONterm) * size);
-       if( js->elm == NULL){
+       if (js->elm == NULL) {
                GDKfree(js);
                return NULL;
        }
@@ -89,7 +89,7 @@ JSONnew(JSON *js)
                        return js->free - 1;
                }
                js->elm = term;
-               memset(((char *) term) + sizeof(JSONterm) * js->size, 0, 8 * 
sizeof(JSONterm));
+               memset(term + js->size, 0, 8 * sizeof(JSONterm));
                js->size += 8;
                if (jsonhint < js->size)
                        jsonhint = js->size;
@@ -124,9 +124,10 @@ JSONfromString(str src, int *len, json *
        }
        JSONfree(jt);
 
+       *len = (int) slen;
        *j = GDKstrdup(src);
-       *len = (int) slen;
-       if (GDKstrFromStr((unsigned char *) *j, (const unsigned char *) src, 
slen) < 0) {
+       if (*j == NULL ||
+               GDKstrFromStr((unsigned char *) *j, (const unsigned char *) 
src, slen) < 0) {
                GDKfree(*j);
                *j = GDKstrdup(str_nil);
                *len = 2;
@@ -168,7 +169,7 @@ JSONtoString(str *s, int *len, json src)
 
        if (cnt > (size_t) *len) {
                GDKfree(*s);
-               *s = (str) GDKmalloc(cnt);
+               *s = GDKmalloc(cnt);
                if (*s == NULL)
                        return -1;
                *len = (int) cnt;
@@ -196,7 +197,12 @@ JSONtoString(str *s, int *len, json src)
        return (int) (cnt - 1); /* length without \0 */
 }
 
-#define tab(D) { int kk; for(kk=0; kk< D * 4; kk++) mnstr_printf(fd," ");}
+#define tab(D)                                                                 
\
+       do {                                                                    
        \
+               int kk;                                                         
        \
+               for (kk = 0; kk < (D) * 4; kk++)                \
+                       mnstr_printf(fd, " ");                          \
+       } while (0)
 
 static void
 JSONdumpInternal(JSON *jt, int depth)
@@ -339,6 +345,8 @@ JSONappend(JSON *jt, int idx, int nxt)
 
        if (jt->elm[nxt].kind == JSON_OBJECT || jt->elm[nxt].kind == 
JSON_ARRAY) {
                chld = JSONnew(jt);
+               if (jt->error)
+                       return;
                jt->elm[chld].kind = jt->elm[nxt].kind;
                jt->elm[chld].name = jt->elm[nxt].name;
                jt->elm[chld].namelen = jt->elm[nxt].namelen;
@@ -497,8 +505,11 @@ JSONglue(str res, str r, char sep)
                return r;
        l = strlen(res);
        n = GDKzalloc(l + len + 3);
-       if( n == NULL)
-               throw(MAL, "json.glue.", MAL_MALLOC_FAIL);
+       if( n == NULL) {
+               GDKfree(res);
+               GDKfree(r);
+               return NULL;
+       }
        strcpy(n, res);
        GDKfree(res);
        if (sep) {
@@ -513,24 +524,32 @@ JSONglue(str res, str r, char sep)
        return n;
 }
 
+/* return NULL on no match, return (str) -1 on (malloc) failure */
 static str
 JSONmatch(JSON *jt, int ji, pattern * terms, int ti)
 {
        str r = NULL, res = NULL;
-       int i, match;
+       int i;
        int cnt;
 
        if (terms[ti].token == ROOT_STEP) {
-               if (terms[ti + 1].token == END_STEP)
-                       return JSONgetValue(jt, 0);
+               if (terms[ti + 1].token == END_STEP) {
+                       res = JSONgetValue(jt, 0);
+                       if (res == NULL)
+                               res = (str) -1;
+                       return res;
+               }
                ti++;
        }
 
        switch (jt->elm[ji].kind) {
        case JSON_ARRAY:
                if (terms[ti].name != 0 && terms[ti].token != ANY_STEP) {
-                       if (terms[ti].token == END_STEP)
+                       if (terms[ti].token == END_STEP) {
                                res = JSONgetValue(jt, ji);
+                               if (res == NULL)
+                                       res = (str) -1;
+                       }
                        return res;
                }
                cnt = 0;
@@ -546,8 +565,14 @@ JSONmatch(JSON *jt, int ji, pattern * te
                                                r = JSONgetValue(jt, 
jt->elm[i].child);
                                        else
                                                r = JSONgetValue(jt, i);
+                                       if (r == NULL)
+                                               r = (str) -1;
                                } else
                                        r = JSONmatch(jt, jt->elm[i].child, 
terms, ti + 1);
+                               if (r == (str) -1) {
+                                       GDKfree(res);
+                                       return r;
+                               }
                                res = JSONglue(res, r, ',');
                        }
                }
@@ -556,18 +581,32 @@ JSONmatch(JSON *jt, int ji, pattern * te
                cnt = 0;
                for (i = jt->elm[ji].next; i && cnt >= 0; i = jt->elm[i].next) {
                        // check the element label
-                       match = (terms[ti].name && jt->elm[i].valuelen == 
terms[ti].namelen && strncmp(terms[ti].name, jt->elm[i].value, 
terms[ti].namelen) == 0) ||terms[ti].name == 0 || terms[ti].name[0] == '*';
-                       if (match) {
-                               if (terms[ti].index == INT_MAX || (cnt >= 
terms[ti].first && cnt <= terms[ti].last)) {
-                                       if (terms[ti + 1].token == END_STEP)
+                       if ((terms[ti].name &&
+                                jt->elm[i].valuelen == terms[ti].namelen &&
+                                strncmp(terms[ti].name, jt->elm[i].value, 
terms[ti].namelen) == 0) ||
+                               terms[ti].name == 0 ||
+                               terms[ti].name[0] == '*') {
+                               if (terms[ti].index == INT_MAX ||
+                                       (cnt >= terms[ti].first && cnt <= 
terms[ti].last)) {
+                                       if (terms[ti + 1].token == END_STEP) {
                                                r = JSONgetValue(jt, 
jt->elm[i].child);
-                                       else
+                                               if (r == NULL)
+                                                       r = (str) -1;
+                                       } else
                                                r = JSONmatch(jt, 
jt->elm[i].child, terms, ti + 1);
+                                       if (r == (str) -1) {
+                                               GDKfree(res);
+                                               return r;
+                                       }
                                        res = JSONglue(res, r, ',');
                                }
                                cnt++;
                        } else if (terms[ti].token == ANY_STEP && 
jt->elm[i].child) {
                                r = JSONmatch(jt, jt->elm[i].child, terms, ti);
+                               if (r == (str) -1) {
+                                       GDKfree(res);
+                                       return r;
+                               }
                                res = JSONglue(res, r, ',');
                                cnt++;
                        }
@@ -589,6 +628,8 @@ JSONfilterInternal(json *ret, json *js, 
        (void) other;
        if (strNil(j)) {
                *ret = GDKstrdup(j);
+               if (*ret == NULL)
+                       throw(MAL,"JSONfilterInternal",MAL_MALLOC_FAIL);
                return MAL_SUCCEED;
        }
        jt = JSONparse(j, FALSE);
@@ -599,10 +640,18 @@ JSONfilterInternal(json *ret, json *js, 
                goto bailout;
 
        result = s = JSONmatch(jt, 0, terms, tidx);
+       if (s == (char *) -1) {
+               msg = createException(MAL,"JSONfilterInternal",MAL_MALLOC_FAIL);
+               goto bailout;
+       }
        // process all other PATH expression
        for (tidx++; tidx < MAXTERMS && terms[tidx].token; tidx++)
                if (terms[tidx].token == END_STEP && tidx + 1 < MAXTERMS && 
terms[tidx + 1].token) {
                        s = JSONmatch(jt, 0, terms, ++tidx);
+                       if (s == (char *) -1) {
+                               msg = 
createException(MAL,"JSONfilterInternal",MAL_MALLOC_FAIL);
+                               goto bailout;
+                       }
                        result = JSONglue(result, s, ',');
                }
        if (result) {
@@ -612,8 +661,10 @@ JSONfilterInternal(json *ret, json *js, 
        } else
                l = 3;
        s = GDKzalloc(l + 3);
-       if( s == NULL)
+       if (s == NULL) {
+               GDKfree(result);
                throw(MAL,"JSONfilterInternal",MAL_MALLOC_FAIL);
+       }
        snprintf(s, l + 3, "[%s]", (result ? result : ""));
        GDKfree(result);
        *ret = s;
@@ -725,6 +776,8 @@ JSONtoken(JSON *jt, char *j, char **next
        int nxt, idx = JSONnew(jt);
 
        assert(silent==0);
+       if (jt->error)
+               return idx;
        skipblancs(j);
        switch (*j) {
        case '{':
@@ -736,7 +789,7 @@ JSONtoken(JSON *jt, char *j, char **next
                        if (*j == '}')
                                break;
                        nxt = JSONtoken(jt, j, next, silent);
-                       if (jt->error) 
+                       if (jt->error)
                                return idx;
                        if (jt->elm[nxt].kind != JSON_ELEMENT) {
                                if (!silent)
@@ -744,6 +797,8 @@ JSONtoken(JSON *jt, char *j, char **next
                                return idx;
                        }
                        JSONappend(jt, idx, nxt);
+                       if (jt->error)
+                               return idx;
                        j = *next;
                        skipblancs(j);
                        if (*j == '}')
@@ -773,11 +828,13 @@ JSONtoken(JSON *jt, char *j, char **next
                        if (*j == ']')
                                break;
                        nxt = JSONtoken(jt, j, next, silent);
-                       if (jt->error) 
+                       if (jt->error)
                                return idx;
                        switch (jt->elm[nxt].kind) {
                        case JSON_ELEMENT:{
                                int k = JSONnew(jt);
+                               if (jt->error)
+                                       return idx;
                                jt->elm[k].kind = JSON_OBJECT;
                                jt->elm[k].child = nxt;
                                nxt = k;
@@ -787,13 +844,19 @@ JSONtoken(JSON *jt, char *j, char **next
                        case JSON_ARRAY:
                                if (jt->elm[nxt].kind == JSON_OBJECT || 
jt->elm[nxt].kind == JSON_ARRAY) {
                                        int k = JSONnew(jt);
+                                       if (jt->error)
+                                               return idx;
                                        JSONappend(jt, idx, k);
+                                       if (jt->error)
+                                               return idx;
                                        jt->elm[k].kind = JSON_VALUE;
                                        jt->elm[k].child = nxt;
                                }
                                break;
                        default:
                                JSONappend(jt, idx, nxt);
+                               if (jt->error)
+                                       return idx;
                        }
                        j = *next;
                        skipblancs(j);
@@ -826,6 +889,8 @@ JSONtoken(JSON *jt, char *j, char **next
                        jt->error = msg;
                        return idx;
                }
+               if (msg != MAL_SUCCEED && msg != M5OutOfMemory)
+                       GDKfree(msg);
                jt->elm[idx].kind = JSON_STRING;
                jt->elm[idx].value = j;
                jt->elm[idx].valuelen = *next - j;
@@ -836,7 +901,7 @@ JSONtoken(JSON *jt, char *j, char **next
                        skipblancs(j);
                        jt->elm[idx].kind = JSON_ELEMENT;
                        nxt = JSONtoken(jt, j, next, silent);
-                       if (jt->error) 
+                       if (jt->error)
                                return idx;
                        jt->elm[idx].child = nxt;
                        jt->elm[idx].value++;
@@ -882,6 +947,8 @@ JSONtoken(JSON *jt, char *j, char **next
                        msg = JSONnumberParser(j, next, silent);
                        if (!silent && msg)
                                jt->error = msg;
+                       else if (msg != MAL_SUCCEED && msg != M5OutOfMemory)
+                               GDKfree(msg);
                        jt->elm[idx].kind = JSON_NUMBER;
                        jt->elm[idx].valuelen = *next - jt->elm[idx].value;
                        return idx;
@@ -1075,8 +1142,10 @@ JSONjson2text(str *ret, json *js)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to