mruby-set: fix memory leak from double initialization; fix #6645

set_init was overwriting set->set without freeing the existing khash
table, causing a memory leak when initialize is called multiple times.

Prevent double initialization by raising an exception in set_init,
while allowing replace/dup semantics in set_init_copy by properly
freeing old data before reinitializing.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-10-22 11:50:33 +09:00
parent 7e26271a01
commit a3797173c2
+7
View File
@@ -158,6 +158,9 @@ static mrb_value
set_init(mrb_state *mrb, mrb_value self)
{
kset_t *set = set_get_kset(mrb, self);
if (!kset_is_uninitialized(set)) {
mrb_raise(mrb, E_RUNTIME_ERROR, "already initialized set");
}
kset_init_data(mrb, set, KSET_INITIAL_SIZE);
return self;
}
@@ -183,6 +186,10 @@ set_init_copy(mrb_state *mrb, mrb_value self)
set_ensure_initialized(mrb, orig_set);
kset_t *self_set = set_get_kset(mrb, self);
/* Free existing data if already initialized (for replace semantics) */
if (!kset_is_uninitialized(self_set)) {
kset_destroy_data(mrb, self_set);
}
kset_init_data(mrb, self_set, kset_size(orig_set));
kh_replace(set_val, mrb, self_set, orig_set);