]> granicus.if.org Git - postgresql/commitdiff
Only adjust negative indexes in json_get up to the length of the path.
authorAndrew Dunstan <andrew@dunslane.net>
Tue, 28 Jul 2015 21:54:13 +0000 (17:54 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Tue, 28 Jul 2015 21:54:13 +0000 (17:54 -0400)
The previous code resulted in memory access beyond the path bounds. The
cure is to move it into a code branch that checks the value of lex_level
is within the correct bounds.

Bug reported and diagnosed by Piotr Stefaniak.

src/backend/utils/adt/jsonfuncs.c

index 17e787b60a2eda2dabc86bae92d9674a5e8a191d..3b8d42e4d51b7b44e4c9670411ec6071b539cad0 100644 (file)
@@ -977,27 +977,27 @@ get_array_start(void *state)
        {
                /* Initialize counting of elements in this array */
                _state->array_cur_index[lex_level] = -1;
+
+               /* INT_MIN value is reserved to represent invalid subscript */
+               if (_state->path_indexes[lex_level] < 0 &&
+                       _state->path_indexes[lex_level] != INT_MIN)
+               {
+                       /* Negative subscript -- convert to positive-wise subscript */
+                       int             nelements = json_count_array_elements(_state->lex);
+
+                       if (-_state->path_indexes[lex_level] <= nelements)
+                               _state->path_indexes[lex_level] += nelements;
+               }
        }
        else if (lex_level == 0 && _state->npath == 0)
        {
                /*
                 * Special case: we should match the entire array.  We only need this
-                * at outermost level because at nested levels the match will have
-                * been started by the outer field or array element callback.
+                * at the outermost level because at nested levels the match will
+                * have been started by the outer field or array element callback.
                 */
                _state->result_start = _state->lex->token_start;
        }
-
-       /* INT_MIN value is reserved to represent invalid subscript */
-       if (_state->path_indexes[lex_level] < 0 &&
-               _state->path_indexes[lex_level] != INT_MIN)
-       {
-               /* Negative subscript -- convert to positive-wise subscript */
-               int             nelements = json_count_array_elements(_state->lex);
-
-               if (-_state->path_indexes[lex_level] <= nelements)
-                       _state->path_indexes[lex_level] += nelements;
-       }
 }
 
 static void