develooper Front page | perl.perl5.porters | Postings from November 2005

Re: [perl #37731] junk and uninit'ed values in tied scalars

Thread Previous | Thread Next
From:
Yitzchak Scott-Thoennes
Date:
November 28, 2005 01:26
Subject:
Re: [perl #37731] junk and uninit'ed values in tied scalars
Message ID:
20051128092605.GA2328@efn.org
On Wed, Nov 23, 2005 at 07:17:30PM -0800, Yitzchak Scott-Thoennes wrote:
> On Tue, Nov 22, 2005 at 05:09:36PM -0800, lallip @ cs. rpi. edu wrote:
> >     Here is a short program that illustrates bug #1:
> > 
> >         sub foo::TIESCALAR { bless {value => $_[1]}, $_[0] }
> >         sub foo::FETCH { $_[0]->{value} }
> >         tie my $test, 'foo', 'test';
> >         print "$test$test\n";
> > 
> > This prints "testp\cX\c@" or other similar garbage. The first
> > interpolation prints fine; the second is reminiscent of a
> > non-NUL-terminated C string.
> 
> Hmm, does Robin's #26192 fix this, too?

Yes, it does.  Thinking ahead to 5.8.9, I'm not sure how well that
plays with the Y2K check that's in pp_concat in maint but not blead,
though.  Robin?

> >     Here is a short program that illustrates bug #2:
> > 
> >         use warnings;
> >         sub foo::TIESCALAR { bless {}, shift }
> >         sub foo::FETCH { return 2 }
> >         tie my $test, 'foo';
> >         my $bits = 3 & ~$test;
> > 
> > This gives the warning
> >         Use of uninitialized value in 1's complement (~) at....
> 
> Fixed in blead, probably by #22163, which Nicholas has hesitated to
> add to maint.

Nope, this was fixed by Rafael's patch #22074; my #22163 was a
followup that eliminated double magic (some introduced by 22074 and
some not, IIRC) and fixed a different problem.

> >     Finally, the mysterious Bug #3:
> > 
> >         sub foo::TIESCALAR { bless {value => $_[1]}, $_[0] }
> >         sub foo::FETCH { $_[0]->{value} }
> >         tie my $VAR, 'foo', 'SEARCH';
> >         foreach my $var ($VAR)
> >         {
> >            print +($var eq $VAR) ? 'yes' : 'no';
> >         }
> > 
> > This prints "no".
> 
> Still a problem in blead.  I hope any fix to this would make something
> that does: sub FETCH { ++$_[0]->{value} } have eq return *false*.

This does it, if a little heavy-handedly:

--- perl/sv.c.orig	2005-11-25 09:33:11.000000000 -0800
+++ perl/sv.c	2005-11-27 21:30:09.828265600 -0800
@@ -5579,6 +5579,15 @@ Perl_sv_eq(pTHX_ register SV *sv1, regis
     else
 	pv1 = SvPV_const(sv1, cur1);
 
+    /* if pv1 and pv2 are the same, second SvPV_const call may
+       invalidate pv1, so we may need to make a copy */
+
+    if (sv1 == sv2 && sv1 && (SvTHINKFIRST(sv1) || SvGMAGICAL(sv1))) {
+        sv1 = sv_2mortal(newSVpvn(pv1, cur1));
+        if (SvUTF8(sv2)) SvUTF8_on(sv1);
+        pv1 = SvPV_const(sv1, cur1);
+    }
+
     if (!sv2){
 	pv2 = "";
 	cur2 = 0;


Thread Previous | Thread Next


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