diff options
| author | Peter Zhu <peter@peterzhu.ca> | 2025-10-15 19:30:31 -0400 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2025-10-16 17:03:20 -0400 |
| commit | 9a80258b23c76a40070668dbebab8dd6f0361b92 (patch) | |
| tree | 48e45c81e931d610b48cbfac7385b0f30ea53597 /class.c | |
| parent | 3fa848460098d1e77919f5280ff3dfd7687e243b (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.c | 9 |
1 files changed, 8 insertions, 1 deletions
@@ -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 |
