diff --git a/libclamav/json_api.c b/libclamav/json_api.c index 3c9c2881a..088de0d62 100644 --- a/libclamav/json_api.c +++ b/libclamav/json_api.c @@ -447,6 +447,98 @@ int json_object_object_get_ex(struct json_object *obj, const char *key, struct j } #endif +/* adding an object does NOT increment reference count */ +int cli_json_addowner(json_object *owner, json_object *child, const char *key, int idx) +{ + json_type objty; + if (NULL == owner) { + cli_dbgmsg("json: no owner object specified to cli_json_addowner\n"); + return CL_ENULLARG; + } + + if (NULL == child) { + cli_dbgmsg("json: no child object specified to cli_json_addowner\n"); + return CL_ENULLARG; + } + objty = json_object_get_type(owner); + + if (objty == json_type_object) { + if (NULL == key) { + cli_dbgmsg("json: null string specified as key to cli_addowner\n"); + return CL_ENULLARG; + } + json_object_object_add(owner, key, child); + } + else if (objty == json_type_array) { + if (idx < 0 || NULL == json_object_array_get_idx(owner, idx)) + json_object_array_add(owner, child); + else if (0 != json_object_array_put_idx(owner, idx, child)) { + /* this shouldn't be possible */ + cli_dbgmsg("json: cannot delete idx %d of owner array\n", idx); + return CL_BREAK; + } + } + else { + cli_dbgmsg("json: no owner object cannot hold ownership\n"); + return CL_EARG; + } + + /* increment reference count */ + json_object_get(child); + return CL_SUCCESS; +} + +/* deleting an object DOES decrement reference count */ +int cli_json_delowner(json_object *owner, const char *key, int idx) +{ + json_type objty; + json_object *obj; + if (NULL == owner) { + cli_dbgmsg("json: no owner object specified to cli_json_delowner\n"); + return CL_ENULLARG; + } + objty = json_object_get_type(owner); + + if (objty == json_type_object) { + if (NULL == key) { + cli_dbgmsg("json: null string specified as key to cli_delowner\n"); + return CL_ENULLARG; + } + + if (!json_object_object_get_ex(owner, key, &obj)) { + cli_dbgmsg("json: owner array does not have content with key %s\n", key); + return CL_EARG; + } + + json_object_object_del(owner, key); + } + else if (objty == json_type_array) { + json_object *empty; + + if (NULL == json_object_array_get_idx(owner, idx)) { + cli_dbgmsg("json: owner array does not have content at idx %d\n", idx); + return CL_EARG; + } + + /* allocate the empty object to replace target object */ + empty = cli_jsonobj(NULL, NULL); + if (NULL == empty) + return CL_EMEM; + + if (0 != json_object_array_put_idx(owner, idx, empty)) { + /* this shouldn't be possible */ + cli_dbgmsg("json: cannot delete idx %d of owner array\n", idx); + return CL_BREAK; + } + } + else { + cli_dbgmsg("json: no owner object cannot hold ownership\n"); + return CL_EARG; + } + + return CL_SUCCESS; +} + #else int cli_json_nojson() diff --git a/libclamav/json_api.h b/libclamav/json_api.h index 4f1860623..9f901da58 100644 --- a/libclamav/json_api.h +++ b/libclamav/json_api.h @@ -46,9 +46,13 @@ int cli_jsonint(json_object *obj, const char* key, int32_t i); int cli_jsonint64(json_object *obj, const char* key, int64_t i); int cli_jsonbool(json_object *obj, const char* key, int i); int cli_jsondouble(json_object *obj, const char* key, double d); + json_object *cli_jsonarray(json_object *obj, const char *key); int cli_jsonint_array(json_object *obj, int32_t val); json_object *cli_jsonobj(json_object *obj, const char *key); +int cli_json_addowner(json_object *owner, json_object *child, const char *key, int idx); +int cli_json_delowner(json_object *owner, const char *key, int idx); +#define cli_json_delobj(obj) json_object_put(obj) #if HAVE_DEPRECATED_JSON int json_object_object_get_ex(struct json_object *obj, const char *key, struct json_object **value); @@ -87,6 +91,10 @@ int cli_jsonint_array_nojson(int32_t val); #define cli_jsondouble(o,n,d) cli_jsondouble_nojson(n,d) #define cli_jsonarray(o,k) cli_jsonarray_nojson(k) #define cli_jsonint_array(o,v) cli_jsonint_array_nojson(v) +#define cli_json_addowner(o,c,k,i) cli_json_nojson() +#define cli_json_addowner(o,k,i) cli_json_nojson() +#define cli_json_delobj(o) cli_json_nojson() + #endif #endif /*__JSON_C_H__*/ diff --git a/libclamav/scanners.c b/libclamav/scanners.c index 62d25d7a1..68bc80ebf 100644 --- a/libclamav/scanners.c +++ b/libclamav/scanners.c @@ -3694,7 +3694,7 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned free(tmpname); } } - json_object_put(ctx.properties); /* frees all json memory */ + cli_json_delobj(ctx.properties); /* frees all json memory */ #if 0 // test code - to be deleted if (cli_checktimelimit(&ctx) != CL_SUCCESS) {