diff options
author | Father Chrysostomos <sprout@cpan.org> | 2015-02-28 22:31:25 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2015-02-28 22:31:25 -0800 |
commit | 55b3980349c58171a77894903fd928262fb081f2 (patch) | |
tree | 02acf5011b735a8065feca7ab7d8d11808687475 /op.c | |
parent | 179b3fadcd608f8420b9976426de4456289a8bc5 (diff) | |
download | perl-55b3980349c58171a77894903fd928262fb081f2.tar.gz |
[perl #123763] Clear target on my $_; split
If a lexical $_ is in scope, then the first argument to split, which
starts out as a match op, will get the pad offset of $_ as its target,
since that’s how implicit lexical $_=~ usually works.
ck_split changes that first argument to a pushre op. The target
was not being cleared. That did not cause any problems, until
v5.21.4-408-gfd017c0, which optimised lexical @array = split to write
to split @array directly, by storing making lexical array’s pad offset
the pushre’s target.
You can see the obvious conflict there. We end up trying to split to
$_, which is not an array. On a debugging build, you get an assertion
failure when trying to extend $_. Make the split list long enough,
and you get a crash on non-debugging builds.
debugging$ ./miniperl -e 'my $_; split'
Use of my $_ is experimental at -e line 1.
Assertion failed: (SvTYPE(av) == SVt_PVAV), function Perl_av_extend, file av.c, line 70.
non-debugging$ ./miniperl -e 'my $_; split //, "a"x100000'
Use of my $_ is experimental at -e line 1.
Segmentation fault: 11
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 2 |
1 files changed, 2 insertions, 0 deletions
@@ -11097,6 +11097,8 @@ Perl_ck_split(pTHX_ OP *o) op_sibling_splice(o, NULL, 0, kid); } CHANGE_TYPE(kid, OP_PUSHRE); + /* target implies @ary=..., so wipe it */ + kid->op_targ = 0; scalar(kid); if (((PMOP *)kid)->op_pmflags & PMf_GLOBAL) { Perl_ck_warner(aTHX_ packWARN(WARN_REGEXP), |