Apparent bug in 5.8 wrt tied scalars

Discussion in 'Perl Misc' started by Eric J. Roode, Nov 19, 2005.

  1. -----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-----
    Eric J. Roode, Nov 19, 2005
    #1
    1. Advertising

  2. Eric J. Roode

    Paul Lalli Guest

    Eric J. Roode wrote:
    > 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
    Paul Lalli, Nov 23, 2005
    #2
    1. Advertising

  3. [A complimentary Cc of this posting was sent to
    Eric J. Roode
    <>], who wrote in article <Xns9713542B3A43Bsdn.comcast@216.196.97.136>:
    > 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
    Ilya Zakharevich, Nov 23, 2005
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Integer Software
    Replies:
    3
    Views:
    688
    Tejal Joshi \(MSFT\)
    Apr 19, 2004
  2. Bengt Richter
    Replies:
    3
    Views:
    279
    Steve Holden
    Jan 19, 2005
  3. Harold Yarmouth

    Apparent bug in FileLock

    Harold Yarmouth, Nov 19, 2008, in forum: Java
    Replies:
    1
    Views:
    321
    Harold Yarmouth
    Nov 20, 2008
  4. Bill Kelly
    Replies:
    6
    Views:
    333
    Bill Kelly
    Aug 27, 2004
  5. Ben Bullock
    Replies:
    4
    Views:
    176
    Ben Bullock
    Jul 13, 2008
Loading...

Share This Page