Apparent bug in 5.8 wrt tied scalars

E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Good morning, (well, it's morning in the USA)

In the past month, three bugs have been reported in my Readonly
module, except that they turned out not to be bugs in the module, but
(sadly) bugs in Perl 5.8. The pure-perl version of Readonly relies
on tied variables, which appear to have various colorful and
intermittent bugs.

I have not reported these via the usual way (perlbug), because at
the current time, I do not have access to a machine that can send
mail to the outside world. So I'm posting it here in the hopes that
a) someone who maintains perl will see it, or b) someone will perlbug
it.

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.

Oddly, with a longer string:

sub foo::TIESCALAR { bless {value => $_[1]}, $_[0] }
sub foo::FETCH { $_[0]->{value} }
tie my $test, 'foo', 'I snort the nose, Lucifer!';
print "$test$test\n";

it prints "I snort the nose, Lucifer!I snort the nose, Lucifer!" as
you'd expect. Also, if there is a space, or any other character,
between the two variables in the interpolation:

print "$test $test\n";

there is no buggy behavior.

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....

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".

Amusingly, change the "print" line to:

print +(lc $var eq lc $VAR) ? 'yes' : 'no';

and it prints "yes".


I had several friends try out the code I posted above for "bug
#1". Two people had perl 5.6.1, and that did not exhibit the buggy
behavior. All others had various forms of 5.8.x (where x ranged from
0 to 7), on various platforms (Windows, linux, FreeBSD, MacOSX,
cygwin/2000, cygwin/XP). All 5.8.x users exhibited the buggy
behavior.

Any insight the users of this group can shed on this problem
would be greatly appreciated.

Thank you,
- --
Eric
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (MingW32) - WinPT 0.7.96rc1

iD8DBQFDfyWUY96i4h5M0egRAmqUAJ4gk+BG2pBjEIJiN1/MTW2rdmxlMwCgpkF8
i0fyS60LX6NVzOCU0ceHzLw=
=0xYi
-----END PGP SIGNATURE-----
 
P

Paul Lalli

Eric said:
In the past month, three bugs have been reported in my Readonly
module, except that they turned out not to be bugs in the module, but
(sadly) bugs in Perl 5.8. The pure-perl version of Readonly relies
on tied variables, which appear to have various colorful and
intermittent bugs.

I have not reported these via the usual way (perlbug), because at
the current time, I do not have access to a machine that can send
mail to the outside world. So I'm posting it here in the hopes that
a) someone who maintains perl will see it, or b) someone will perlbug
it.

Eric,

I have no answers for you as to why this behavior is occurring, but I
have confirmed all three on 5.8.5 for solaris, and I have filled out a
perlbug report as requested.

Paul Lalli
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Eric J. Roode
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.

I think this is "as expected" (the state of "tieing" engine is pretty
pitiful....). There is a slot in a tied scalar where the value "is
created" each time the scalar is accessed; you use this slot two times
in the same expression. Essentially, you are trying to evaluate

$test . $test

The operator `.' expects to get two values; however, when $test is
calculated the second time, the first value "is overwritten", so you
get garbage. (This does not explain why the garbage is in the second
position, but you got the idea...)
print "$test $test\n";
there is no buggy behavior.

($test . ' ') . $test

Each `.' operator works on one copy only.
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....

Maybe similar: ~ accesses its argument several times - once to
understand whether it is a string or number, then to fetch
string/number. (Well, I'm stressing my imagination....)
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".
Likewise.

Amusingly, change the "print" line to:

print +(lc $var eq lc $VAR) ? 'yes' : 'no';

and it prints "yes".

See above.

To work around, instead of "$test$test" you can use "$test$EMPTY$test"
etc.

Hope this helps,
Ilya
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top