JSON patch is a bit more clear on how some array operations should be
handled. Unfortunately, handling them on a case-by-case is a bit tricky
because it's difficult to satisfy properly an 'add' operating with a 'move'
operation and the basic json_pointer_set().
With json_pointer_set{f}() we use json_object_array_put_idx() to insert a
value at a certain index.
With JSON patch:
* for the 'add' operation, we need to insert a value at a given index,
which means shifting existing values by one to the right
- also, we cannot allow values to be inserted/added outside the bounds of
the array
* a 'move' operation, is described as a 'remove' and then an 'add';
for arrays this complicates things, because when we want to a move a
value within the array, we have to remove it first (during which the size
of the array is reduced by one); when the size of the array is reduced by
one, we can't add it to the last position in the array (before the
remove)
The only sane method to handle this (after a few considerations) is to
provide a callback to the function that does the final put/insert into
the array. That way, we can do some final checks where these are needed to
handle each corner-case.
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
The out-of-bounds check is useful when trying to index/obtain a value from
an array.
However, when we set a value to a specific JSON pointer, we can allow
values that are outside the length of the current array.
The RFC6901 doc isn't clear on that aspect, and doing so is a bit more
in-line with how json_object_array_{put,insert}_idx() functions behave.
This changes the behavior of json_pointer_set{f}() because now a value can
be set anywhere in the array.
Also, added a test-case for this behavior change.
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
For JSON patch, we require that we get access to the parent of a JSON
object as well in order to do some operations via the API.
For example, given the object:
{
"foo": "bar",
"array", [ 1, 2, 3]
}
Using JSON pointer with the path
* '/foo' will return 'bar' of type string
* '/array/0' will return '1', of type integer
The problem is, that if we do 'json_object_put()' on any of the objects
above, this will not detach them from the parent, because there is no
information back to the parent.
One way to fix this, is to introduce links back to the parent, and have
these links be made by 'json_object_array_{put,insert}_idx()' and
'json_object_object_add{_ex}()'[1].
[1] For json_object_object_add_ex() we would need to de-constify the second
parameter, as we need to change it's internal state when being added to a
parent object. It may break some applications, but who knows.
But, since this information is needed mostly for JSON patch, another way to
address this, is to also retrieve the parent of an object via JSON pointer
and use json_object_object_del() and json_object_array_del_idx() on the
object's parent.
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
The index cannot be negative when parsing in is_valid_index(), because we
don't allow the '-' character in a string before we get to the strtol()
function.
So, might as well remove the negative check (for idx) in is_valid_index()
and convert it to size_t. That may allow for higher values for the index
(which can be insane, but some people may want to try it).
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
This helps compiling with MS compiler, error seems to be
due to defining a variable within the body of the function
its allowed in c99 but not in c89. This should fix build with
MSVC 16.0.40219.1 compiler from Visual Studio 14 2015
Signed-off-by: Khem Raj <raj.khem@gmail.com>
If we want to override `strerror()` in libjson-c
to make tests consistent across platforms, we
need to do it build-wide as configure/build
option.
Apple linkers make it really hard to override functions
at link-time, and this seems to be locked down on travis-ci.org
[ for security reasons I assume ].
While I got it to work locally, it did not work
when running on travis.
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
These include support for printf() style args for path.
Adds support for calling with 'json_pointer_getf(obj, &res, "/foo/%d/%s", 0, bar)'
style args.
Makes it easier for doing more dynamic stuff/magic, without
needing to use vasprintf() externally.
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>