Only adjust negative indexes in json_get up to the length of the path.
authorAndrew Dunstan
Tue, 28 Jul 2015 21:54:13 +0000 (17:54 -0400)
committerAndrew Dunstan
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