diff options
author | Andrew Dunstan <andrew@dunslane.net> | 2015-07-28 17:54:13 -0400 |
---|---|---|
committer | Andrew Dunstan <andrew@dunslane.net> | 2015-07-28 17:54:13 -0400 |
commit | 6d10f4e9d7f0051afb60c42409f2fe61cf4da348 (patch) | |
tree | 4db7a8ed0088b5d6614caab678d54737661a50f5 /src/backend/utils/adt/jsonfuncs.c | |
parent | d8f15c95bec50f552ad0b13ea6eafb6975126184 (diff) | |
download | postgresql-6d10f4e9d7f0051afb60c42409f2fe61cf4da348.tar.gz postgresql-6d10f4e9d7f0051afb60c42409f2fe61cf4da348.zip |
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.
Diffstat (limited to 'src/backend/utils/adt/jsonfuncs.c')
-rw-r--r-- | src/backend/utils/adt/jsonfuncs.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index 17e787b60a2..3b8d42e4d51 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 |