diff --git a/json_patch.c b/json_patch.c index 904f609..3f9567b 100644 --- a/json_patch.c +++ b/json_patch.c @@ -292,7 +292,7 @@ static int json_patch_apply_move_copy(struct json_object **res, * sibling keys that happen to share a name prefix. */ if (strncmp(from_s, path, from_s_len) == 0 && - (path[from_s_len] == '\0' || path[from_s_len] == '/')) { + (from_s_len == 0 || path[from_s_len] == '\0' || path[from_s_len] == '/')) { /** * If lengths match, it's a noop, if they don't, * then we're trying to move a parent under a child diff --git a/tests/json_patch_tests.json b/tests/json_patch_tests.json index e2d62d6..ef7575b 100644 --- a/tests/json_patch_tests.json +++ b/tests/json_patch_tests.json @@ -480,6 +480,16 @@ "patch": [{"op": "copy", "from": "/aa", "path": "/aab"}], "expected": {"aa": 1, "aab": 1} }, + { "comment": "Moving the root to a path without a leading '/' must fail, not free the document", + "doc": {"a": null}, + "patch": [{"op": "move", "from": "", "path": "a"}], + "error": "the root is a parent of every other location" }, + + { "comment": "Copying the root to a path without a leading '/' must fail", + "doc": {"a": null}, + "patch": [{"op": "copy", "from": "", "path": "a"}], + "error": "the root is a parent of every other location" }, + { "comment": "Remove members whose names need escaping", "doc": {"a/b": 1, "m~n": 2, "c": 3}, "patch": [{"op": "remove", "path": "/a~1b"}, diff --git a/tests/test_json_patch.expected b/tests/test_json_patch.expected index c2b5db7..28bd7c6 100644 --- a/tests/test_json_patch.expected +++ b/tests/test_json_patch.expected @@ -131,6 +131,10 @@ Testing '(null)', doc '{ "foo": [ "bar", "baz" ], "": 0, "a\/b": 1, "c%d": 2, "e Testing 'Move to same location has no effect', doc '{ "foo": 1 }' patch '[ { "op": "move", "from": "\/foo", "path": "\/foo" } ]' : OK Testing 'Move between sibling keys sharing a name prefix is not a parent/child move', doc '{ "aa": 1, "aab": 2 }' patch '[ { "op": "move", "from": "\/aa", "path": "\/aab" } ]' : OK Testing 'Copy between sibling keys sharing a name prefix is not a parent/child move', doc '{ "aa": 1, "aab": 2 }' patch '[ { "op": "copy", "from": "\/aa", "path": "\/aab" } ]' : OK +Testing 'Moving the root to a path without a leading '/' must fail, not free the document', doc '{ "a": null }' patch '[ { "op": "move", "from": "", "path": "a" } ]' : OK + => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Invalid attempt to move parent under a child +Testing 'Copying the root to a path without a leading '/' must fail', doc '{ "a": null }' patch '[ { "op": "copy", "from": "", "path": "a" } ]' : OK + => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Invalid attempt to move parent under a child Testing 'Remove members whose names need escaping', doc '{ "a\/b": 1, "m~n": 2, "c": 3 }' patch '[ { "op": "remove", "path": "\/a~1b" }, { "op": "remove", "path": "\/m~0n" } ]' : OK Testing 'Move from a member whose name needs escaping', doc '{ "a\/b": 1 }' patch '[ { "op": "move", "from": "\/a~1b", "path": "\/c" } ]' : OK Testing '(null)', doc '{ "foo": 1, "baz": [ { "qux": "hello" } ] }' patch '[ { "op": "move", "from": "\/foo", "path": "\/bar" } ]' : OK