From 6d10f4e9d7f0051afb60c42409f2fe61cf4da348 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Tue, 28 Jul 2015 17:54:13 -0400
Subject: [PATCH] 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.
---
 src/backend/utils/adt/jsonfuncs.c | 26 +++++++++++++-------------
 1 file 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
-- 
GitLab