diff options
-rw-r--r-- | regexec.c | 4 | ||||
-rw-r--r-- | regexp.h | 1 | ||||
-rw-r--r-- | t/re/pat_re_eval.t | 16 |
3 files changed, 20 insertions, 1 deletions
@@ -10233,6 +10233,7 @@ S_setup_eval_state(pTHX_ regmatch_info *const reginfo) regmatch_info_aux_eval *eval_state = reginfo->info_aux_eval; eval_state->rex = rex; + eval_state->sv = reginfo->sv; if (reginfo->sv) { /* Make $_ available to executed code. */ @@ -10240,6 +10241,8 @@ S_setup_eval_state(pTHX_ regmatch_info *const reginfo) SAVE_DEFSV; DEFSV_set(reginfo->sv); } + /* will be dec'd by S_cleanup_regmatch_info_aux */ + SvREFCNT_inc_NN(reginfo->sv); if (!(mg = mg_find_mglob(reginfo->sv))) { /* prepare for quick setting of pos */ @@ -10331,6 +10334,7 @@ S_cleanup_regmatch_info_aux(pTHX_ void *arg) } PL_curpm = eval_state->curpm; + SvREFCNT_dec(eval_state->sv); } PL_regmatch_state = aux->old_regmatch_state; @@ -658,6 +658,7 @@ typedef struct { STRLEN sublen; /* saved sublen field from rex */ STRLEN suboffset; /* saved suboffset field from rex */ STRLEN subcoffset; /* saved subcoffset field from rex */ + SV *sv; /* $_ during (?{}) */ MAGIC *pos_magic; /* pos() magic attached to $_ */ SSize_t pos; /* the original value of pos() in pos_magic */ U8 pos_flags; /* flags to be restored; currently only MGf_BYTES*/ diff --git a/t/re/pat_re_eval.t b/t/re/pat_re_eval.t index 8325451377..696b6a3fb5 100644 --- a/t/re/pat_re_eval.t +++ b/t/re/pat_re_eval.t @@ -23,7 +23,7 @@ BEGIN { our @global; -plan tests => 504; # Update this when adding/deleting tests. +plan tests => 506; # Update this when adding/deleting tests. run_tests() unless caller; @@ -1317,6 +1317,20 @@ sub run_tests { ok "ABC" =~ /^ $runtime_re (?(?{ 0; })xy|BC) $/x, 'RT #133687 yes|no'; } + # RT #134208 + # when the string being matched was an SvTEMP and the re_eval died, + # the SV's magic was being restored after the SV was freed. + # Give ASan something to play with. + + { + my $a; + no warnings 'uninitialized'; + eval { "$a $1" =~ /(?{ die })/ }; + pass("SvTEMP 1"); + eval { sub { " " }->() =~ /(?{ die })/ }; + pass("SvTEMP 2"); + } + } # End of sub run_tests 1; |