summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Danzberger <daniel@dd-wrt.com>2022-07-24 18:46:03 +0200
committerDaniel Danzberger <daniel@dd-wrt.com>2022-07-24 19:03:49 +0200
commit213bb5caa11ed2182848d86c86f8e9ab4c75642a (patch)
tree7db2ba90458a360670b2b050e6fb8b026fc59b3c
parentd28ac67dde77566f53a97f22b4ea7cb36afe6582 (diff)
downloadjson-c-213bb5caa11ed2182848d86c86f8e9ab4c75642a.tar.gz
Fix memory leak with emtpy strings in json_object_set_string
When a json string object is updated with a bigger string, a new malloc'ed buffer is used to store the new string and it's size is made negative to indicate that an external buffer is in use. When that same json string object get's updated again with an empty stirng (size = 0), the new external malloc'ed buffer is still used. But the fact that the new size value is not negative removes the indicator that the externally malloc'ed buffer is used. This becomes a problem when the object get's updated again with any other string, because a new buffer will be malloced and linked to the object while to old one won't be free'd. This causes a memory leak when updating a json string with json_object_set_stirng() which has previously been updated with an empty string. Example: -- obj = json_object_new_string("data"); json_object_set_string(obj, "more data"); json_object_set_string(obj, ""); json_object_set_string(obj, "other data"); /* leaks */ -- This commit fixes the issue by free'ing the external buffer when an empty string is set and use the internal one again. Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
-rw-r--r--json_object.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/json_object.c b/json_object.c
index e52ca40..581b1e2 100644
--- a/json_object.c
+++ b/json_object.c
@@ -1323,11 +1323,18 @@ static int _json_object_set_string_len(json_object *jso, const char *s, size_t l
// length as int, cap length at INT_MAX.
return 0;
- dstbuf = get_string_component_mutable(jso);
curlen = JC_STRING(jso)->len;
- if (curlen < 0)
- curlen = -curlen;
+ if (curlen < 0) {
+ if (len == 0) {
+ free(JC_STRING(jso)->c_string.pdata);
+ JC_STRING(jso)->len = curlen = 0;
+ } else {
+ curlen = -curlen;
+ }
+ }
+
newlen = len;
+ dstbuf = get_string_component_mutable(jso);
if ((ssize_t)len > curlen)
{