]> granicus.if.org Git - postgresql/commitdiff
Clean up callers of JsonbIteratorNext().
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Apr 2018 16:40:01 +0000 (12:40 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Apr 2018 16:40:01 +0000 (12:40 -0400)
Coverity complained about the lack of a check on the return value in
parse_jsonb_index_flags' last call of JsonbIteratorNext.  Seems like
a reasonable gripe to me, especially since the code is depending on
that being WJB_DONE to not leak memory, so add a check.

In passing, improve a couple other places where the result was being
ignored, either by adding an assert or at least a cast to void.

Also, don't spell "WJB_DONE" as "0".  That's horrid coding style,
and it wasn't consistent either.

src/backend/utils/adt/jsonfuncs.c

index 2f12d0325abe97f1d0acc8fbf8b953aa7ed30cee..202779dfffb446bc94a02657394e57f7108bf9e0 100644 (file)
@@ -1745,6 +1745,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
                         * matter what shape it is.
                         */
                        r = JsonbIteratorNext(&it, &v, skipNested);
+                       Assert(r != WJB_DONE);
 
                        values[0] = PointerGetDatum(key);
 
@@ -4111,6 +4112,7 @@ addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb)
        if (JB_ROOT_IS_SCALAR(jb))
        {
                (void) JsonbIteratorNext(&it, &v, false);       /* skip array header */
+               Assert(v.type == jbvArray);
                (void) JsonbIteratorNext(&it, &v, false);       /* fetch scalar value */
 
                switch (o->type)
@@ -4224,7 +4226,7 @@ jsonb_delete(PG_FUNCTION_ARGS)
 
        it = JsonbIteratorInit(&in->root);
 
-       while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
+       while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE)
        {
                skipNested = true;
 
@@ -4234,7 +4236,7 @@ jsonb_delete(PG_FUNCTION_ARGS)
                {
                        /* skip corresponding value as well */
                        if (r == WJB_KEY)
-                               JsonbIteratorNext(&it, &v, true);
+                               (void) JsonbIteratorNext(&it, &v, true);
 
                        continue;
                }
@@ -4289,7 +4291,7 @@ jsonb_delete_array(PG_FUNCTION_ARGS)
 
        it = JsonbIteratorInit(&in->root);
 
-       while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0)
+       while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE)
        {
                skipNested = true;
 
@@ -4319,7 +4321,7 @@ jsonb_delete_array(PG_FUNCTION_ARGS)
                        {
                                /* skip corresponding value as well */
                                if (r == WJB_KEY)
-                                       JsonbIteratorNext(&it, &v, true);
+                                       (void) JsonbIteratorNext(&it, &v, true);
 
                                continue;
                        }
@@ -4385,7 +4387,7 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
 
        pushJsonbValue(&state, r, NULL);
 
-       while ((r = JsonbIteratorNext(&it, &v, true)) != 0)
+       while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
        {
                if (r == WJB_ELEM)
                {
@@ -4576,7 +4578,7 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
                 * Append the all tokens from v2 to res, include last WJB_END_OBJECT
                 * (the concatenation will be completed).
                 */
-               while ((r2 = JsonbIteratorNext(it2, &v2, true)) != 0)
+               while ((r2 = JsonbIteratorNext(it2, &v2, true)) != WJB_DONE)
                        res = pushJsonbValue(state, r2, r2 != WJB_END_OBJECT ? &v2 : NULL);
        }
 
@@ -4616,10 +4618,10 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
                if (prepend)
                {
                        pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL);
-                       while ((r1 = JsonbIteratorNext(it_object, &v1, true)) != 0)
+                       while ((r1 = JsonbIteratorNext(it_object, &v1, true)) != WJB_DONE)
                                pushJsonbValue(state, r1, r1 != WJB_END_OBJECT ? &v1 : NULL);
 
-                       while ((r2 = JsonbIteratorNext(it_array, &v2, true)) != 0)
+                       while ((r2 = JsonbIteratorNext(it_array, &v2, true)) != WJB_DONE)
                                res = pushJsonbValue(state, r2, r2 != WJB_END_ARRAY ? &v2 : NULL);
                }
                else
@@ -4628,7 +4630,7 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
                                pushJsonbValue(state, r1, &v1);
 
                        pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL);
-                       while ((r2 = JsonbIteratorNext(it_object, &v2, true)) != 0)
+                       while ((r2 = JsonbIteratorNext(it_object, &v2, true)) != WJB_DONE)
                                pushJsonbValue(state, r2, r2 != WJB_END_OBJECT ? &v2 : NULL);
 
                        res = pushJsonbValue(state, WJB_END_ARRAY, NULL);
@@ -4959,7 +4961,7 @@ parse_jsonb_index_flags(Jsonb *jb)
 
        /*
         * We iterate over array (scalar internally is represented as array, so, we
-        * will accept it too) to check all its elements. Flag's names are choosen
+        * will accept it too) to check all its elements.  Flag names are chosen
         * the same as jsonb_typeof uses.
         */
        if (type != WJB_BEGIN_ARRAY)
@@ -4997,12 +4999,14 @@ parse_jsonb_index_flags(Jsonb *jb)
                                         errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\" and \"all\"")));
        }
 
-       /* user should not get it */
+       /* expect end of array now */
        if (type != WJB_END_ARRAY)
                elog(ERROR, "unexpected end of flag array");
 
        /* get final WJB_DONE and free iterator */
-       JsonbIteratorNext(&it, &v, false);
+       type = JsonbIteratorNext(&it, &v, false);
+       if (type != WJB_DONE)
+               elog(ERROR, "unexpected end of flag array");
 
        return flags;
 }