develooper Front page | perl.perl5.porters | Postings from April 2006

[perl #3237] tr/// against $1 causes persistent data

From:
Steve Peters via RT
Date:
April 17, 2006 13:53
Subject:
[perl #3237] tr/// against $1 causes persistent data
Message ID:
rt-3.0.11-3237-132354.0.895428686192687@perl.org
> [RT_System - Thu May 11 20:40:52 2000]:
> 
> In <Pine.GSO.4.10.10005111759110.16364-100000@user2.teleport.com>, Tom
> Phoenix
> writes:
> :This is a bug report for perl from rootbeer@redcat.com,
> :generated with the help of perlbug 1.28 running under perl v5.6.0.
> :
> :-----------------------------------------------------------------
> :
> :The substitution near the end of this chunk of code should change $_
> from
> :'fred' to 'Fred', but a previous value from $1 leaks in as well. This
> :seems to happen only when $1 has been used in a tr///-for-counting
> :operation.
> :
> :    $_ = "fred";
> :    /([a-z]{2})/;
> :    $1 =~ tr/A-Z//;
> :    print;			# prints "fred"
> :    s/^(\s*)f/$1F/;
> :    print;			# prints "frFred"
> 
> This appears to occur because the tr/// sets POK on $1, which bypasses
> the magic get that should happen in the substitution. The culprit is
> this line from doop.c:595 in Perl_do_trans():
>     (void)SvPOK_only(sv);
> 
> I'm not sure quite why this line exists, since removing it does not
> trigger any test failures, but I suspect that it should occur only if
> the SV does not have a magic get (as in the attached patch).
> If someone can confirm or correct this belief, I'll aim to add
> appropriate test cases.
> 
> Hugo
> --- doop.c.old	Sun Mar 12 03:36:32 2000
> +++ doop.c	Fri May 12 10:41:04 2000
> @@ -592,7 +592,8 @@
>  	return 0;
>      if (!SvPOKp(sv))
>  	(void)SvPV_force(sv, len);
> -    (void)SvPOK_only(sv);
> +    if (!SvGMAGICAL(sv))
> +	(void)SvPOK_only(sv);
> 
>      DEBUG_t( Perl_deb(aTHX_ "2.TBL\n"));
> 

It looks like this patch or the other patch in this ticket thread were
never applied.  Instead, the following change seemed to take care of things.

Change 17984 by rgs@rgs-home on 2002/10/09 19:17:08

	Fix bug #17823 : non-modifying tr/// stringifies references

Affected files ...

... //depot/perl/doop.c#129 edit
... //depot/perl/t/op/tr.t#33 edit

Differences ...

==== //depot/perl/doop.c#129 (text) ====

@@ -608,10 +608,11 @@
     (void)SvPV(sv, len);
     if (!len)
 	return 0;
-    if (!SvPOKp(sv))
-	(void)SvPV_force(sv, len);
-    if (!(PL_op->op_private & OPpTRANS_IDENTICAL))
+    if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) {
+	if (!SvPOKp(sv))
+	    (void)SvPV_force(sv, len);
 	(void)SvPOK_only_UTF8(sv);
+    }
 
     DEBUG_t( Perl_deb(aTHX_ "2.TBL\n"));
 

==== //depot/perl/t/op/tr.t#33 (xtext) ====

@@ -6,7 +6,7 @@
     require './test.pl';
 }
 
-plan tests => 97;
+plan tests => 99;
 
 my $Is_EBCDIC = (ord('i') == 0x89 & ord('J') == 0xd1);
 
@@ -379,3 +379,7 @@
 eval '$foo{bar} =~ tr/N/N/';
 is( $@, '',         'implicit count outside hash bounds' );
 is( scalar keys %foo, 0,   "    doesn't extend the hash");
+
+$x = \"foo";
+is( $x =~ tr/A/A/, 2, 'non-modifying tr/// on a scalar ref' );
+is( ref $x, 'SCALAR', "    doesn't stringify its argument" );



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About