Search code examples
jsonparsingg-wan

Using jsn_totext() and xbuf_empty()


Consider the following simple program (run on gwan v4.3.14):

xbuf_t buf;
xbuf_init(&buf);
xbuf_cat(&buf, "{\"num\":-1}");            // simple json string
jsn_t *jrec = jsn_frtext(buf.ptr, "rec");  // parse it
jsn_t *jnum = jsn_byname(jrec, "num",1);   // look for the element
jsn_updt(jnum, 2);                         // change the value to positive 2
xbuf_empty(&buf);                          // reuse the buffer
puts(jsn_totext(&buf, jrec, 0));           // lets take a look

The expected output is {"num":2} but it turned out to be {"num":-2}.

Somehow, jsn_totext() reused the emptied xbuffer and overwrote the location of '1' with '2'. But if I were to do jsn_update(jnum, 100), the output would be correct.

Is this a bug or did I misunderstand the functionality of xbuf_empty() ?

I am asking the quesiton because using xbuf_reset() instead of xbuf_empty() makes this code work as expected.


Solution

  • You have almost answered the question: the problem in your code comes from the (mis)use of the xbuf_empty() function.

    Let's explain why:

    The manual explains that jsn_totext() stores the output in an xbuffer and that you then have to "call xbuf_free(text) when you are done with the text".

    It means that the destination xbuffer is supposed to be unallocated yet as jsn_totext() will allocate it.

    You said that using xbuf_reset() works. This si because this call is a deprecated alias of the xbuf_init() function.

    Your confusion came from the fact that xbuf_reset() is too close to xbuf_empty()... and that's why we renamed it xbuf_init() (a few years ago).

    Now, your question is raising an interesting question which is why we did not think to either reuse or re-init already allocated xbuffers passed to jsn_totext().

    We did not do it because we obviously did not think someone would reuse the same buffer. But as your report shows, it may happen, so we will make the modification to help other users avoid the same trap.

    This is this kind of relevant feedback that makes products better as time goes. Thank you for your input.