Re: jsonb iterator not fully initialized - Mailing list pgsql-hackers

From Piotr Stefaniak
Subject Re: jsonb iterator not fully initialized
Date
Msg-id DB6PR0301MB237442B41DBEBA1979ED2178F2680@DB6PR0301MB2374.eurprd03.prod.outlook.com
Whole thread Raw
In response to jsonb iterator not fully initialized  (Peter Eisentraut <peter.eisentraut@2ndquadrant.com>)
Responses Re: jsonb iterator not fully initialized  (Andrew Dunstan <andrew.dunstan@2ndquadrant.com>)
List 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);
  }

pgsql-hackers by date:

Previous
From: Michael Paquier
Date:
Subject: Re: Avoiding Tablespace path collision for primary and standby
Next
From: Amit Kapila
Date:
Subject: Re: zheap: a new storage format for PostgreSQL