Skip to content

Commit 9afe2fc

Browse files
committed
Merge remote-tracking branch 'origin/master' into gh-pages
2 parents 9fb3671 + 81d9bcb commit 9afe2fc

22 files changed

Lines changed: 266 additions & 34 deletions

.github/workflows/test_script.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ echo "Building out-tree"
2020
cd build
2121
../configure $CONFIG_FLAGS || (cat config.log && /bin/false)
2222
make check || ((for f in `find test/ -name "*.log"`; do cat $f; done;) && /bin/false)
23+
echo "Running oom_create_test without valgrind..."
24+
./test/oom_create_test
2325
2426
echo "Running examples..."
2527
valgrind --leak-check=full examples/bbitmap

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,30 @@ Legend:
99
- [O] Other
1010
```
1111

12+
### v0.6.4 (27th February 2026)
13+
14+
- [B] utils: fix `cdada_strerr()` bounds handling for invalid and negative error codes
15+
- [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)
17+
- [B] str: fix `cdada_str_replace*()` to reject empty match and self-replacement issues
18+
- [B] str: return `NULL` in `cdada_str_create()` when input C string is `NULL`
19+
- [B] str: align `cdada_str()` invalid-handle behavior with API docs (return `NULL`, not empty string)
20+
- [B] bbitmap: make `cdada_bbitmap_dump()` set `size_used` in buffered paths too
21+
- [B] bbitmap: fix corrupted BSD license header in `bbitmap.h`
22+
- [B] str: fix underflow in `cdada_str_rtraverse()` on empty strings
23+
- [B] list: fix `cdada_list_first()`/`cdada_list_last()` returning `CDADA_SUCCESS` on invalid input
24+
- [B] set: fix `cdada_set_find()` returning `true` on internal error
25+
- [B] str: fix uint32_t overflow in `cdada_str_erase()` bounds check
26+
- [B] str: fix `cdada_str_find_count()`/`cdada_str_find_all()` not returning `CDADA_E_NOT_FOUND`
27+
- [B] str: reject empty `substr` in `cdada_str_find_count()`/`cdada_str_find_all()`
28+
- [B] list/map/queue/set/stack: report `size_used` as bytes written on incomplete `dump()`
29+
- [O] tests: add coverage for `cdada_strerr()` valid, boundary and high invalid values
30+
- [O] tests: add `oom_create_test` coverage for create paths (`list`, `map`, `queue`, `set`, `stack`, `str`, `bbitmap`)
31+
- [O] tests: add coverage for `cdada_str_replace_all()` empty-match invalid input and self-overlap replacement
32+
- [O] tests: add `cdada_str_create(NULL)` regression coverage
33+
- [O] tests: align invalid `cdada_str()` assertion with documented `NULL` return
34+
- [O] tests: validate `cdada_bbitmap_dump()` updates `size_used` for both incomplete and complete buffered dumps
35+
1236
### v0.6.3 (28th January 2026)
1337

1438
- [O] tests/CI: fixed compilation with GCC 16 (thanks A. Stieger). Added CI coverage for GCC 15.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.6.3
1+
v0.6.4

include/cdada/bbitmap.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
Copyright (c) 2020, Marc Sune Clos
33
All rights reserved.
44
5-
Redibbitmapibution and use in source and binary forms, with or without
5+
Redistribution and use in source and binary forms, with or without
66
modification, are permitted provided that the following conditions are met:
77
8-
* Redibbitmapibutions of source code must retain the above copyright notice, this
8+
* Redistributions of source code must retain the above copyright notice, this
99
list of conditions and the following disclaimer.
1010
11-
* Redibbitmapibutions in binary form must reproduce the above copyright notice,
11+
* Redistributions in binary form must reproduce the above copyright notice,
1212
this list of conditions and the following disclaimer in the documentation
13-
and/or other materials provided with the dibbitmapibution.
13+
and/or other materials provided with the distribution.
1414
1515
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1616
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

src/bbitmap.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,16 @@ int cdada_bbitmap_dump(cdada_bbitmap_t* b, uint32_t size, char* buffer,
112112
std::stringstream ss;
113113
for(i=0;i<b->n_words; ++i)
114114
__cdada_bbitmap_dump_word(i, &b->ptr[i], ss);
115+
*size_used = ss.str().length()+1;
115116

116-
if(!buffer){
117-
*size_used = ss.str().length()+1;
117+
if(!buffer)
118118
return CDADA_SUCCESS;
119-
}
120119

121120
snprintf(buffer, size, "%s", ss.str().c_str());
122-
if(ss.str().length()+1 > size)
121+
if(*size_used > size){
122+
*size_used = size;
123123
return CDADA_E_INCOMPLETE;
124+
}
124125
}catch(bad_alloc& e){
125126
return CDADA_E_MEM;
126127
}catch(...){

src/list.cc

Lines changed: 7 additions & 3 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;
@@ -401,7 +403,7 @@ static int __cdada_list_first_last(const cdada_list_t* list, bool first,
401403
__cdada_list_int_t* m = (__cdada_list_int_t*)list;
402404

403405
if(unlikely(!m || m->magic_num != CDADA_MAGIC || !key))
404-
return false;
406+
return CDADA_E_INVALID;
405407

406408
try{
407409
int c = m->ops? 0 : m->val_len;
@@ -450,7 +452,7 @@ static int __cdada_list_first_last(const cdada_list_t* list, bool first,
450452
}catch(...){}
451453

452454
CDADA_ASSERT(0);
453-
return false;
455+
return CDADA_E_UNKNOWN;
454456
}
455457

456458
int cdada_list_first(const cdada_list_t* list, void* key){
@@ -1104,8 +1106,10 @@ int cdada_list_dump(cdada_list_t* list, uint32_t size, char* buffer,
11041106
return CDADA_SUCCESS;
11051107

11061108
snprintf(buffer, size, "%s", ss.str().c_str());
1107-
if(ss.str().length()+1 > size)
1109+
if(*size_used > size){
1110+
*size_used = size;
11081111
return CDADA_E_INCOMPLETE;
1112+
}
11091113
}catch(bad_alloc& e){
11101114
return CDADA_E_MEM;
11111115
}catch(...){

src/map.cc

Lines changed: 5 additions & 1 deletion
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;
@@ -899,8 +901,10 @@ int cdada_map_dump(cdada_map_t* map, uint32_t size, char* buffer,
899901
return CDADA_SUCCESS;
900902

901903
snprintf(buffer, size, "%s", ss.str().c_str());
902-
if(ss.str().length()+1 > size)
904+
if(*size_used > size){
905+
*size_used = size;
903906
return CDADA_E_INCOMPLETE;
907+
}
904908
}catch(bad_alloc& e){
905909
return CDADA_E_MEM;
906910
}catch(...){

src/queue.cc

Lines changed: 5 additions & 1 deletion
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;
@@ -555,8 +557,10 @@ int cdada_queue_dump(cdada_queue_t* queue, uint32_t size, char* buffer,
555557
return CDADA_SUCCESS;
556558

557559
snprintf(buffer, size, "%s", ss.str().c_str());
558-
if(ss.str().length()+1 > size)
560+
if(*size_used > size){
561+
*size_used = size;
559562
return CDADA_E_INCOMPLETE;
563+
}
560564
}catch(bad_alloc& e){
561565
return CDADA_E_MEM;
562566
}catch(...){

src/set.cc

Lines changed: 6 additions & 2 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;
@@ -446,7 +448,7 @@ bool cdada_set_find(const cdada_set_t* set, const void* key){
446448
return (*m->ops->find)(m, key);
447449
default:
448450
CDADA_ASSERT(0);
449-
return CDADA_E_UNKNOWN;
451+
return false;
450452
}
451453
}catch(...){}
452454

@@ -818,8 +820,10 @@ int cdada_set_dump(cdada_set_t* set, uint32_t size, char* buffer,
818820
return CDADA_SUCCESS;
819821

820822
snprintf(buffer, size, "%s", ss.str().c_str());
821-
if(ss.str().length()+1 > size)
823+
if(*size_used > size){
824+
*size_used = size;
822825
return CDADA_E_INCOMPLETE;
826+
}
823827
}catch(bad_alloc& e){
824828
return CDADA_E_MEM;
825829
}catch(...){

src/stack.cc

Lines changed: 5 additions & 1 deletion
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;
@@ -493,8 +495,10 @@ int cdada_stack_dump(cdada_stack_t* stack, uint32_t size, char* buffer,
493495
return CDADA_SUCCESS;
494496

495497
snprintf(buffer, size, "%s", ss.str().c_str());
496-
if(ss.str().length()+1 > size)
498+
if(*size_used > size){
499+
*size_used = size;
497500
return CDADA_E_INCOMPLETE;
501+
}
498502
}catch(bad_alloc& e){
499503
return CDADA_E_MEM;
500504
}catch(...){

0 commit comments

Comments
 (0)