Skip to content

Commit 9892e8d

Browse files
committed
all: handle properly OOM on *_create()
Fix dereferencing of malloc() on OOM conditions (NULL dereferrencing) Added OOM test and CHANGELOG entries. Reported-by: CodexGPT-5.3 <noreply@openai.com>
1 parent 2ebb88e commit 9892e8d

8 files changed

Lines changed: 121 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ Legend:
1313

1414
- [B] utils: fix `cdada_strerr()` bounds handling for invalid and negative error codes
1515
- [B] utils: add missing human-readable message for `CDADA_E_FULL`
16+
- [B] list/map/queue/set/stack: return `NULL` when constructor `malloc()` fails (avoid null dereference)
1617
- [O] tests: add coverage for `cdada_strerr()` valid, boundary and high invalid values
18+
- [O] tests: add `oom_create_test` coverage for create paths (`list`, `map`, `queue`, `set`, `stack`, `str`, `bbitmap`)
1719

1820
### v0.6.3 (28th January 2026)
1921

src/list.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ cdada_list_t* __cdada_list_create(const uint16_t val_size,
1616
return m;
1717

1818
m = (__cdada_list_int_t*)malloc(sizeof(__cdada_list_int_t));
19+
if(!m)
20+
return NULL;
1921
memset(m, 0, sizeof(__cdada_list_int_t));
2022
m->magic_num = CDADA_MAGIC;
2123
m->user_val_len = val_size;

src/map.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ cdada_map_t* __cdada_map_create(const uint16_t key_size,
1616
return m;
1717

1818
m = (__cdada_map_int_t*)malloc(sizeof(__cdada_map_int_t));
19+
if(!m)
20+
return NULL;
1921
memset(m, 0, sizeof(__cdada_map_int_t));
2022
m->magic_num = CDADA_MAGIC;
2123
m->user_key_len = key_size;

src/queue.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ cdada_queue_t* __cdada_queue_create(const uint16_t val_size,
1616
return m;
1717

1818
m = (__cdada_queue_int_t*)malloc(sizeof(__cdada_queue_int_t));
19+
if(!m)
20+
return NULL;
1921
memset(m, 0, sizeof(__cdada_queue_int_t));
2022
m->magic_num = CDADA_MAGIC;
2123
m->user_val_len = val_size;

src/set.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ cdada_set_t* __cdada_set_create(const uint16_t key_size,
1616
return m;
1717

1818
m = (__cdada_set_int_t*)malloc(sizeof(__cdada_set_int_t));
19+
if(!m)
20+
return NULL;
1921
memset(m, 0, sizeof(__cdada_set_int_t));
2022
m->magic_num = CDADA_MAGIC;
2123
m->user_key_len = key_size;

src/stack.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ cdada_stack_t* __cdada_stack_create(const uint16_t val_size,
1616
return m;
1717

1818
m = (__cdada_stack_int_t*)malloc(sizeof(__cdada_stack_int_t));
19+
if(!m)
20+
return NULL;
1921
memset(m, 0, sizeof(__cdada_stack_int_t));
2022
m->magic_num = CDADA_MAGIC;
2123
m->user_val_len = val_size;

test/Makefile.am

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ check_PROGRAMS= bbitmap_test \
88
cdada_include_test \
99
list_test \
1010
map_test \
11+
oom_create_test \
1112
queue_test \
1213
set_test \
1314
stack_test \
@@ -18,6 +19,7 @@ TESTS = bbitmap_test \
1819
cdada_include_test \
1920
list_test \
2021
map_test \
22+
oom_create_test \
2123
queue_test \
2224
set_test \
2325
stack_test \
@@ -40,6 +42,10 @@ map_test_SOURCES= map_test.c map_custom.cc
4042
map_test_CPPFLAGS= -I$(top_builddir)/include/ -I$(top_srcdir)/include/
4143
map_test_LDADD= -lpthread ../src/libcdada.la
4244

45+
oom_create_test_SOURCES= oom_create_test.c
46+
oom_create_test_CPPFLAGS= -I$(top_builddir)/include/ -I$(top_srcdir)/include/
47+
oom_create_test_LDADD= -lpthread ../src/libcdada.la
48+
4349
queue_test_SOURCES= queue_test.c queue_custom.cc
4450
queue_test_CPPFLAGS= -I$(top_builddir)/include/ -I$(top_srcdir)/include/
4551
queue_test_LDADD= -lpthread ../src/libcdada.la

test/oom_create_test.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
4+
#include "cdada/bbitmap.h"
5+
#include "cdada/list.h"
6+
#include "cdada/map.h"
7+
#include "cdada/queue.h"
8+
#include "cdada/set.h"
9+
#include "cdada/stack.h"
10+
#include "cdada/str.h"
11+
#include "common.h"
12+
13+
static int g_fail_next_malloc = 0;
14+
15+
#ifdef __GLIBC__
16+
extern void* __libc_malloc(size_t size);
17+
18+
void* malloc(size_t size){
19+
if(g_fail_next_malloc){
20+
g_fail_next_malloc = 0;
21+
return NULL;
22+
}
23+
return __libc_malloc(size);
24+
}
25+
#endif
26+
27+
int main(int argc, char** argv){
28+
cdada_list_t* list;
29+
cdada_map_t* map;
30+
cdada_queue_t* queue;
31+
cdada_set_t* set;
32+
cdada_stack_t* stack;
33+
cdada_str_t* str;
34+
cdada_bbitmap_t* bbitmap;
35+
36+
(void)argc;
37+
(void)argv;
38+
39+
g_fail_next_malloc = 0;
40+
list = cdada_list_create(uint32_t);
41+
TEST_ASSERT(list != NULL);
42+
TEST_ASSERT(cdada_list_destroy(list) == CDADA_SUCCESS);
43+
44+
g_fail_next_malloc = 1;
45+
list = cdada_list_create(uint32_t);
46+
TEST_ASSERT(list == NULL);
47+
48+
g_fail_next_malloc = 0;
49+
map = cdada_map_create(uint32_t);
50+
TEST_ASSERT(map != NULL);
51+
TEST_ASSERT(cdada_map_destroy(map) == CDADA_SUCCESS);
52+
53+
g_fail_next_malloc = 1;
54+
map = cdada_map_create(uint32_t);
55+
TEST_ASSERT(map == NULL);
56+
57+
g_fail_next_malloc = 0;
58+
queue = cdada_queue_create(uint32_t);
59+
TEST_ASSERT(queue != NULL);
60+
TEST_ASSERT(cdada_queue_destroy(queue) == CDADA_SUCCESS);
61+
62+
g_fail_next_malloc = 1;
63+
queue = cdada_queue_create(uint32_t);
64+
TEST_ASSERT(queue == NULL);
65+
66+
g_fail_next_malloc = 0;
67+
set = cdada_set_create(uint32_t);
68+
TEST_ASSERT(set != NULL);
69+
TEST_ASSERT(cdada_set_destroy(set) == CDADA_SUCCESS);
70+
71+
g_fail_next_malloc = 1;
72+
set = cdada_set_create(uint32_t);
73+
TEST_ASSERT(set == NULL);
74+
75+
g_fail_next_malloc = 0;
76+
stack = cdada_stack_create(uint32_t);
77+
TEST_ASSERT(stack != NULL);
78+
TEST_ASSERT(cdada_stack_destroy(stack) == CDADA_SUCCESS);
79+
80+
g_fail_next_malloc = 1;
81+
stack = cdada_stack_create(uint32_t);
82+
TEST_ASSERT(stack == NULL);
83+
84+
g_fail_next_malloc = 0;
85+
str = cdada_str_create("oom");
86+
TEST_ASSERT(str != NULL);
87+
TEST_ASSERT(cdada_str_destroy(str) == CDADA_SUCCESS);
88+
89+
g_fail_next_malloc = 1;
90+
str = cdada_str_create("oom");
91+
TEST_ASSERT(str == NULL);
92+
93+
g_fail_next_malloc = 0;
94+
bbitmap = cdada_bbitmap_create(64);
95+
TEST_ASSERT(bbitmap != NULL);
96+
TEST_ASSERT(cdada_bbitmap_destroy(bbitmap) == CDADA_SUCCESS);
97+
98+
g_fail_next_malloc = 1;
99+
bbitmap = cdada_bbitmap_create(64);
100+
TEST_ASSERT(bbitmap == NULL);
101+
102+
return EXIT_SUCCESS;
103+
}

0 commit comments

Comments
 (0)