summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo van der Sanden <hv@crypt.org>2003-02-15 06:27:07 +0000
committerhv <hv@crypt.org>2003-02-15 06:27:07 +0000
commitff891bcd7c107dda45206b62ef4ec8446c385934 (patch)
treea6c024a90f162d75254414cd7cacbf565c158012
parentf3924ce0f1ae999272b2ac9a02a388833baf0b15 (diff)
downloadperl-ff891bcd7c107dda45206b62ef4ec8446c385934.tar.gz
Re: [perl #20933] \substr reuses lvalues (sometimes)
From: Dave Mitchell <davem@fdgroup.com> Date: Fri, 14 Feb 2003 22:48:27 +0000 Message-ID: <20030214224827.B6783@fdgroup.com> with tests: From: Slaven Rezic <slaven@rezic.de> Date: 14 Feb 2003 20:23:20 +0100 Message-ID: <87bs1e4qfr.fsf@vran.herceg.de> p4raw-id: //depot/perl@18705
-rw-r--r--pp.c4
-rwxr-xr-xt/op/substr.t9
-rwxr-xr-xt/op/vec.t13
3 files changed, 24 insertions, 2 deletions
diff --git a/pp.c b/pp.c
index 67fe7f64e3..4fbcad44f8 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 85574d56ec..17f86e3e63 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 67d7527412..158711f6ea 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";
+}