use safe memcmp also as default for the hash map - relates to # 615

Fri, 19 Dec 2025 17:41:53 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 19 Dec 2025 17:41:53 +0100
changeset 1635
4983b6a34996
parent 1634
006e076a8db7
child 1636
5ed91801f79d

use safe memcmp also as default for the hash map - relates to # 615

src/hash_map.c file | annotate | diff | comparison | revisions
src/list.c file | annotate | diff | comparison | revisions
tests/test_hash_map.c file | annotate | diff | comparison | revisions
--- a/src/hash_map.c	Fri Dec 19 17:37:17 2025 +0100
+++ b/src/hash_map.c	Fri Dec 19 17:41:53 2025 +0100
@@ -400,6 +400,13 @@
         cx_hash_map_iterator,
 };
 
+static int cx_map_cmpfunc2_safe_memcmp(const void *a, const void *b, void *c) {
+    // it is not safe to store a pointer to the size in the list
+    // because the entire list structure might get reallocated
+    size_t elem_size = (size_t)(uintptr_t)c;
+    return memcmp(a, b, elem_size);
+}
+
 CxMap *cxHashMapCreate(
         const CxAllocator *allocator,
         size_t itemsize,
@@ -432,8 +439,8 @@
 
     if (itemsize > 0) {
         map->base.collection.elem_size = itemsize;
-        map->base.collection.advanced_cmp = cx_ccmp_memcmp;
-        map->base.collection.cmp_data = &map->base.collection.elem_size;
+        map->base.collection.advanced_cmp = cx_map_cmpfunc2_safe_memcmp;
+        map->base.collection.cmp_data = (void*)(uintptr_t)itemsize;
     } else {
         map->base.collection.elem_size = sizeof(void *);
         map->base.collection.store_pointer = true;
--- a/src/list.c	Fri Dec 19 17:37:17 2025 +0100
+++ b/src/list.c	Fri Dec 19 17:41:53 2025 +0100
@@ -339,7 +339,7 @@
     return 0;
 }
 
-static int cx_list_ccmp_safe_memcmp(const void *a, const void *b, void *c) {
+static int cx_list_cmpfunc2_safe_memcmp(const void *a, const void *b, void *c) {
     // it is not safe to store a pointer to the size in the list
     // because the entire list structure might get reallocated
     size_t elem_size = (size_t)(uintptr_t)c;
@@ -359,7 +359,7 @@
     if (elem_size > 0) {
         list->collection.elem_size = elem_size;
         list->collection.simple_cmp = NULL;
-        list->collection.advanced_cmp = cx_list_ccmp_safe_memcmp;
+        list->collection.advanced_cmp = cx_list_cmpfunc2_safe_memcmp;
         list->collection.cmp_data = (void*)(uintptr_t)list->collection.elem_size;
         list->collection.store_pointer = false;
     } else {
--- a/tests/test_hash_map.c	Fri Dec 19 17:37:17 2025 +0100
+++ b/tests/test_hash_map.c	Fri Dec 19 17:41:53 2025 +0100
@@ -38,19 +38,19 @@
     cx_testing_allocator_init(&talloc);
     CxAllocator *allocator = &talloc.base;
     CX_TEST_DO {
-        CxMap *map = cxHashMapCreate(allocator, 1, 0);
+        CxMap *map = cxHashMapCreate(allocator, sizeof(int), 0);
         struct cx_hash_map_s *hmap = (struct cx_hash_map_s *) map;
         CX_TEST_ASSERT(hmap->bucket_count > 0);
         for(size_t i = 0 ; i < hmap->bucket_count ; i++) {
             CX_TEST_ASSERT(hmap->buckets[i] == NULL);
         }
-        CX_TEST_ASSERT(map->collection.elem_size == 1);
+        CX_TEST_ASSERT(map->collection.elem_size == 4);
         CX_TEST_ASSERT(map->collection.size == 0);
         CX_TEST_ASSERT(map->collection.allocator == allocator);
         CX_TEST_ASSERT(!map->collection.store_pointer);
         CX_TEST_ASSERT(map->collection.simple_cmp == NULL);
-        CX_TEST_ASSERT(map->collection.advanced_cmp == cx_ccmp_memcmp);
-        CX_TEST_ASSERT(map->collection.cmp_data == &map->collection.elem_size);
+        CX_TEST_ASSERT(map->collection.advanced_cmp != NULL);
+        CX_TEST_ASSERT((uintptr_t) map->collection.cmp_data == sizeof(int));
         CX_TEST_ASSERT(map->collection.simple_destructor == NULL);
         CX_TEST_ASSERT(map->collection.advanced_destructor == NULL);
         CX_TEST_ASSERT(map->collection.destructor_data == NULL);

mercurial