diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 768277b..45dc383 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -233,6 +233,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ + \ size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ \ SNAME *_map_ = malloc(sizeof(SNAME)); \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 61c0aa4..81705d3 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -225,6 +225,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ + \ size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ \ SNAME *_set_ = malloc(sizeof(SNAME)); \ diff --git a/src/ext/multimap.h b/src/ext/multimap.h index dab2b7f..abac290 100644 --- a/src/ext/multimap.h +++ b/src/ext/multimap.h @@ -248,6 +248,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, if (capacity == 0 || load <= 0) \ return NULL; \ \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ + \ size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ \ SNAME *_map_ = malloc(sizeof(SNAME)); \ diff --git a/tests/main/src/hashmap.c b/tests/main/src/hashmap.c index 57b9b45..816b9bc 100644 --- a/tests/main/src/hashmap.c +++ b/tests/main/src/hashmap.c @@ -45,6 +45,7 @@ bool hm_contains(hashmap *_map_, size_t key); bool hm_empty(hashmap *_map_); size_t hm_count(hashmap *_map_); size_t hm_capacity(hashmap *_map_); +cmc_string hm_to_string(hashmap *_map_); hashmap_iter *hm_iter_new(hashmap *target); void hm_iter_free(hashmap_iter *iter); void hm_iter_init(hashmap_iter *iter, hashmap *target); @@ -79,6 +80,8 @@ hashmap *hm_new(size_t capacity, double load, int (*compare)(size_t, size_t), si { if (capacity == 0 || load <= 0 || load >= 1) return NULL; + if (capacity >= UINTMAX_MAX * load) + return NULL; size_t real_capacity = hm_impl_calculate_size(capacity / load); hashmap *_map_ = malloc(sizeof(hashmap)); if (!_map_) @@ -249,6 +252,14 @@ bool hm_contains(hashmap *_map_, size_t key) { return hm_impl_get_entry(_map_, k bool hm_empty(hashmap *_map_) { return _map_->count == 0; } size_t hm_count(hashmap *_map_) { return _map_->count; } size_t hm_capacity(hashmap *_map_) { return _map_->capacity; } +cmc_string hm_to_string(hashmap *_map_) +{ + cmc_string str; + hashmap *m_ = _map_; + const char *name = "hashmap"; + snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmap, name, m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->cmp, m_->hash); + return str; +} hashmap_iter *hm_iter_new(hashmap *target) { hashmap_iter *iter = malloc(sizeof(hashmap_iter)); diff --git a/tests/main/src/hashset.c b/tests/main/src/hashset.c index 8287c06..78070ed 100644 --- a/tests/main/src/hashset.c +++ b/tests/main/src/hashset.c @@ -42,6 +42,7 @@ bool hs_contains(hashset *_set_, size_t element); bool hs_empty(hashset *_set_); size_t hs_count(hashset *_set_); size_t hs_capacity(hashset *_set_); +cmc_string hs_to_string(hashset *_set_); hashset *hs_union(hashset *_set1_, hashset *_set2_); hashset *hs_intersection(hashset *_set1_, hashset *_set2_); hashset *hs_difference(hashset *_set1_, hashset *_set2_); @@ -77,6 +78,8 @@ hashset *hs_new(size_t capacity, double load, int (*compare)(size_t, size_t), si { if (capacity == 0 || load <= 0 || load >= 1) return NULL; + if (capacity >= UINTMAX_MAX * load) + return NULL; size_t real_capacity = hs_impl_calculate_size(capacity / load); hashset *_set_ = malloc(sizeof(hashset)); if (!_set_) @@ -212,6 +215,14 @@ bool hs_contains(hashset *_set_, size_t element) { return hs_impl_get_entry(_set bool hs_empty(hashset *_set_) { return _set_->count == 0; } size_t hs_count(hashset *_set_) { return _set_->count; } size_t hs_capacity(hashset *_set_) { return _set_->capacity; } +cmc_string hs_to_string(hashset *_set_) +{ + cmc_string str; + hashset *s_ = _set_; + const char *name = "hashset"; + snprintf(str.s, cmc_string_len, cmc_string_fmt_hashset, name, s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->cmp, s_->hash); + return str; +} hashset *hs_union(hashset *_set1_, hashset *_set2_) { hashset *_set_r_ = hs_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); diff --git a/tests/main/src/multimap.c b/tests/main/src/multimap.c index 97815f2..87b2224 100644 --- a/tests/main/src/multimap.c +++ b/tests/main/src/multimap.c @@ -31,7 +31,7 @@ typedef struct multimap_iter_s bool start; bool end; } multimap_iter, *multimap_iter_ptr; -multimap *mm_new(size_t size, double load, int (*compare)(size_t, size_t), size_t (*hash)(size_t)); +multimap *mm_new(size_t capacity, double load, int (*compare)(size_t, size_t), size_t (*hash)(size_t)); void mm_clear(multimap *_map_); void mm_free(multimap *_map_); bool mm_insert(multimap *_map_, size_t key, size_t value); @@ -82,6 +82,8 @@ multimap *mm_new(size_t capacity, double load, int (*compare)(size_t, size_t), s { if (capacity == 0 || load <= 0) return NULL; + if (capacity >= UINTMAX_MAX * load) + return NULL; size_t real_capacity = mm_impl_calculate_size(capacity / load); multimap *_map_ = malloc(sizeof(multimap)); if (!_map_)