mirror of
https://github.com/json-c/json-c.git
synced 2026-11-09 23:40:14 +08:00
json_patch: reject a move past the end of the same array
json_object_array_move_cb() added one to the array length when "from"
and "path" are in the same array, so that the old length counted as a
valid target index. A move is a remove followed by an add (RFC 6902
section 4.4), and the add's index must not be greater than the number
of elements left after the remove. With the extra slot,
json_object_array_insert_idx() was called one past the end and padded
the array with a null:
doc: {"foo": [1, 2, 3]}
patch: [{"op": "move", "from": "/foo/0", "path": "/foo/3"}]
returned 0 with {"foo": [2, 3, null, 1]}. It now fails with EINVAL,
like an add to /foo/3 on a two-element array. Moving to /foo/2 or
/foo/- still puts the element last.
This commit is contained in:
1 parent
46f0355925
commit
0389cc85ce
3 files changed
+16
-10
No files matched your search
+3
-10
@@ -233,19 +233,12 @@ static int json_object_array_move_cb(struct json_object *parent, const char *key
|
||||
struct json_object *value, void *priv)
|
||||
{
|
||||
int rc;
|
||||
struct json_pointer_get_result *from = priv;
|
||||
size_t len = json_object_array_length(parent);
|
||||
|
||||
/**
|
||||
* If it's the same array parent, it means that we removed
|
||||
* and element from it, so the length is temporarily reduced
|
||||
* by 1, which means that if we try to move an element to
|
||||
* the last position, we need to check the current length + 1
|
||||
* When moving within the same array, the element has already been
|
||||
* removed, and idx refers to the shorter array (RFC 6902 section 4.4)
|
||||
*/
|
||||
if (parent == from->parent)
|
||||
len++;
|
||||
|
||||
if (idx > len)
|
||||
if (idx > json_object_array_length(parent))
|
||||
{
|
||||
// Note: will propagate back out through json_pointer_set_with_cb()
|
||||
errno = EINVAL;
|
||||
|
||||
Reference in new issue
Block a user