Zack,
> On Wednesday, February 17, 2016 at 7:42:53 PM UTC-5, Solar Designer wrote:
> > Why does one of these lines use OD_DUP_VALUE? -
> >
> > /// Prepare message
> > onion_dict *jres=onion_dict_new();
> > onion_dict_add(jres, "jsonrpc", "2.0", 0);
> > onion_dict_add(jres, "result", str+start, OD_DUP_VALUE);
> > onion_dict_add(jres, "id", onion_dict_get(jreq, "id"), 0);
> >
> > "str" isn't freed until after the response is written, and str+start is
> > just part of it. Indeed, the program still appears to work fine (to the
> > extent it did before) after I changed OD_DUP_VALUE to 0 on that line.
On Thu, Feb 18, 2016 at 05:05:36AM -0800, Zachary Grafton wrote:
> I'm not 100% sure on this, but I believe it's because the onion_dict_free
> function will try to free the value stored in the key.
If I followed the calls correctly, onion_dict_node_data_free() would be
the lower-level functions eventually doing it, but only when
OD_FREE_VALUE is set. In this case, there doesn't appear to be anything
setting that flag. So no, while your theory was good, it doesn't appear
to apply to this example.
Also, if your theory applied, then the code would be trying to free the
constant string "2.0", and would likely be crashing right there.
> In this case it
> would probably lead to a double free issue when the onion_dict_free is
> called at the end of the block after onion_low_free is called on str.
That wouldn't exactly be a double-free, because str+start isn't even a
valid pointer to free unless the string started with no whitespace.
Anyway, the example mostly works fine (on valid input) whether with or
without the OD_DUP_VALUE. (It probably leaks memory as written with
OD_DUP_VALUE. I didn't check for memory leaks.)
> Either way the example is definitely confusing. I have been poking around
> the internals of onion for a couple of months and never even looked at that
> example. I think the example is claiming to adhere to the json rpc 2.0
> specification, however, from a cursory reading of the spec, it seems that
> the id field is not necessarily required. The example should check for that
> and return a proper error message. I think that according to the
> specification, when the id field is missing, that should be classified as
> an invalid request and the connection should be terminated in this case,
> unless your were sending a json rpc notification.
OK. In any case, it shouldn't segfault even on invalid input.
> If that's the behavior that you expect, please let me know and I'll try to
> fix it sometime today.
I am not currently playing with JSON-RPC specifically, so I can't answer
this directly. I'd need to take a look at JSON-RPC spec.
So far, I wrote a prototype server implementing an HTTP+JSON protocol
that I needed, using libonion and those dict functions, and it appears
to work fine and without memory leaks (on correct input, at least).
I dislike it having so much malloc()/free() activity, though, which is
potentially costly in a multi-threaded program. And yes, I am aware
libonion lets me hook its memory allocation; I'll consider that.
Alexander