]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
reject null op/path/from fields in json_patch_apply
authorJavid Khan <dxbjavid@gmail.com>
Thu, 16 Jul 2026 07:25:41 +0000 (12:55 +0530)
committerJavid Khan <dxbjavid@gmail.com>
Thu, 16 Jul 2026 07:25:41 +0000 (12:55 +0530)
json_patch.c
tests/json_patch_tests.json
tests/test_json_patch.expected

index 7eec770ccea64354564d6d31b2d4f55b8720c786..6b061ff51c39ae0ff94b5f12549259d2e01a5ed7 100644 (file)
@@ -209,6 +209,10 @@ static int json_patch_apply_move_copy(struct json_object **res,
        }
 
        from_s = json_object_get_string(jfrom);
+       if (from_s == NULL) {
+               _set_err(EINVAL, "Patch object 'from' field is not a string");
+               return -1;
+       }
 
        from_s_len = strlen(from_s);
        if (strncmp(from_s, path, from_s_len) == 0) {
@@ -320,11 +324,19 @@ int json_patch_apply(struct json_object *copy_from, struct json_object *patch,
                        return -1;
                }
                op = json_object_get_string(jop);
+               if (op == NULL) {
+                       _set_err(EINVAL, "Patch object 'op' field is not a string");
+                       return -1;
+               }
                if (!json_object_object_get_ex(patch_elem, "path", &jpath)) {
                        _set_err(EINVAL, "Patch object does not contain 'path' field");
                        return -1;
                }
                path = json_object_get_string(jpath); // Note: empty string is ok!
+               if (path == NULL) {
+                       _set_err(EINVAL, "Patch object 'path' field is not a string");
+                       return -1;
+               }
 
                if (!strcmp(op, "test"))
                        rc = json_patch_apply_test(base, patch_elem, path, patch_error);
index a554ab96f987fff78c4b55c0d718bc73b703adb1..10fad98df9f002ae481de84332395f170ab7868a 100644 (file)
        "patch": [{"op": "copy", "from": "/a", "path": "/b"},
                  {"op": "copy", "from": "/b", "path": "/a/p/x"}],
        "expected": {"a": {"p": {"x": {"p": {}}}}, "b": {"p": {}}}
+    },
+
+    { "comment": "null op field must be rejected, not dereferenced",
+       "doc": {"foo": "bar"},
+       "patch": [{"op": null, "path": "/foo"}],
+       "error": "a null op field should fail rather than crash"
+    },
+
+    { "comment": "null from field must be rejected, not dereferenced",
+       "doc": {"foo": "bar"},
+       "patch": [{"op": "move", "from": null, "path": "/foo"}],
+       "error": "a null from field should fail rather than crash"
     }
 
 ]
index 69777eb3c70dd662407fc14eb7d77d1cad7e3421..9f065e02d7ad23d3f08d629c2b83941be767c2cc 100644 (file)
@@ -123,7 +123,7 @@ Testing 'test add with bad number should fail', doc '[ "foo", "sil" ]' patch '[
 Testing 'missing 'path' parameter', doc '{ }' patch '[ { "op": "add", "value": "bar" } ]' : OK
  => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Patch object does not contain 'path' field
 Testing ''path' parameter with null value', doc '{ }' patch '[ { "op": "add", "path": null, "value": "bar" } ]' : OK
- => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Failed to set value at path referenced by 'path' field
+ => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Patch object 'path' field is not a string
 Testing 'invalid JSON Pointer token', doc '{ }' patch '[ { "op": "add", "path": "foo", "value": "bar" } ]' : OK
  => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Failed to set value at path referenced by 'path' field
 Testing 'missing 'value' parameter to add', doc '[ 1 ]' patch '[ { "op": "add", "path": "\/-" } ]' : OK
@@ -157,3 +157,7 @@ Testing 'Removing nonexistent index', doc '[ "foo", "bar" ]' patch '[ { "op": "r
  => json_patch_apply failed as expected: ERRNO=ENOENT at patch idx 0: Did not find element referenced by path field
 Testing 'Patch with different capitalisation than doc', doc '{ "foo": "bar" }' patch '[ { "op": "add", "path": "\/FOO", "value": "BAR" } ]' : OK
 Testing 'copy must duplicate the value, not alias it, so no cycle can form', doc '{ "a": { "p": { } } }' patch '[ { "op": "copy", "from": "\/a", "path": "\/b" }, { "op": "copy", "from": "\/b", "path": "\/a\/p\/x" } ]' : OK
+Testing 'null op field must be rejected, not dereferenced', doc '{ "foo": "bar" }' patch '[ { "op": null, "path": "\/foo" } ]' : OK
+ => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Patch object 'op' field is not a string
+Testing 'null from field must be rejected, not dereferenced', doc '{ "foo": "bar" }' patch '[ { "op": "move", "from": null, "path": "\/foo" } ]' : OK
+ => json_patch_apply failed as expected: ERRNO=EINVAL at patch idx 0: Patch object 'from' field is not a string