Skip to content

Commit 3c633f3

Browse files
committed
Only allow returning string types or bytea from json_serialize
These are documented to be the allowed types for the RETURNING clause, but the restriction was not being enforced, which caused a segfault if another type was specified. Add some testing for this. Per report from a.kozhemyakin Backpatch to release 15.
1 parent 8821054 commit 3c633f3

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

src/backend/parser/parse_expr.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4574,7 +4574,24 @@ transformJsonSerializeExpr(ParseState *pstate, JsonSerializeExpr *expr)
45744574
JsonReturning *returning;
45754575

45764576
if (expr->output)
4577+
{
45774578
returning = transformJsonOutput(pstate, expr->output, true);
4579+
4580+
if (returning->typid != BYTEAOID)
4581+
{
4582+
char typcategory;
4583+
bool typispreferred;
4584+
4585+
get_type_category_preferred(returning->typid, &typcategory,
4586+
&typispreferred);
4587+
if (typcategory != TYPCATEGORY_STRING)
4588+
ereport(ERROR,
4589+
(errcode(ERRCODE_DATATYPE_MISMATCH),
4590+
errmsg("cannot use RETURNING type %s in JSON_SERIALIZE",
4591+
format_type_be(returning->typid)),
4592+
errhint("Try returning a string type or bytea")));
4593+
}
4594+
}
45784595
else
45794596
{
45804597
/* RETURNING TEXT FORMAT JSON is by default */

src/test/regress/expected/sqljson.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,12 +302,22 @@ SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING bytea);
302302
\x7b20226122203a2031207d20
303303
(1 row)
304304

305+
SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar);
306+
json_serialize
307+
----------------
308+
{ "a" : 1 }
309+
(1 row)
310+
305311
SELECT pg_typeof(JSON_SERIALIZE(NULL));
306312
pg_typeof
307313
-----------
308314
text
309315
(1 row)
310316

317+
-- only string types or bytea allowed
318+
SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING jsonb);
319+
ERROR: cannot use RETURNING type jsonb in JSON_SERIALIZE
320+
HINT: Try returning a string type or bytea
311321
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}');
312322
QUERY PLAN
313323
-----------------------------------------------------

src/test/regress/sql/sqljson.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,13 @@ SELECT JSON_SERIALIZE('{ "a" : 1 } ');
6060
SELECT JSON_SERIALIZE('1');
6161
SELECT JSON_SERIALIZE('1' FORMAT JSON);
6262
SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING bytea);
63+
SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar);
6364
SELECT pg_typeof(JSON_SERIALIZE(NULL));
6465

66+
-- only string types or bytea allowed
67+
SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING jsonb);
68+
69+
6570
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}');
6671
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SERIALIZE('{}' RETURNING bytea);
6772

0 commit comments

Comments
 (0)