json_pointer: find null array elements

json_pointer_get_single_path() returned ENOENT when the array element
at an in-range index was NULL, which is how json-c stores a JSON null.
A null object member was already found, but on [0, null, 2] "/1" failed
with "not found", although RFC 6901 says it references the null value.

The array index is bounds-checked just before, so a NULL element now
resolves like a null member: json_pointer_get() returns 0 and sets
*res to NULL. This also fixes json_patch_apply(), which failed every
"test", "replace" and "remove" on a null array element, and every
"move" and "copy" from one, with "Did not find element referenced by
path field".

Added a json_pointer_get() test, and json_patch_tests.json cases that
mirror the existing null object member ones.
This commit is contained in:
Wleeaf authored and Eric Hawicz committed 2026-10-26 00:39:03 -04:00
1 parent 86fe287188
commit d9b375ff1b
5 files changed
+47 -10

No files matched your search

+5
View File
@@ -89,6 +89,11 @@ Testing 'null value should be valid obj property to be moved', doc '{ "foo": nul
Testing 'null value should be valid obj property to be copied', doc '{ "foo": null }' patch '[ { "op": "copy", "from": "\/foo", "path": "\/bar" } ]' : OK
Testing 'null value should be valid obj property to be removed', doc '{ "foo": null }' patch '[ { "op": "remove", "path": "\/foo" } ]' : OK
Testing 'null value should still be valid obj property replace other value', doc '{ "foo": "bar" }' patch '[ { "op": "replace", "path": "\/foo", "value": null } ]' : OK
Testing 'null value should be valid array element', doc '{ "foo": [ null ] }' patch '[ { "op": "test", "path": "\/foo\/0", "value": null } ]' : OK
Testing 'null value should be valid array element to be replaced with something truthy', doc '{ "foo": [ null ] }' patch '[ { "op": "replace", "path": "\/foo\/0", "value": "truthy" } ]' : OK
Testing 'null value should be valid array element to be moved', doc '{ "foo": [ null, 1 ] }' patch '[ { "op": "move", "from": "\/foo\/0", "path": "\/bar" } ]' : OK
Testing 'null value should be valid array element to be copied', doc '{ "foo": [ null ] }' patch '[ { "op": "copy", "from": "\/foo\/0", "path": "\/foo\/-" } ]' : OK
Testing 'null value should be valid array element to be removed', doc '{ "foo": [ null, 1 ] }' patch '[ { "op": "remove", "path": "\/foo\/0" } ]' : OK
Testing 'test should pass despite rearrangement', doc '{ "foo": { "foo": 1, "bar": 2 } }' patch '[ { "op": "test", "path": "\/foo", "value": { "bar": 2, "foo": 1 } } ]' : OK
Testing 'test should pass despite (nested) rearrangement', doc '{ "foo": [ { "foo": 1, "bar": 2 } ] }' patch '[ { "op": "test", "path": "\/foo", "value": [ { "bar": 2, "foo": 1 } ] } ]' : OK
Testing 'test should pass - no error', doc '{ "foo": { "bar": [ 1, 2, 5, 4 ] } }' patch '[ { "op": "test", "path": "\/foo", "value": { "bar": [ 1, 2, 5, 4 ] } } ]' : OK