From fb15583ce89edd4826fa22a2dbe7af09dfafccab Mon Sep 17 00:00:00 2001 From: yangchenguang Date: Tue, 13 Sep 2022 15:42:52 +0800 Subject: [PATCH] Fix memory leak with emtpy strings in json_object_set_string and add test --- Add-test-to-check-for-the-memory-leak.patch | 32 +++++++++ ...py-strings-in-json_object_set_string.patch | 69 +++++++++++++++++++ json-c.spec | 7 +- 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 Add-test-to-check-for-the-memory-leak.patch create mode 100644 Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch diff --git a/Add-test-to-check-for-the-memory-leak.patch b/Add-test-to-check-for-the-memory-leak.patch new file mode 100644 index 0000000..549bbe5 --- /dev/null +++ b/Add-test-to-check-for-the-memory-leak.patch @@ -0,0 +1,32 @@ +From 16208fc01afcd742fd5e6736f52849ad2ec03e8f Mon Sep 17 00:00:00 2001 +From: Eric Haszlakiewicz +Date: Sun, 24 Jul 2022 18:59:26 +0000 +Subject: [PATCH] Add test to check for the memory leak mentioned in + issue #781 + +--- + tests/test_set_value.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/tests/test_set_value.c b/tests/test_set_value.c +index f51a2a5..a8ebbfe 100644 +--- a/tests/test_set_value.c ++++ b/tests/test_set_value.c +@@ -71,6 +71,14 @@ int main(int argc, char **argv) + json_object_set_string(tmp, SHORT); + assert(strcmp(json_object_get_string(tmp), SHORT) == 0); + assert(strcmp(json_object_to_json_string(tmp), "\"" SHORT "\"") == 0); ++ ++ // Set an empty string a couple times to try to trigger ++ // a case that used to leak memory. ++ json_object_set_string(tmp, ""); ++ json_object_set_string(tmp, HUGE); ++ json_object_set_string(tmp, ""); ++ json_object_set_string(tmp, HUGE); ++ + json_object_put(tmp); + printf("STRING PASSED\n"); + +-- +2.20.1 + diff --git a/Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch b/Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch new file mode 100644 index 0000000..5821404 --- /dev/null +++ b/Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch @@ -0,0 +1,69 @@ +From 213bb5caa11ed2182848d86c86f8e9ab4c75642a Mon Sep 17 00:00:00 2001 +From: Daniel Danzberger +Date: Sun, 24 Jul 2022 18:46:03 +0200 +Subject: [PATCH] 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 + +--- + json_object.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/json_object.c b/json_object.c +index 3216941..a01f8f7 100644 +--- a/json_object.c ++++ b/json_object.c +@@ -1335,11 +1335,18 @@ static int _json_object_set_string_len(json_object *jso, const char *s, size_t l + // full size_t range. + 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) + { +-- +2.33.0 + diff --git a/json-c.spec b/json-c.spec index c85b7b6..b337348 100644 --- a/json-c.spec +++ b/json-c.spec @@ -6,7 +6,7 @@ Name: json-c Version: 0.15 -Release: 5 +Release: 6 Summary: JSON implementation in C License: MIT @@ -28,6 +28,8 @@ Summary: Development files for %{name} Requires: %{name}%{?_isa} == %{version}-%{release} Patch6001: backport-json-escape-str-avoid-harmless-unsigned-integer-overflow.patch +Patch6002: Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch +Patch6003: Add-test-to-check-for-the-memory-leak.patch %description devel This package contains libraries and header files for @@ -105,6 +107,9 @@ end %doc %{_pkgdocdir} %changelog +* Tue Sep 13 2022 yangchenguang - 0.15-6 +- Fix memory leak with emtpy strings in json_object_set_string and add test + * Tue May 24 2022 fengtao - 0.15-5 - we got upgrade error when upgrade json-c from very low version, for example json-c-0.11-5. because old version has a softlink: -- Gitee