diff options
| author | Tom Lane | 2025-12-13 21:18:23 +0000 |
|---|---|---|
| committer | Tom Lane | 2025-12-13 21:18:29 +0000 |
| commit | ef5f559b95e2883c32d20d309d316f0572fd84b5 (patch) | |
| tree | d3f56d73ea1752f1377991d74cf34fed50f275c9 /src/backend/utils/adt/jsonb.c | |
| parent | 315342ffedf6b81f629c42e87bfaedbcc7211646 (diff) | |
Fix jsonb_object_agg crash after eliminating null-valued pairs.
In commit b61aa76e4 I added an assumption in jsonb_object_agg_finalfn
that it'd be okay to apply uniqueifyJsonbObject repeatedly to a
JsonbValue. I should have studied that code more closely first,
because in skip_nulls mode it removed leading nulls by changing the
"pairs" array start pointer. This broke the data structure's
invariants in two ways: pairs no longer references a repalloc-able
chunk, and the distance from pairs to the end of its array is less
than parseState->size. So any subsequent addition of more pairs is
at high risk of clobbering memory and/or causing repalloc to crash.
Unfortunately, adding more pairs is exactly what will happen when the
aggregate is being used as a window function.
Fix by rewriting uniqueifyJsonbObject to not do that. The prior
coding had little to recommend it anyway.
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/ec5e96fb-ee49-4e5f-8a09-3f72b4780538@gmail.com
Diffstat (limited to 'src/backend/utils/adt/jsonb.c')
| -rw-r--r-- | src/backend/utils/adt/jsonb.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index c4fe6e00dcd..dcf84c3fddc 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -1755,8 +1755,11 @@ jsonb_object_agg_finalfn(PG_FUNCTION_ARGS) * the stored JsonbValue data structure. Fortunately, the WJB_END_OBJECT * action will only destructively change fields in the JsonbInState struct * itself, so we can simply invoke pushJsonbValue on a local copy of that. - * (This technique results in running uniqueifyJsonbObject each time, but - * for now we won't bother trying to avoid that.) + * Note that this will run uniqueifyJsonbObject each time; that's hard to + * avoid, since duplicate pairs may have been added since the previous + * finalization. We assume uniqueifyJsonbObject can be applied repeatedly + * (with the same unique_keys/skip_nulls options) without damaging the + * data structure. */ result = arg->pstate; |
