mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-regexp: keep MatchData source/regexp GC-reachable
The mrb_match_data struct stores `source` and `regexp` as plain mrb_value members of a C-allocated struct, which the GC does not scan. Under MRB_GC_STRESS the source string could be collected while the MatchData was still alive, causing md[0] to read freed memory (observed as "\xff\xff\xff"). Also stash source and regexp as instance variables on the MatchData object so they remain reachable via the object's iv_tbl during GC. The C struct members continue to provide fast direct access, and no other call sites need to change. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -172,6 +172,11 @@ create_matchdata(mrb_state *mrb, mrb_value regexp, mrb_value str, int *captures,
|
||||
memcpy(md->captures, captures, sizeof(int) * ncap);
|
||||
|
||||
mrb_value obj = mrb_obj_value(mrb_data_object_alloc(mrb, md_class, md, &matchdata_type));
|
||||
/* Keep `source` and `regexp` GC-reachable via instance variables.
|
||||
* The mrb_values are also held in mrb_match_data, but C-allocated
|
||||
* structs are not scanned by the GC. */
|
||||
mrb_iv_set(mrb, obj, mrb_intern_lit(mrb, "source"), str);
|
||||
mrb_iv_set(mrb, obj, mrb_intern_lit(mrb, "regexp"), regexp);
|
||||
mrb_gv_set(mrb, mrb_intern_lit(mrb, "$~"), obj);
|
||||
|
||||
/* set $1-$9 from captures */
|
||||
|
||||
Reference in New Issue
Block a user