mirror of
https://github.com/json-c/json-c.git
synced 2026-03-16 11:39:07 +08:00
- Changed json_pointer_set_with_array_cb to json_pointer_set_with_cb, related cb updated - Added tests(test_safe_json_pointer_set.*) for new-exported funcs, also updated cmake & meson Signed-off-by: lone <lonechan314@qq.com>
189 lines
7.8 KiB
C
189 lines
7.8 KiB
C
/*
|
|
* Copyright (c) 2016 Alexadru Ardelean.
|
|
*
|
|
* This is free software; you can redistribute it and/or modify
|
|
* it under the terms of the MIT license. See COPYING for details.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief JSON Pointer (RFC 6901) implementation for retrieving
|
|
* objects from a json-c object tree.
|
|
*/
|
|
#ifndef _json_pointer_h_
|
|
#define _json_pointer_h_
|
|
|
|
#include "json_object.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* Retrieves a JSON sub-object from inside another JSON object
|
|
* using the JSON pointer notation as defined in RFC 6901
|
|
* https://tools.ietf.org/html/rfc6901
|
|
*
|
|
* The returned JSON sub-object is equivalent to parsing manually the
|
|
* 'obj' JSON tree ; i.e. it's not a new object that is created, but rather
|
|
* a pointer inside the JSON tree.
|
|
*
|
|
* Internally, this is equivalent to doing a series of 'json_object_object_get()'
|
|
* and 'json_object_array_get_idx()' along the given 'path'.
|
|
*
|
|
* @param obj the json_object instance/tree from where to retrieve sub-objects
|
|
* @param path a (RFC6901) string notation for the sub-object to retrieve
|
|
* @param res a pointer that stores a reference to the json_object
|
|
* associated with the given path
|
|
*
|
|
* @return negative if an error (or not found), or 0 if succeeded
|
|
*/
|
|
JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path,
|
|
struct json_object **res);
|
|
|
|
/**
|
|
* This is a variant of 'json_pointer_get()' that supports printf() style arguments.
|
|
*
|
|
* Variable arguments go after the 'path_fmt' parameter.
|
|
*
|
|
* Example: json_pointer_getf(obj, res, "/foo/%d/%s", 0, "bar")
|
|
* This also means that you need to escape '%' with '%%' (just like in printf())
|
|
*
|
|
* Please take into consideration all recommended 'printf()' format security
|
|
* aspects when using this function.
|
|
*
|
|
* @param obj the json_object instance/tree to which to add a sub-object
|
|
* @param res a pointer that stores a reference to the json_object
|
|
* associated with the given path
|
|
* @param path_fmt a printf() style format for the path
|
|
*
|
|
* @return negative if an error (or not found), or 0 if succeeded
|
|
*/
|
|
JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res,
|
|
const char *path_fmt, ...);
|
|
|
|
/**
|
|
* Sets JSON object 'value' in the 'obj' tree at the location specified
|
|
* by the 'path'. 'path' is JSON pointer notation as defined in RFC 6901
|
|
* https://tools.ietf.org/html/rfc6901
|
|
*
|
|
* Note that 'obj' is a double pointer, mostly for the "" (empty string)
|
|
* case, where the entire JSON object would be replaced by 'value'.
|
|
* In the case of the "" path, the object at '*obj' will have it's refcount
|
|
* decremented with 'json_object_put()' and the 'value' object will be assigned to it.
|
|
*
|
|
* For other cases (JSON sub-objects) ownership of 'value' will be transferred into
|
|
* '*obj' via 'json_object_object_add()' & 'json_object_array_put_idx()', so the
|
|
* only time the refcount should be decremented for 'value' is when the return value of
|
|
* 'json_pointer_set()' is negative (meaning the 'value' object did not get set into '*obj').
|
|
*
|
|
* That also implies that 'json_pointer_set()' does not do any refcount incrementing.
|
|
* (Just that single decrement that was mentioned above).
|
|
*
|
|
* @warning This function is vulnerable to an OOM.
|
|
* To prevent this, use the safer variant 'json_pointer_set_with_limit_index()'
|
|
* or the flexible 'json_pointer_set_with_array_cb()' with a custom callback.
|
|
*
|
|
* @param obj the json_object instance/tree to which to add a sub-object
|
|
* @param path a (RFC6901) string notation for the sub-object to set in the tree
|
|
* @param value object to set at path
|
|
*
|
|
* @return negative if an error (or not found), or 0 if succeeded
|
|
*/
|
|
JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path,
|
|
struct json_object *value);
|
|
|
|
/**
|
|
* This is a variant of 'json_pointer_set()' that supports printf() style arguments.
|
|
*
|
|
* Variable arguments go after the 'path_fmt' parameter.
|
|
*
|
|
* Example: json_pointer_setf(obj, value, "/foo/%d/%s", 0, "bar")
|
|
* This also means that you need to escape '%' with '%%' (just like in printf())
|
|
*
|
|
* Please take into consideration all recommended 'printf()' format security
|
|
* aspects when using this function.
|
|
*
|
|
* @param obj the json_object instance/tree to which to add a sub-object
|
|
* @param value object to set at path
|
|
* @param path_fmt a printf() style format for the path
|
|
*
|
|
* @return negative if an error (or not found), or 0 if succeeded
|
|
*/
|
|
JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value,
|
|
const char *path_fmt, ...);
|
|
|
|
/**
|
|
* A convenient and safe variant of 'json_pointer_set()' that prevents excessive memory allocations
|
|
* by enforcing a limit on array indices.
|
|
*
|
|
* @param obj the json_object instance/tree to which to add a sub-object
|
|
* @param path a (RFC6901) string notation for the sub-object to set in the tree
|
|
* @param value object to set at path
|
|
* @param limit_index The maximum allowed value for an array index. If a path
|
|
* contains an index larger than this, the function will fail
|
|
* with errno set to EINVAL. A value of -1 can be used to specify
|
|
* no limit, reverting to the original behavior
|
|
*
|
|
* @return negative if an error (or not found), or 0 if succeeded
|
|
*/
|
|
JSON_EXPORT int json_pointer_set_with_limit_index(struct json_object **obj, const char *path,
|
|
struct json_object *value, size_t limit_index);
|
|
|
|
/**
|
|
* Callback function type.
|
|
*
|
|
* When setting an array element, 'key' will be NULL and 'idx' will be the
|
|
* target index.
|
|
* When setting an object field, 'key' will be the target key and 'idx' will
|
|
* be -1.
|
|
*/
|
|
typedef int(*json_pointer_set_cb)(json_object *parent, const char *key, size_t idx,
|
|
json_object *value, void *priv);
|
|
|
|
/**
|
|
* Variant of 'json_pointer_set()' that allows specifying a custom callback
|
|
*
|
|
* @param obj the json_object instance/tree to which to add a sub-object
|
|
* @param path a (RFC6901) string notation for the sub-object to set in the tree
|
|
* @param value object to set at path
|
|
* @param set_cb A custom callback function to handle setting the element
|
|
* @param cb_handles_obj If 0, the callback is only invoked for array modifications.
|
|
* If 1, the callback is invoked for both array and object
|
|
* modifications.
|
|
* @param priv A private pointer passed through to the set_cb callback,
|
|
* for user-defined context
|
|
*
|
|
* @return negative if an error (or not found), or 0 if succeeded
|
|
*/
|
|
JSON_EXPORT int json_pointer_set_with_cb(struct json_object **obj, const char *path,
|
|
struct json_object *value,
|
|
json_pointer_set_cb set_cb, int cb_handles_obj, void *priv);
|
|
|
|
/**
|
|
* A safer callback for 'json_pointer_set_with_cb()' that enforces a
|
|
* maximum array index.
|
|
*
|
|
* This function can be used as the 'set_cb' argument to prevent OOM.
|
|
* It expects the 'priv' argument to be a valid pointer to a 'size_t' variable
|
|
* that holds the maximum allowed index.
|
|
*
|
|
* @param jso the parent json_object array.
|
|
* @param key the object field where the element is to be placed, should be NULL here.
|
|
* @param idx the index where the element is to be placed.
|
|
* @param jso_new the new json_object to place at the index.
|
|
* @param priv A pointer to a 'size_t' variable specifying the maximum index.
|
|
* This pointer must not be NULL.
|
|
*
|
|
* @return 0 on success, or a negative value if idx exceeds the limit or 'priv' is NULL.
|
|
*/
|
|
JSON_EXPORT int json_object_array_put_with_idx_limit_cb(struct json_object *jso, const char *key, size_t idx,
|
|
struct json_object *jso_new, void *priv);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|