]> git.ipfire.org Git - thirdparty/postgresql.git/commit
Fix jsonb subscripting to cope with toasted subscript values.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 12 Dec 2022 21:17:49 +0000 (16:17 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 12 Dec 2022 21:17:49 +0000 (16:17 -0500)
commita18328bb3395188befc2785dbbe47f0d84baf6d1
treeb3a4cb360d7867bbbef0f81caa1f69da76f70e20
parentd43a97ef493a7edc9e03b5dd15870e04a0c38f75
Fix jsonb subscripting to cope with toasted subscript values.

jsonb_get_element() was incautious enough to use VARDATA() and
VARSIZE() directly on an arbitrary text Datum.  That of course
fails if the Datum is short-header, compressed, or out-of-line.
The typical result would be failing to match any element of a
jsonb object, though matching the wrong one seems possible as well.

setPathObject() was slightly brighter, in that it used VARDATA_ANY
and VARSIZE_ANY_EXHDR, but that only kept it out of trouble for
short-header Datums.  push_path() had the same issue.  This could
result in faulty subscripted insertions, though keys long enough to
cause a problem are likely rare in the wild.

Having seen these, I looked around for unsafe usages in the rest
of the adt/json* files.  There are a couple of places where it's not
immediately obvious that the Datum can't be compressed or out-of-line,
so I added pg_detoast_datum_packed() to cope if it is.  Also, remove
some other usages of VARDATA/VARSIZE on Datums we just extracted from
a text array.  Those aren't actively broken, but they will become so
if we ever start allowing short-header array elements, which does not
seem like a terribly unreasonable thing to do.  In any case they are
not great coding examples, and they could also do with comments
pointing out that we're assuming we don't need pg_detoast_datum_packed.

Per report from exe-dealer@yandex.ru.  Patch by me, but thanks to
David Johnston for initial investigation.  Back-patch to v14 where
jsonb subscripting was introduced.

Discussion: https://postgr.es/m/205321670615953@mail.yandex.ru
src/backend/utils/adt/jsonb_gin.c
src/backend/utils/adt/jsonb_op.c
src/backend/utils/adt/jsonfuncs.c
src/test/regress/expected/jsonb.out
src/test/regress/sql/jsonb.sql