This is an automated email from the ASF dual-hosted git repository.

pengzheng pushed a commit to branch hotfix/730-realloc-leak-fix
in repository https://gitbox.apache.org/repos/asf/celix.git

commit d729e7a2d0cab3d30cac014c7d311fa8439cfe40
Author: PengZheng <[email protected]>
AuthorDate: Thu Feb 22 16:28:00 2024 +0800

    gh-730: Fix leaks caused by realloc failure.
---
 .../src/endpoint_discovery_poller.c                | 11 +++++----
 libs/dfi/gtest/src/dyn_type_ei_tests.cc            | 28 ++++++++++++++++++++++
 libs/dfi/src/dyn_type.c                            |  6 ++---
 libs/etcdlib/src/etcd.c                            | 11 +++++----
 4 files changed, 43 insertions(+), 13 deletions(-)

diff --git 
a/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c 
b/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c
index edf560fc..6e674409 100644
--- a/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c
+++ b/bundles/remote_services/discovery_common/src/endpoint_discovery_poller.c
@@ -339,11 +339,12 @@ static size_t endpointDiscoveryPoller_writeMemory(void 
*contents, size_t size, s
        size_t realsize = size * nmemb;
        struct MemoryStruct *mem = (struct MemoryStruct *)memoryPtr;
 
-       mem->memory = realloc(mem->memory, mem->size + realsize + 1);
-       if(mem->memory == NULL) {
-               printf("ENDPOINT_POLLER: not enough memory (realloc returned 
NULL)!");
-               return 0;
-       }
+    void* newMem = realloc(mem->memory, mem->size + realsize + 1);
+    if (newMem == NULL) {
+        printf("ENDPOINT_POLLER: not enough memory (realloc returned NULL)!");
+        return 0;
+    }
+    mem->memory = newMem;
 
        memcpy(&(mem->memory[mem->size]), contents, realsize);
        mem->size += realsize;
diff --git a/libs/dfi/gtest/src/dyn_type_ei_tests.cc 
b/libs/dfi/gtest/src/dyn_type_ei_tests.cc
index cf5c8056..533ed7c5 100644
--- a/libs/dfi/gtest/src/dyn_type_ei_tests.cc
+++ b/libs/dfi/gtest/src/dyn_type_ei_tests.cc
@@ -173,6 +173,34 @@ TEST_F(DynTypeErrorInjectionTestSuite, 
SequenceReserveError) {
     dynType_destroy(type);
 }
 
+TEST_F(DynTypeErrorInjectionTestSuite, SequenceReserveError2) {
+    struct double_sequence {
+        uint32_t cap;
+        uint32_t len;
+        double* buf;
+    };
+
+    dyn_type *type = NULL;
+    int rc = 0;
+    rc = dynType_parseWithStr("[D", NULL, NULL, &type);
+    ASSERT_EQ(0, rc);
+
+    struct double_sequence *seq = NULL;
+    rc = dynType_alloc(type, (void **)&seq);
+    ASSERT_EQ(0, rc);
+    ASSERT_TRUE(seq != NULL);
+
+    celix_ei_expect_realloc((void*)dynType_sequence_reserve, 0, nullptr, 2);
+    rc = dynType_sequence_reserve(type, seq, 1);
+    ASSERT_EQ(0, rc);
+    rc = dynType_sequence_reserve(type, seq, 2);
+    ASSERT_NE(0, rc);
+    ASSERT_STREQ("Error allocating memory for seq buf", 
celix_err_popLastError());
+
+    dynType_free(type, seq);
+    dynType_destroy(type);
+}
+
 TEST_F(DynTypeErrorInjectionTestSuite, TextAllocateError) {
     dyn_type *type = NULL;
     int rc = 0;
diff --git a/libs/dfi/src/dyn_type.c b/libs/dfi/src/dyn_type.c
index 399bb766..0431da8f 100644
--- a/libs/dfi/src/dyn_type.c
+++ b/libs/dfi/src/dyn_type.c
@@ -604,12 +604,12 @@ int dynType_sequence_reserve(const dyn_type* type, void* 
inst, uint32_t cap) {
         return OK;
     }
     size_t size = dynType_size(type->sequence.itemType);
-    seq->buf = realloc(seq->buf, (size_t)(cap * size));
-    if (seq->buf == NULL) {
-        seq->cap = 0;
+    void* newBuf = realloc(seq->buf, (size_t)(cap * size));
+    if (newBuf == NULL) {
         celix_err_pushf("Error allocating memory for seq buf");
         return MEM_ERROR;
     }
+    seq->buf = newBuf;
     memset(seq->buf+seq->cap*size, 0, (cap-seq->cap)*size);
     seq->cap = cap;
     return status;
diff --git a/libs/etcdlib/src/etcd.c b/libs/etcdlib/src/etcd.c
index e2582fae..26382172 100644
--- a/libs/etcdlib/src/etcd.c
+++ b/libs/etcdlib/src/etcd.c
@@ -637,12 +637,12 @@ static size_t WriteMemoryCallback(void *contents, size_t 
size, size_t nmemb, voi
     size_t realsize = size * nmemb;
     struct MemoryStruct *mem = (struct MemoryStruct *) userp;
 
-    mem->memory = realloc(mem->memory, mem->memorySize + realsize + 1);
-    if (mem->memory == NULL) {
-        /* out of memory! */
+    void* newMem = realloc(mem->memory, mem->memorySize + realsize + 1);
+    if (newMem == NULL) {
         fprintf(stderr, "[ETCDLIB] Error: not enough memory (realloc returned 
NULL)\n");
         return 0;
     }
+    mem->memory = newMem;
 
     memcpy(&(mem->memory[mem->memorySize]), contents, realsize);
     mem->memorySize += realsize;
@@ -655,12 +655,13 @@ static size_t WriteHeaderCallback(void *contents, size_t 
size, size_t nmemb, voi
     size_t realsize = size * nmemb;
     struct MemoryStruct *mem = (struct MemoryStruct *) userp;
 
-    mem->header = realloc(mem->header, mem->headerSize + realsize + 1);
-    if (mem->header == NULL) {
+    void* newHeader = realloc(mem->header, mem->headerSize + realsize + 1);
+    if (newHeader == NULL) {
         /* out of memory! */
         fprintf(stderr, "[ETCDLIB] Error: not enough header-memory (realloc 
returned NULL)\n");
         return 0;
     }
+    mem->header = newHeader;
 
     memcpy(&(mem->header[mem->headerSize]), contents, realsize);
     mem->headerSize += realsize;

Reply via email to