Fixed integer overflow with hashtables when calculating their capacity

This commit is contained in:
Leonardo committed 2019-08-02 00:18:22 -03:00
1 parent 1254e657c5
commit 976965bcfa
6 files changed
+37 -1

No files matched your search

+4
View File
@@ -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)); \
+4
View File
@@ -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)); \
+4
View File
@@ -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)); \
+11
View File
@@ -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));
+11
View File
@@ -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);
+3 -1
View File
@@ -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_)