From: Andrew Dunstan Date: Tue, 28 Jul 2015 21:54:13 +0000 (-0400) Subject: Only adjust negative indexes in json_get up to the length of the path. X-Git-Tag: REL9_6_BETA1~1612 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d10f4e9d7f0051afb60c42409f2fe61cf4da348;p=postgresql Only adjust negative indexes in json_get up to the length of the path. 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. --- diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index 17e787b60a..3b8d42e4d5 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -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