From: Hugo van der Sanden Date: Sat, 15 Feb 2003 06:27:07 +0000 (+0000) Subject: Re: [perl #20933] \substr reuses lvalues (sometimes) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=24aef97f7fec4668a5731fc6d5179ebebd43f183;p=p5sagit%2Fp5-mst-13.2.git Re: [perl #20933] \substr reuses lvalues (sometimes) From: Dave Mitchell Date: Fri, 14 Feb 2003 22:48:27 +0000 Message-ID: <20030214224827.B6783@fdgroup.com> with tests: From: Slaven Rezic Date: 14 Feb 2003 20:23:20 +0100 Message-ID: <87bs1e4qfr.fsf@vran.herceg.de> p4raw-id: //depot/perl@18705 --- diff --git a/pp.c b/pp.c index 67fe7f6..4fbcad4 100644 --- a/pp.c +++ b/pp.c @@ -3094,6 +3094,8 @@ PP(pp_substr) sv_setpvn(sv,"",0); /* avoid lexical reincarnation */ } + if (SvREFCNT(TARG) > 1) /* don't share the TARG (#20933) */ + TARG = sv_newmortal(); if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); sv_magic(TARG, Nullsv, PERL_MAGIC_substr, Nullch, 0); @@ -3124,6 +3126,8 @@ PP(pp_vec) SvTAINTED_off(TARG); /* decontaminate */ if (lvalue) { /* it's an lvalue! */ + if (SvREFCNT(TARG) > 1) /* don't share the TARG (#20933) */ + TARG = sv_newmortal(); if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); sv_magic(TARG, Nullsv, PERL_MAGIC_vec, Nullch, 0); diff --git a/t/op/substr.t b/t/op/substr.t index 85574d5..17f86e3 100755 --- a/t/op/substr.t +++ b/t/op/substr.t @@ -1,6 +1,6 @@ #!./perl -print "1..174\n"; +print "1..175\n"; #P = start of string Q = start of substr R = end of substr S = end of string @@ -585,3 +585,10 @@ ok 173, $x eq "\xFFb\x{100}\x{200}"; substr($x = "\x{100}\x{200}", 2, 0, "\xFFb"); ok 174, $x eq "\x{100}\x{200}\xFFb"; +# [perl #20933] +{ + my $s = "ab"; + my @r; + $r[$_] = \ substr $s, $_, 1 for (0, 1); + ok 175, join("", map { $$_ } @r) eq "ab"; +} diff --git a/t/op/vec.t b/t/op/vec.t index 67d7527..158711f 100755 --- a/t/op/vec.t +++ b/t/op/vec.t @@ -1,6 +1,6 @@ #!./perl -print "1..30\n"; +print "1..31\n"; my $Is_EBCDIC = (ord('A') == 193) ? 1 : 0; @@ -86,3 +86,14 @@ print "ok 29\n"; vec(substr($foo, 1,3), 5, 4) = 3; print "not " if $foo ne "\x61\x62\x63\x34\x65\x66"; print "ok 30\n"; + +# A variation of [perl #20933] +{ + my $s = ""; + vec($s, 0, 1) = 0; + vec($s, 1, 1) = 1; + my @r; + $r[$_] = \ vec $s, $_, 1 for (0, 1); + print "not " if (${ $r[0] } != 0 || ${ $r[1] } != 1); + print "ok 31\n"; +}