Fixed integer overflow with hashtables when calculating their capacity
This commit is contained in:
1 parent
1254e657c5
commit
976965bcfa
6 files changed
+37
-1
No files matched your search
@@ -233,6 +233,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
|||||||
if (capacity == 0 || load <= 0 || load >= 1) \
|
if (capacity == 0 || load <= 0 || load >= 1) \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
\
|
\
|
||||||
|
/* Prevent integer overflow */ \
|
||||||
|
if (capacity >= UINTMAX_MAX * load) \
|
||||||
|
return NULL; \
|
||||||
|
\
|
||||||
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
|
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
|
||||||
\
|
\
|
||||||
SNAME *_map_ = malloc(sizeof(SNAME)); \
|
SNAME *_map_ = malloc(sizeof(SNAME)); \
|
||||||
|
|||||||
@@ -225,6 +225,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
|||||||
if (capacity == 0 || load <= 0 || load >= 1) \
|
if (capacity == 0 || load <= 0 || load >= 1) \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
\
|
\
|
||||||
|
/* Prevent integer overflow */ \
|
||||||
|
if (capacity >= UINTMAX_MAX * load) \
|
||||||
|
return NULL; \
|
||||||
|
\
|
||||||
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
|
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
|
||||||
\
|
\
|
||||||
SNAME *_set_ = malloc(sizeof(SNAME)); \
|
SNAME *_set_ = malloc(sizeof(SNAME)); \
|
||||||
|
|||||||
@@ -248,6 +248,10 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
|||||||
if (capacity == 0 || load <= 0) \
|
if (capacity == 0 || load <= 0) \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
\
|
\
|
||||||
|
/* Prevent integer overflow */ \
|
||||||
|
if (capacity >= UINTMAX_MAX * load) \
|
||||||
|
return NULL; \
|
||||||
|
\
|
||||||
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
|
size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
|
||||||
\
|
\
|
||||||
SNAME *_map_ = malloc(sizeof(SNAME)); \
|
SNAME *_map_ = malloc(sizeof(SNAME)); \
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ bool hm_contains(hashmap *_map_, size_t key);
|
|||||||
bool hm_empty(hashmap *_map_);
|
bool hm_empty(hashmap *_map_);
|
||||||
size_t hm_count(hashmap *_map_);
|
size_t hm_count(hashmap *_map_);
|
||||||
size_t hm_capacity(hashmap *_map_);
|
size_t hm_capacity(hashmap *_map_);
|
||||||
|
cmc_string hm_to_string(hashmap *_map_);
|
||||||
hashmap_iter *hm_iter_new(hashmap *target);
|
hashmap_iter *hm_iter_new(hashmap *target);
|
||||||
void hm_iter_free(hashmap_iter *iter);
|
void hm_iter_free(hashmap_iter *iter);
|
||||||
void hm_iter_init(hashmap_iter *iter, hashmap *target);
|
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)
|
if (capacity == 0 || load <= 0 || load >= 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (capacity >= UINTMAX_MAX * load)
|
||||||
|
return NULL;
|
||||||
size_t real_capacity = hm_impl_calculate_size(capacity / load);
|
size_t real_capacity = hm_impl_calculate_size(capacity / load);
|
||||||
hashmap *_map_ = malloc(sizeof(hashmap));
|
hashmap *_map_ = malloc(sizeof(hashmap));
|
||||||
if (!_map_)
|
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; }
|
bool hm_empty(hashmap *_map_) { return _map_->count == 0; }
|
||||||
size_t hm_count(hashmap *_map_) { return _map_->count; }
|
size_t hm_count(hashmap *_map_) { return _map_->count; }
|
||||||
size_t hm_capacity(hashmap *_map_) { return _map_->capacity; }
|
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 *hm_iter_new(hashmap *target)
|
||||||
{
|
{
|
||||||
hashmap_iter *iter = malloc(sizeof(hashmap_iter));
|
hashmap_iter *iter = malloc(sizeof(hashmap_iter));
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ bool hs_contains(hashset *_set_, size_t element);
|
|||||||
bool hs_empty(hashset *_set_);
|
bool hs_empty(hashset *_set_);
|
||||||
size_t hs_count(hashset *_set_);
|
size_t hs_count(hashset *_set_);
|
||||||
size_t hs_capacity(hashset *_set_);
|
size_t hs_capacity(hashset *_set_);
|
||||||
|
cmc_string hs_to_string(hashset *_set_);
|
||||||
hashset *hs_union(hashset *_set1_, hashset *_set2_);
|
hashset *hs_union(hashset *_set1_, hashset *_set2_);
|
||||||
hashset *hs_intersection(hashset *_set1_, hashset *_set2_);
|
hashset *hs_intersection(hashset *_set1_, hashset *_set2_);
|
||||||
hashset *hs_difference(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)
|
if (capacity == 0 || load <= 0 || load >= 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (capacity >= UINTMAX_MAX * load)
|
||||||
|
return NULL;
|
||||||
size_t real_capacity = hs_impl_calculate_size(capacity / load);
|
size_t real_capacity = hs_impl_calculate_size(capacity / load);
|
||||||
hashset *_set_ = malloc(sizeof(hashset));
|
hashset *_set_ = malloc(sizeof(hashset));
|
||||||
if (!_set_)
|
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; }
|
bool hs_empty(hashset *_set_) { return _set_->count == 0; }
|
||||||
size_t hs_count(hashset *_set_) { return _set_->count; }
|
size_t hs_count(hashset *_set_) { return _set_->count; }
|
||||||
size_t hs_capacity(hashset *_set_) { return _set_->capacity; }
|
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 *hs_union(hashset *_set1_, hashset *_set2_)
|
||||||
{
|
{
|
||||||
hashset *_set_r_ = hs_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash);
|
hashset *_set_r_ = hs_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ typedef struct multimap_iter_s
|
|||||||
bool start;
|
bool start;
|
||||||
bool end;
|
bool end;
|
||||||
} multimap_iter, *multimap_iter_ptr;
|
} 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_clear(multimap *_map_);
|
||||||
void mm_free(multimap *_map_);
|
void mm_free(multimap *_map_);
|
||||||
bool mm_insert(multimap *_map_, size_t key, size_t value);
|
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)
|
if (capacity == 0 || load <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (capacity >= UINTMAX_MAX * load)
|
||||||
|
return NULL;
|
||||||
size_t real_capacity = mm_impl_calculate_size(capacity / load);
|
size_t real_capacity = mm_impl_calculate_size(capacity / load);
|
||||||
multimap *_map_ = malloc(sizeof(multimap));
|
multimap *_map_ = malloc(sizeof(multimap));
|
||||||
if (!_map_)
|
if (!_map_)
|
||||||
|
|||||||
Reference in new issue
Block a user