From a3797173c2c526a0a40e35ca5a75eb476cac4cb8 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Oct 2025 11:50:33 +0900 Subject: [PATCH] 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 --- mrbgems/mruby-set/src/set.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mrbgems/mruby-set/src/set.c b/mrbgems/mruby-set/src/set.c index 39e7f6007..eaa1f1d8b 100644 --- a/mrbgems/mruby-set/src/set.c +++ b/mrbgems/mruby-set/src/set.c @@ -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);