summaryrefslogtreecommitdiff
path: root/jsonpatch.py
diff options
context:
space:
mode:
authorStefan Kögl <stefan@skoegl.net>2021-03-02 21:11:16 +0100
committerGitHub <noreply@github.com>2021-03-02 21:11:16 +0100
commit25762afe94ce465c05465a763f27e879e1523819 (patch)
tree89bb2c6e98c6ed5ebbe1851cb836df2fd6b29d68 /jsonpatch.py
parenta9a83b5aae65db3007fef8a4015f46e6e59d69c2 (diff)
parentf6b26b25805f1c01c3fae1495176cefac7d4a158 (diff)
downloadpython-json-patch-1.29.tar.gz
Merge pull request #122 from RyanSept/119-120-fix-diffbuilderv1.29
#119 #120 Fix make_patch() to avoid casting numeric string to int on item moved
Diffstat (limited to 'jsonpatch.py')
-rw-r--r--jsonpatch.py13
1 files changed, 10 insertions, 3 deletions
diff --git a/jsonpatch.py b/jsonpatch.py
index 84f6fb3..b4ff24b 100644
--- a/jsonpatch.py
+++ b/jsonpatch.py
@@ -635,7 +635,7 @@ class JsonPatch(object):
True
"""
json_dumper = dumps or cls.json_dumper
- builder = DiffBuilder(json_dumper, pointer_cls=pointer_cls)
+ builder = DiffBuilder(src, dst, json_dumper, pointer_cls=pointer_cls)
builder._compare_values('', None, src, dst)
ops = list(builder.execute())
return cls(ops, pointer_cls=pointer_cls)
@@ -688,12 +688,14 @@ class JsonPatch(object):
class DiffBuilder(object):
- def __init__(self, dumps=json.dumps, pointer_cls=JsonPointer):
+ def __init__(self, src_doc, dst_doc, dumps=json.dumps, pointer_cls=JsonPointer):
self.dumps = dumps
self.pointer_cls = pointer_cls
self.index_storage = [{}, {}]
self.index_storage2 = [[], []]
self.__root = root = []
+ self.src_doc = src_doc
+ self.dst_doc = dst_doc
root[:] = [root, root, None]
def store_index(self, value, index, st):
@@ -800,7 +802,12 @@ class DiffBuilder(object):
new_index = self.insert(new_op)
if index is not None:
op = index[2]
- if type(op.key) == int:
+ # We can't rely on the op.key type since PatchOperation casts
+ # the .key property to int and this path wrongly ends up being taken
+ # for numeric string dict keys while the intention is to only handle lists.
+ # So we do an explicit check on the item affected by the op instead.
+ added_item = op.pointer.to_last(self.dst_doc)[0]
+ if type(added_item) == list:
for v in self.iter_from(index):
op.key = v._on_undo_add(op.path, op.key)