diff options
| author | Peter Zhu <peter@peterzhu.ca> | 2023-11-27 14:45:47 -0500 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2023-11-27 16:49:52 -0500 |
| commit | 94015e0dce38d238d428b60b46dcb9f3caef445f (patch) | |
| tree | e3075cd2f0fcd8d77cf03686ae84b5ceeec04387 /string.c | |
| parent | 1acea5010023deb0b4747e6c7309c4d69bdaf47d (diff) | |
Guard match from GC when scanning string
We need to guard match from GC because otherwise it could end up being
reclaimed or moved in compaction.
Diffstat (limited to 'string.c')
| -rw-r--r-- | string.c | 28 |
1 files changed, 17 insertions, 11 deletions
@@ -9973,11 +9973,11 @@ rb_str_strip(VALUE str) static VALUE scan_once(VALUE str, VALUE pat, long *start, int set_backref_str) { - VALUE result, match; - struct re_registers *regs; - int i; + VALUE result = Qnil; long end, pos = rb_pat_search(pat, str, *start, set_backref_str); if (pos >= 0) { + VALUE match; + struct re_registers *regs; if (BUILTIN_TYPE(pat) == T_STRING) { regs = NULL; end = pos + RSTRING_LEN(pat); @@ -9988,6 +9988,7 @@ scan_once(VALUE str, VALUE pat, long *start, int set_backref_str) pos = BEG(0); end = END(0); } + if (pos == end) { rb_encoding *enc = STR_ENC_GET(str); /* @@ -10002,22 +10003,27 @@ scan_once(VALUE str, VALUE pat, long *start, int set_backref_str) else { *start = end; } + if (!regs || regs->num_regs == 1) { result = rb_str_subseq(str, pos, end - pos); return result; } - result = rb_ary_new2(regs->num_regs); - for (i=1; i < regs->num_regs; i++) { - VALUE s = Qnil; - if (BEG(i) >= 0) { - s = rb_str_subseq(str, BEG(i), END(i)-BEG(i)); + else { + result = rb_ary_new2(regs->num_regs); + for (int i = 1; i < regs->num_regs; i++) { + VALUE s = Qnil; + if (BEG(i) >= 0) { + s = rb_str_subseq(str, BEG(i), END(i)-BEG(i)); + } + + rb_ary_push(result, s); } - rb_ary_push(result, s); } - return result; + RB_GC_GUARD(match); } - return Qnil; + + return result; } |
