poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: master is broken due to latest changes to pk-mi-json


From: Jose E. Marchesi
Subject: Re: master is broken due to latest changes to pk-mi-json
Date: Fri, 26 Nov 2021 17:31:08 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

> On Fri, Nov 26, 2021 at 04:41:57PM +0100, Jose E. Marchesi wrote:
>> 
>> > On Fri, Nov 26, 2021 at 04:14:15PM +0100, Jose E. Marchesi wrote:
>> >> 
>> >> > Or even better approach:
>> >> >   Convert JSON to string representation (using 
>> >> > `json_object_to_json_string`)
>> >> >   and `strcmp` the string representation of objects.
>> >> >
>> >> > I think due to the fact that we just use `json_object_equal` in 
>> >> > testsuite,
>> >> > it's totally fine to use this not-so-optimized approach.
>> >> > WDYT?
>> >> 
>> >> This would be feasible, but may lead to spurious results depending on
>> >> how the conversion routine is implemented: there may not be a 1-1
>> >> relationship between the written representation and the JSON object.
>> >> 
>> >
>> >
>> > The whole purpose of a JSON library is to encode/decode to/from string
>> > representation. If a library fails on this simple thing, we should not use
>> > it at all.
>> 
>> I think that this:
>> 
>> <<<<<<<
>> { 10, 20 }
>> >>>>>>>
>> 
>> and this:
>> 
>> <<<<<<<
>> { 10,
>>   20,
>> }
>> >>>>>>>
>> 
>> Denote the same JSON object using different written representations.
>
>
> Yes. You're right.
>
>
>> 
>> I don't think that json_object_to_json_string makes any promise in that
>> the returned string is identical when the passed JSON objects are
>> "equal".
>> 
>
>
> Excerpt from `json-c/json_object.h`:
>
>
> ```c
> /**
>  * A flag for the json_object_to_json_string_ext() and
>  * json_object_to_file_ext() functions which causes the output to have
>  * minimal whitespace inserted to make things slightly more readable.
>  */
> #define JSON_C_TO_STRING_SPACED (1 << 0)
>
> // ...
>
> /** Stringify object to json format.
>  * Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED)
>  * The pointer you get is an internal of your json object. You don't
>  * have to free it, later use of json_object_put() should be sufficient.
>  * If you can not ensure there's no concurrent access to *obj use
>  * strdup().
>  * @param obj the json_object instance
>  * @returns a string in JSON format
>  */
> JSON_EXPORT const char *json_object_to_json_string(struct json_object *obj);
> ```
>
> So, I think it will produce the same amount of whitespace in two consecutive
> calls in a single executable :)

Ok, so what about this:

<<<<<
{1,2}
>>>>>

versus this:

<<<<<
{0x1,0x2}
>>>>>

:)

>> By the way, what does that mean, for a JSON object to be "equal" to
>> another?  Is that equality by structure?
>> 
>
>
> IMHO if it has the same structure and fields, we can define them as equal.
> We're talking equality in a very specific context, string represention from
> a function in a single library in a single executable.
> Yes, I consider `{"a":1,"b":2}` equal to `{"b":2,"a":1}` despite the fact that
> they're not using the same string representation.
> But here, we're talking about output of `json_object_to_json_string`.

Right.  But again, json_object_to_json_string doesn't promise anything
about the written representation of two _different_ JSON objects that
happen to be the "equal".

There is not a canonical written representation of the JSON dictionary
object having two entries one with name "a" and value 1 and the other
with name "b" and value 2.

json_object is an opaque type for us.  We don't know what data structure
they use to store dictionary entries.  It may be a hash table, or it may
be an array of entries, or a linked-list of entries.  We don't know, and
we don't care.

So let's suppose they use a linked list of entries.  Then two
json_object values, like j1 and j2 in your example, may be "equal" but
having the entries stored internally in different order.

Then it would be natural for

  json_object_to_json_string (j1)

and

  json_object_to_json_string (j2)

to generate two different strings

  {"a":1,"b":2}

and

  {"b":2,"a":1}

because of the lack of a canonical written representation.

So this predicate:

> static int
> pk_json_object_equal_p (struct json_object *j1, struct json_object *j2)
> {
>   return STREQ (json_object_to_json_string (j1),
>                 json_object_to_json_string (j2));
> }

is clearly wrong.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]