From ad66344ad6ec13403d90a12e959e980a4f1933dd Mon Sep 17 00:00:00 2001 From: Lucas Alvares Gomes Date: Wed, 22 Jan 2014 17:02:42 +0000 Subject: Catch KeyError when accessing the sub-doc items --- jsonpatch.py | 12 +++++++++--- tests.py | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/jsonpatch.py b/jsonpatch.py index a46c9b0..59b3274 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -398,7 +398,7 @@ class RemoveOperation(PatchOperation): subobj, part = self.pointer.to_last(obj) try: del subobj[part] - except IndexError as ex: + except (KeyError, IndexError) as ex: raise JsonPatchConflict(str(ex)) return obj @@ -464,7 +464,10 @@ class MoveOperation(PatchOperation): def apply(self, obj): from_ptr = JsonPointer(self.operation['from']) subobj, part = from_ptr.to_last(obj) - value = subobj[part] + try: + value = subobj[part] + except (KeyError, IndexError) as ex: + raise JsonPatchConflict(str(ex)) if isinstance(subobj, dict) and self.pointer.contains(from_ptr): raise JsonPatchException('Cannot move values into its own children') @@ -512,7 +515,10 @@ class CopyOperation(PatchOperation): def apply(self, obj): from_ptr = JsonPointer(self.operation['from']) subobj, part = from_ptr.to_last(obj) - value = copy.deepcopy(subobj[part]) + try: + value = copy.deepcopy(subobj[part]) + except (KeyError, IndexError) as ex: + raise JsonPatchConflict(str(ex)) obj = AddOperation({ 'op': 'add', diff --git a/tests.py b/tests.py index c071ce2..9b1c5d9 100755 --- a/tests.py +++ b/tests.py @@ -75,6 +75,12 @@ class ApplyPatchTestCase(unittest.TestCase): 'value': 'boo'}]) self.assertEqual(res['foo'], ['bar', 'boo', 'baz']) + def test_move_object_keyerror(self): + obj = {'foo': {'bar': 'baz'}, + 'qux': {'corge': 'grault'}} + patch_obj = [ {'op': 'move', 'from': '/foo/non-existent', 'path': '/qux/thud'} ] + self.assertRaises(jsonpatch.JsonPatchConflict, jsonpatch.apply_patch, obj, patch_obj) + def test_move_object_key(self): obj = {'foo': {'bar': 'baz', 'waldo': 'fred'}, 'qux': {'corge': 'grault'}} @@ -94,6 +100,12 @@ class ApplyPatchTestCase(unittest.TestCase): res = jsonpatch.apply_patch(obj, patch) self.assertEqual(res, [{'bar': [{"foo": []}]}]) + def test_copy_object_keyerror(self): + obj = {'foo': {'bar': 'baz'}, + 'qux': {'corge': 'grault'}} + patch_obj = [{'op': 'copy', 'from': '/foo/non-existent', 'path': '/qux/thud'}] + self.assertRaises(jsonpatch.JsonPatchConflict, jsonpatch.apply_patch, obj, patch_obj) + def test_copy_object_key(self): obj = {'foo': {'bar': 'baz', 'waldo': 'fred'}, 'qux': {'corge': 'grault'}} @@ -314,6 +326,11 @@ class ConflictTests(unittest.TestCase): patch_obj = [ { "op": "remove", "path": "/foo/b"} ] self.assertRaises(jsonpointer.JsonPointerException, jsonpatch.apply_patch, src, patch_obj) + def test_remove_keyerror_dict(self): + src = {'foo': {'bar': 'barz'}} + patch_obj = [ { "op": "remove", "path": "/foo/non-existent"} ] + self.assertRaises(jsonpatch.JsonPatchConflict, jsonpatch.apply_patch, src, patch_obj) + def test_insert_oob(self): src = {"foo": [1, 2]} patch_obj = [ { "op": "add", "path": "/foo/10", "value": 1} ] -- cgit v1.2.1