From d729e7a2d0cab3d30cac014c7d311fa8439cfe40 Mon Sep 17 00:00:00 2001 From: PengZheng Date: Thu, 22 Feb 2024 16:28:00 +0800 Subject: [PATCH] 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 edf560fca..6e6744091 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 cf5c80560..533ed7c57 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 399bb7663..0431da8f1 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 e2582fae1..26382172e 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;