summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2023-06-29 15:25:31 -0400
committerPeter Zhu <peter@peterzhu.ca>2023-06-29 19:07:26 -0400
commitd3ff43852b22f5463d22aab390ef340d9ebe4b06 (patch)
treec99959edf8a7a0b0ea445f090208433a4f8ba386 /hash.c
parent1272865a8ee948816ee9f5484f8adba8e26f45e2 (diff)
Fix memory leak in Hash#replace
Hash#replace can leak memory if the receiver has an ST table.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/8001
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/hash.c b/hash.c
index a779c6f218..f3514cd94b 100644
--- a/hash.c
+++ b/hash.c
@@ -1158,6 +1158,19 @@ ar_clear(VALUE hash)
}
}
+static void
+st_free_and_clear_table(VALUE hash)
+{
+ HASH_ASSERT(RHASH_ST_TABLE_P(hash));
+
+ st_table *tab = RHASH_ST_TABLE(hash);
+
+ if (tab->bins != NULL) free(tab->bins);
+ free(tab->entries);
+
+ RHASH_ST_CLEAR(hash);
+}
+
typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
struct foreach_safe_arg {
@@ -2894,7 +2907,7 @@ rb_hash_replace(VALUE hash, VALUE hash2)
ar_free_and_clear_table(hash);
}
else {
- RHASH_ST_CLEAR(hash);
+ st_free_and_clear_table(hash);
}
hash_copy(hash, hash2);