Skip to content

Commit

Permalink
s/.../$_++/ge assertion failure
Browse files Browse the repository at this point in the history
The code that updated pos() on a match string assumed that it was SvPOK().
Cunning code like the following converted $_ to SvIOK only:

    $_ = 0;
    s/.?/$_++/ge;
  • Loading branch information
iabyn committed Apr 22, 2015
1 parent 6b7f14c commit a911bb2
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
8 changes: 7 additions & 1 deletion pp_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,16 @@ PP(pp_substcont)
SV * const sv
= (pm->op_pmflags & PMf_NONDESTRUCT) ? cx->sb_dstr : cx->sb_targ;
MAGIC *mg;

/* the string being matched against may no longer be a string,
* e.g. $_=0; s/.../$_++/ge */

if (!SvPOK(sv))
SvPV_force_nomg_nolen(sv);

if (!(mg = mg_find_mglob(sv))) {
mg = sv_magicext_mglob(sv);
}
assert(SvPOK(sv));
MgBYTEPOS_set(mg, sv, SvPVX(sv), m - orig);
}
if (old != rx)
Expand Down
11 changes: 10 additions & 1 deletion t/re/subst.t
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ BEGIN {
require './charset_tools.pl';
}

plan( tests => 260 );
plan( tests => 261 );

$_ = 'david';
$a = s/david/rules/r;
Expand Down Expand Up @@ -1052,3 +1052,12 @@ SKIP: {
}

}

{
# RT #123954 if the string getting matched against got converted during
# s///e so that it was no longer SvPOK, an assertion would fail when
# setting pos.
my $s1 = 0;
$s1 =~ s/.?/$s1++/ge;
is($s1, "01","RT #123954 s1");
}

0 comments on commit a911bb2

Please sign in to comment.