json_patch: remove members whose names contain '/' or '~'

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.
This commit is contained in:
fhgffy authored and Eric Hawicz committed 2026-10-25 18:19:07 -04:00
1 parent e77ca4fb3d
commit 86fe287188
4 files changed
+26 -3

No files matched your search

+11
View File
@@ -380,6 +380,17 @@
"patch": [{"op": "copy", "from": "/aa", "path": "/aab"}],
"expected": {"aa": 1, "aab": 1} },
{ "comment": "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"}],
"expected": {"c": 3} },
{ "comment": "Move from a member whose name needs escaping",
"doc": {"a/b": 1},
"patch": [{"op": "move", "from": "/a~1b", "path": "/c"}],
"expected": {"c": 1} },
{ "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
"patch": [{"op": "move", "from": "/foo", "path": "/bar"}],
"expected": {"baz": [{"qux": "hello"}], "bar": 1} },