mirror of
https://github.com/json-c/json-c.git
synced 2026-09-07 08:36:50 +08:00
Merge pull request #961 from dxbjavid/pointer-set-unescape
decode ~1/~0 escapes when setting an object member in json_pointer
This commit is contained in:
+18
-9
@@ -141,19 +141,28 @@ static int json_pointer_set_single_path(struct json_object *parent, const char *
|
|||||||
return set_cb(parent, NULL, idx, value, priv);
|
return set_cb(parent, NULL, idx, value, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* path replacements should have been done in json_pointer_get_single_path(),
|
|
||||||
* and we should still be good here
|
|
||||||
*/
|
|
||||||
if (json_object_is_type(parent, json_type_object))
|
if (json_object_is_type(parent, json_type_object))
|
||||||
{
|
{
|
||||||
|
/* Unlike the getter, which decodes the reference token in
|
||||||
|
* json_pointer_get_single_path(), nothing had decoded the '~1'/'~0'
|
||||||
|
* escapes on the way here, so a member whose name contains '/' or '~'
|
||||||
|
* was addressed under its still-escaped spelling. Decode a copy per
|
||||||
|
* RFC 6901 (first '~1' then '~0') before using it as the key.
|
||||||
|
*/
|
||||||
|
char *key = strdup(path);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (key == NULL)
|
||||||
|
return -1;
|
||||||
|
string_replace_all_occurrences_with_char(key, "~1", '/');
|
||||||
|
string_replace_all_occurrences_with_char(key, "~0", '~');
|
||||||
|
|
||||||
if (cb_handles_obj)
|
if (cb_handles_obj)
|
||||||
{
|
rc = set_cb(parent, key, (size_t)-1, value, priv);
|
||||||
return set_cb(parent, path, (size_t)-1, value, priv);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
rc = json_object_object_add(parent, key, value);
|
||||||
return json_object_object_add(parent, path, value);
|
free(key);
|
||||||
}
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Getting here means that we tried to "dereference" a primitive JSON type
|
/* Getting here means that we tried to "dereference" a primitive JSON type
|
||||||
|
|||||||
@@ -268,6 +268,25 @@ static void test_example_set(void)
|
|||||||
printf("PASSED - SET - Final JSON is: %s\n", json_object_get_string(jo1));
|
printf("PASSED - SET - Final JSON is: %s\n", json_object_get_string(jo1));
|
||||||
json_object_put(jo2);
|
json_object_put(jo2);
|
||||||
|
|
||||||
|
/* RFC 6901 escapes must be decoded on the set path too, just as the
|
||||||
|
* getter does, so "/a~1b" addresses the member "a/b" and "/m~0n"
|
||||||
|
* addresses "m~n" rather than creating keys spelled "a~1b"/"m~0n". */
|
||||||
|
{
|
||||||
|
struct json_object *esc = json_tokener_parse("{ 'a/b': 1, 'm~n': 2 }");
|
||||||
|
struct json_object *v = NULL;
|
||||||
|
assert(0 == json_pointer_set(&esc, "/a~1b", json_object_new_int(11)));
|
||||||
|
assert(0 == json_pointer_setf(&esc, json_object_new_int(22), "/m~0n"));
|
||||||
|
assert(0 == json_pointer_get(esc, "/a~1b", &v));
|
||||||
|
assert(11 == json_object_get_int(v));
|
||||||
|
assert(0 == json_pointer_get(esc, "/m~0n", &v));
|
||||||
|
assert(22 == json_object_get_int(v));
|
||||||
|
assert(NULL == json_object_object_get(esc, "a~1b"));
|
||||||
|
assert(NULL == json_object_object_get(esc, "m~0n"));
|
||||||
|
assert(2 == json_object_object_length(esc));
|
||||||
|
printf("PASSED - SET - escaped keys /a~1b and /m~0n\n");
|
||||||
|
json_object_put(esc);
|
||||||
|
}
|
||||||
|
|
||||||
assert(0 == json_pointer_set(&jo1, "", json_object_new_int(10)));
|
assert(0 == json_pointer_set(&jo1, "", json_object_new_int(10)));
|
||||||
assert(10 == json_object_get_int(jo1));
|
assert(10 == json_object_get_int(jo1));
|
||||||
printf("%s\n", json_object_get_string(jo1));
|
printf("%s\n", json_object_get_string(jo1));
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ PASSED - SET - /fug/gaw == [0,2,3]
|
|||||||
PASSED - SET - /fug/gaw == [0,2,3,4]
|
PASSED - SET - /fug/gaw == [0,2,3,4]
|
||||||
PASSED - SET - / == 9
|
PASSED - SET - / == 9
|
||||||
PASSED - SET - Final JSON is: { "foo": [ "bar", "cod" ], "": 9, "a\/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8, "fud": { "gaw": [ 0, 2, 3, 4 ] } }
|
PASSED - SET - Final JSON is: { "foo": [ "bar", "cod" ], "": 9, "a\/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8, "fud": { "gaw": [ 0, 2, 3, 4 ] } }
|
||||||
|
PASSED - SET - escaped keys /a~1b and /m~0n
|
||||||
10
|
10
|
||||||
PASSED - SET - LOADED TEST JSON
|
PASSED - SET - LOADED TEST JSON
|
||||||
{ "foo": [ "bar", "baz" ], "": 0, "a\/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 }
|
{ "foo": [ "bar", "baz" ], "": 0, "a\/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8 }
|
||||||
|
|||||||
Reference in New Issue
Block a user