summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/json.c7
-rw-r--r--src/test/regress/expected/json.out9
-rw-r--r--src/test/regress/expected/json_1.out9
-rw-r--r--src/test/regress/sql/json.sql6
4 files changed, 31 insertions, 0 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 0566b926fed..61088a24339 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -21,6 +21,7 @@
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
+#include "miscadmin.h"
#include "parser/parse_coerce.h"
#include "utils/array.h"
#include "utils/builtins.h"
@@ -427,6 +428,8 @@ parse_object(JsonLexContext *lex, JsonSemAction *sem)
json_struct_action oend = sem->object_end;
JsonTokenType tok;
+ check_stack_depth();
+
if (ostart != NULL)
(*ostart) (sem->semstate);
@@ -505,6 +508,8 @@ parse_array(JsonLexContext *lex, JsonSemAction *sem)
json_struct_action astart = sem->array_start;
json_struct_action aend = sem->array_end;
+ check_stack_depth();
+
if (astart != NULL)
(*astart) (sem->semstate);
@@ -1338,6 +1343,8 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
char *outputstr;
text *jsontext;
+ check_stack_depth();
+
if (is_null)
{
appendStringInfoString(result, "null");
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index 0e1d79121f9..a43c9e01bef 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -231,6 +231,15 @@ LINE 1: SELECT '{"abc":1,3}'::json;
^
DETAIL: Expected string, but found "3".
CONTEXT: JSON data, line 1: {"abc":1,3...
+-- Recursion.
+SET max_stack_depth = '100kB';
+SELECT repeat('[', 1000)::json;
+ERROR: stack depth limit exceeded
+HINT: Increase the configuration parameter "max_stack_depth" (currently 100kB), after ensuring the platform's stack depth limit is adequate.
+SELECT repeat('{"a":', 1000)::json;
+ERROR: stack depth limit exceeded
+HINT: Increase the configuration parameter "max_stack_depth" (currently 100kB), after ensuring the platform's stack depth limit is adequate.
+RESET max_stack_depth;
-- Miscellaneous stuff.
SELECT 'true'::json; -- OK
json
diff --git a/src/test/regress/expected/json_1.out b/src/test/regress/expected/json_1.out
index f19acf755a2..075c3f0e0fa 100644
--- a/src/test/regress/expected/json_1.out
+++ b/src/test/regress/expected/json_1.out
@@ -231,6 +231,15 @@ LINE 1: SELECT '{"abc":1,3}'::json;
^
DETAIL: Expected string, but found "3".
CONTEXT: JSON data, line 1: {"abc":1,3...
+-- Recursion.
+SET max_stack_depth = '100kB';
+SELECT repeat('[', 1000)::json;
+ERROR: stack depth limit exceeded
+HINT: Increase the configuration parameter "max_stack_depth" (currently 100kB), after ensuring the platform's stack depth limit is adequate.
+SELECT repeat('{"a":', 1000)::json;
+ERROR: stack depth limit exceeded
+HINT: Increase the configuration parameter "max_stack_depth" (currently 100kB), after ensuring the platform's stack depth limit is adequate.
+RESET max_stack_depth;
-- Miscellaneous stuff.
SELECT 'true'::json; -- OK
json
diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql
index 2de144bbaf7..f1f898418dd 100644
--- a/src/test/regress/sql/json.sql
+++ b/src/test/regress/sql/json.sql
@@ -45,6 +45,12 @@ SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::json; -- OK
SELECT '{"abc":1:2}'::json; -- ERROR, colon in wrong spot
SELECT '{"abc":1,3}'::json; -- ERROR, no value
+-- Recursion.
+SET max_stack_depth = '100kB';
+SELECT repeat('[', 1000)::json;
+SELECT repeat('{"a":', 1000)::json;
+RESET max_stack_depth;
+
-- Miscellaneous stuff.
SELECT 'true'::json; -- OK
SELECT 'false'::json; -- OK