json_pointer_get_internal() decodes the last reference token in a
private copy of the path, then pointed key_in_parent at the same offset
in the caller's path, where the token is still escaped. For a path like
"/a~1b" that gave "a~1b" instead of "a/b", so json_patch's remove,
and the remove step of move, called json_object_object_del() with a key
that doesn't exist. Nothing was removed and the patch still reported
success; a move left the source member in place.
Point key_in_parent at the key as it is stored in the parent object
instead, which is always the decoded name.
Added remove and move cases with escaped member names to
json_patch_tests.json and refreshed test_json_patch.expected.
json_patch_apply_move_copy() checks that "from" is not a proper prefix
of "path" per RFC 6902 section 4.4 (a location cannot be moved into one
of its own children), but it did so with a plain strncmp() over the raw
pointer strings, without checking that the shared run of characters
actually ends on a JSON Pointer reference-token boundary in "path".
As a result, moving or copying between two sibling object keys where
one name is a textual prefix of the other, e.g. "/aa" to "/aab", was
rejected with "Invalid attempt to move parent under a child" even
though "/aa" is not an ancestor pointer of "/aab" at all, just an
unrelated key that happens to share a few leading characters.
The fix requires that the character in "path" right after the shared
"from" prefix be either the end of the string (equal paths, a no-op)
or a '/' (a genuine nested reference token), before treating it as an
attempt to move a location under its own descendant.
Added two cases to json_patch_tests.json covering the move and copy
operations between such sibling keys, and refreshed the corresponding
golden test_json_patch.expected output.