summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2015-02-28 22:31:25 -0800
committerFather Chrysostomos <sprout@cpan.org>2015-02-28 22:31:25 -0800
commit55b3980349c58171a77894903fd928262fb081f2 (patch)
tree02acf5011b735a8065feca7ab7d8d11808687475 /op.c
parent179b3fadcd608f8420b9976426de4456289a8bc5 (diff)
downloadperl-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.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/op.c b/op.c
index 073cb1bfdc..45cde2be80 100644
--- a/op.c
+++ b/op.c
@@ -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),