Skip to content

Commit d4f7986

Browse files
committed
Fix copy-paste error in datum_to_jsonb_internal()
Commit 3c152a2 mistakenly repeated JSONTYPE_JSON in a condition, omitting JSONTYPE_CAST. As a result, datum_to_jsonb_internal() failed to reject inputs that were casts (e.g., from an enum to json as in the example below) when used as keys in JSON constructors. This led to a crash in cases like: SELECT JSON_OBJECT('happy'::mood: '123'::jsonb); where 'happy'::mood is implicitly cast to json. The missing check meant such casted values weren’t properly rejected as invalid (non-scalar) JSON keys. Reported-by: Maciek Sakrejda <maciek@pganalyze.com> Reviewed-by: Tender Wang <tndrwang@gmail.com> Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org> Reviewed-by: Maciek Sakrejda <maciek@pganalyze.com> Discussion: https://postgr.es/m/CADXhmgTJtJZK9A3Na_ry+Xrq-ghjcejBRhcRMzWZvbd__QdgJA@mail.gmail.com Backpatch-through: 17
1 parent 4ecdd41 commit d4f7986

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

src/backend/utils/adt/jsonb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
657657
tcategory == JSONTYPE_COMPOSITE ||
658658
tcategory == JSONTYPE_JSON ||
659659
tcategory == JSONTYPE_JSONB ||
660-
tcategory == JSONTYPE_JSON))
660+
tcategory == JSONTYPE_CAST))
661661
{
662662
ereport(ERROR,
663663
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),

src/test/regress/expected/sqljson.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,18 @@ SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, 4: NULL, '5': 'a' ABSENT ON NULL WIT
573573
{"1": 1, "3": 1, "5": "a"}
574574
(1 row)
575575

576+
-- BUG: https://postgr.es/m/CADXhmgTJtJZK9A3Na_ry%2BXrq-ghjcejBRhcRMzWZvbd__QdgJA%40mail.gmail.com
577+
-- datum_to_jsonb_internal() didn't catch keys that are casts instead of a simple scalar
578+
CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral');
579+
CREATE FUNCTION mood_to_json(mood) RETURNS json AS $$
580+
SELECT to_json($1::text);
581+
$$ LANGUAGE sql IMMUTABLE;
582+
CREATE CAST (mood AS json) WITH FUNCTION mood_to_json(mood) AS IMPLICIT;
583+
SELECT JSON_OBJECT('happy'::mood: '123'::jsonb);
584+
ERROR: key value must be scalar, not array, composite, or json
585+
DROP CAST (mood AS json);
586+
DROP FUNCTION mood_to_json;
587+
DROP TYPE mood;
576588
-- JSON_ARRAY()
577589
SELECT JSON_ARRAY();
578590
json_array

src/test/regress/sql/sqljson.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,17 @@ SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE RETURNING
152152
SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITHOUT UNIQUE RETURNING jsonb);
153153
SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, 4: NULL, '5': 'a' ABSENT ON NULL WITH UNIQUE RETURNING jsonb);
154154

155+
-- BUG: https://postgr.es/m/CADXhmgTJtJZK9A3Na_ry%2BXrq-ghjcejBRhcRMzWZvbd__QdgJA%40mail.gmail.com
156+
-- datum_to_jsonb_internal() didn't catch keys that are casts instead of a simple scalar
157+
CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral');
158+
CREATE FUNCTION mood_to_json(mood) RETURNS json AS $$
159+
SELECT to_json($1::text);
160+
$$ LANGUAGE sql IMMUTABLE;
161+
CREATE CAST (mood AS json) WITH FUNCTION mood_to_json(mood) AS IMPLICIT;
162+
SELECT JSON_OBJECT('happy'::mood: '123'::jsonb);
163+
DROP CAST (mood AS json);
164+
DROP FUNCTION mood_to_json;
165+
DROP TYPE mood;
155166

156167
-- JSON_ARRAY()
157168
SELECT JSON_ARRAY();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy