From 957c832db137e67289e93dfd9fd9e915b1f2fc87 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Sat, 18 Oct 2025 14:32:25 -0400 Subject: [PATCH] Fix memory leak in rb_const_remove when using namespace We need to free the rb_const_entry_t we remove from the RCLASS_WRITABLE_CONST_TBL otherwise it will leak memory. --- variable.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/variable.c b/variable.c index c8565047a46e4e..5fc98fb0879024 100644 --- a/variable.c +++ b/variable.c @@ -3533,7 +3533,8 @@ rb_const_remove(VALUE mod, ID id) rb_check_frozen(mod); ce = rb_const_lookup(mod, id); - if (!ce || !rb_id_table_delete(RCLASS_WRITABLE_CONST_TBL(mod), id)) { + + if (!ce) { if (rb_const_defined_at(mod, id)) { rb_name_err_raise("cannot remove %2$s::%1$s", mod, ID2SYM(id)); } @@ -3541,6 +3542,14 @@ rb_const_remove(VALUE mod, ID id) undefined_constant(mod, ID2SYM(id)); } + VALUE writable_ce = 0; + if (rb_id_table_lookup(RCLASS_WRITABLE_CONST_TBL(mod), id, &writable_ce)) { + rb_id_table_delete(RCLASS_WRITABLE_CONST_TBL(mod), id); + if ((rb_const_entry_t *)writable_ce != ce) { + xfree((rb_const_entry_t *)writable_ce); + } + } + rb_const_warn_if_deprecated(ce, mod, id); rb_clear_constant_cache_for_id(id);