summaryrefslogtreecommitdiff
path: root/class.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2025-10-15 19:30:31 -0400
committerPeter Zhu <peter@peterzhu.ca>2025-10-16 17:03:20 -0400
commit9a80258b23c76a40070668dbebab8dd6f0361b92 (patch)
tree48e45c81e931d610b48cbfac7385b0f30ea53597 /class.c
parent3fa848460098d1e77919f5280ff3dfd7687e243b (diff)
Fix crash when freeing namespaces
remove_class_from_subclasses calls st_insert, which mallocs. Malloc is not allowed in GC. This commit replaces the st_insert with an st_update since we know that ns_id exists in the st_table. The following script reproduces the crash: require "tempfile" Tempfile.create do |file| ns = Namespace.new ns.require(file) end
Diffstat (limited to 'class.c')
-rw-r--r--class.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/class.c b/class.c
index 84c8668b6b..469cc5e54f 100644
--- a/class.c
+++ b/class.c
@@ -496,6 +496,13 @@ class_get_subclasses_for_ns(struct st_table *tbl, VALUE ns_id)
return NULL;
}
+static int
+remove_class_from_subclasses_replace_first_entry(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
+{
+ *value = arg;
+ return ST_CONTINUE;
+}
+
static void
remove_class_from_subclasses(struct st_table *tbl, VALUE ns_id, VALUE klass)
{
@@ -516,7 +523,7 @@ remove_class_from_subclasses(struct st_table *tbl, VALUE ns_id, VALUE klass)
if (first_entry) {
if (next) {
- st_insert(tbl, ns_id, (st_data_t)next);
+ st_update(tbl, ns_id, remove_class_from_subclasses_replace_first_entry, (st_data_t)next);
}
else {
// no subclass entries in this ns