Re: jsonb iterator not fully initialized

From: Piotr Stefaniak <postgres(at)piotr-stefaniak(dot)me>
To: Peter Eisentraut <peter(dot)eisentraut(at)2ndquadrant(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: jsonb iterator not fully initialized
Date: 2018-05-26 07:09:00
Message-ID: DB6PR0301MB237442B41DBEBA1979ED2178F2680@DB6PR0301MB2374.eurprd03.prod.outlook.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 2018-05-26 02:02, Peter Eisentraut wrote:
> I got this error message via -fsanitized=undefined:
>
> jsonfuncs.c:5169:12: runtime error: load of value 127, which is not a
> valid value for type '_Bool'
>
> The query was
>
> select ts_headline('{}'::jsonb, tsquery('aaa & bbb'));
>
> This calls the C function ts_headline_jsonb_byid_opt(), which calls
> transform_jsonb_string_values(), which calls
>
> it = JsonbIteratorInit(&jsonb->root);
> is_scalar = it->isScalar;
>
> but it->isScalar is not always initialized by JsonbIteratorInit(). (So
> the 127 is quite likely clobbered memory.)
>
> It can be fixed this way:
>
> --- a/src/backend/utils/adt/jsonb_util.c
> +++ b/src/backend/utils/adt/jsonb_util.c
> @@ -901,7 +901,7 @@ iteratorFromContainer(JsonbContainer *container,
> JsonbIterator *parent)
> {
> JsonbIterator *it;
>
> - it = palloc(sizeof(JsonbIterator));
> + it = palloc0(sizeof(JsonbIterator));
> it->container = container;
> it->parent = parent;
> it->nElems = JsonContainerSize(container);
>
> It's probably not a problem in practice, since the isScalar business is
> apparently only used in the array case, but it's dubious to leave things
> uninitialized like this nonetheless.
>

I've seen it earlier but couldn't decide what my proposed fix should
look like. One of the options I considered was:

--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -5010,10 +5010,8 @@ transform_jsonb_string_values(Jsonb *jsonb, void
*action_state,
JsonbIteratorToken type;
JsonbParseState *st = NULL;
text *out;
- bool is_scalar = false;

it = JsonbIteratorInit(&jsonb->root);
- is_scalar = it->isScalar;

while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
{
@@ -5033,7 +5031,7 @@ transform_jsonb_string_values(Jsonb *jsonb, void
*action_state,
}

if (res->type == jbvArray)
- res->val.array.rawScalar = is_scalar;
+ res->val.array.rawScalar =
JsonContainerIsScalar(&jsonb->root);

return JsonbValueToJsonb(res);
}

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2018-05-26 13:03:00 Re: zheap: a new storage format for PostgreSQL
Previous Message Michael Paquier 2018-05-26 03:48:04 Re: Avoiding Tablespace path collision for primary and standby