summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-02-11 08:26:33 +0900
committerGitHub <[email protected]>2021-02-11 08:26:33 +0900
commitd178e147f5cd86af247fc4b6cfafbde1308ede33 (patch)
tree9bf92b07c0d7c9a407db5326f5c2f615e4cbc780 /src
parent5735d7c2fd18c7d92bfe7a7d1d68547e5765c60d (diff)
parent28eb6271ba231fb8a6bfc2110b06e24c410bf8e1 (diff)
downloadmruby-d178e147f5cd86af247fc4b6cfafbde1308ede33.tar.gz
mruby-d178e147f5cd86af247fc4b6cfafbde1308ede33.zip
Merge pull request #5333 from shuujii/fix-heap-buffer-overflow-for-small-Hash-HT-in-Hash-rehash
Fix heap-buffer-overflow for small `Hash` (HT) in `Hash#rehash`
Diffstat (limited to 'src')
-rw-r--r--src/hash.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/hash.c b/src/hash.c
index 289f02a91..1fbacc889 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -718,6 +718,7 @@ ib_bit_for(uint32_t size)
static uint32_t
ib_byte_size_for(uint32_t ib_bit)
{
+ mrb_assert(IB_INIT_BIT <= ib_bit);
uint32_t ary_size = IB_INIT_BIT == 4 ?
ib_bit_to_capa(ib_bit) * 2 / IB_TYPE_BIT * ib_bit / 2 :
ib_bit_to_capa(ib_bit) / IB_TYPE_BIT * ib_bit;
@@ -892,7 +893,13 @@ static void
ht_rehash(mrb_state *mrb, struct RHash *h)
{
/* see comments in `h_rehash` */
- uint32_t size = ht_size(h), w_size = 0, ea_capa = ht_ea_capa(h);
+ uint32_t size = ht_size(h);
+ if (size <= AR_MAX_SIZE) {
+ ht_to_ar(mrb, h);
+ ar_rehash(mrb, h);
+ return;
+ }
+ uint32_t w_size = 0, ea_capa = ht_ea_capa(h);
hash_entry *ea = ht_ea(h);
ht_init(mrb, h, 0, ea, ea_capa, h_ht(h), ib_bit_for(size));
ht_set_size(h, size);