Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
2k stars 559 forks source link

inconsistent hash dereferencing #2335

Closed p5pRT closed 21 years ago

p5pRT commented 24 years ago

Migrated from rt.perl.org#3659 (status was 'resolved')

Searchable as RT3659$

p5pRT commented 24 years ago

From jtate@mi-messages.com

Created by jtate@adsrtp.com

I tried to retrieve a cookie from the hash returned from the CGI​:Cookie module using the following code​: --BEGIN CODE--   use constant AUTHENTCOOKIE => 'foo';   \<---SNIP-->   my %cookies = CGI​::Cookie->parse($request->header_in('Cookie'));   my $cookie = $cookies{AUTHENTCOOKIE}; --END CODE-- but never could get a value for $cookie. It was undefined\, even though there was a value referenced by AUTHENTCOOKIE in the hash. Eventually I had to replace the above code with the following​: --BEGIN CODE--   use constant AUTHENTCOOKIE => 'foo';   \<--SNIP-->   my %cookies = CGI​::Cookie->parse($request->header_in('Cookie'));   my $cookie;   foreach (keys %cookies){   if($_ eq AUTHENTCOOKIE){   $cookie = $cookies{$_};   }   } --END CODE-- which gave me a proper value for $cookie. I can't explain the behavior\, but I have been able to reproduce it in a smaller program​: --BEGIN CODE-- #!/usr/bin/perl

use CGI​::Cookie;

use constant NAME => 'crazystuff';

$cookie = CGI​::Cookie->new(-name => NAME\,   -value => {foo => 'FOO'\, bar => 'BAR'\,   mash => 'MASH'}\,   -path => '/'\,   -expires => '+1d'); %cookies = ( 'crazystuff' => $cookie);

$testcookie = $cookies{NAME}; print "cookie = $cookie. ref(cookie) = " . ref($cookie) . "\n"; print "testcookie = $testcookie. ref(testcookie) = " . ref($testcookie) . "\n";

foreach (keys %cookies){   print "foreach​:%cookies{$_} = $cookies{$_}\, ref = " .   ref($cookies{$_}) . "\n"; }

print "scalar​: cookie = $cookies{'crazystuff'}. ref = " .   ref($cookies{'crazystuff'}) . "\n"; --END CODE-- This should output the following since 'crazystuff' eq NAME​:

cookie = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu\, 10-Aug-2000 01 :44​:59 GMT. ref(cookie) = CGI​::Cookie testcookie = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu\, 10-Aug-200 0 01​:46​:02 GMT. ref(testcookie) = CGI​::Cookie foreach​:%cookies{crazystuff} = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expir es=Thu\, 10-Aug-2000 01​:45​:35 GMT\, ref = CGI​::Cookie scalar​: cookie = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu\, 10-Aug -2000 01​:45​:35 GMT. ref = CGI​::Cookie

It does not however. If configured as above\, it outputs​:

cookie = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu\, 10-Aug-2000 01 :50​:03 GMT. ref(cookie) = CGI​::Cookie testcookie = . ref(testcookie) = foreach​:%cookies{crazystuff} = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expir es=Thu\, 10-Aug-2000 01​:50​:03 GMT\, ref = CGI​::Cookie scalar​: cookie = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu\, 10-Aug -2000 01​:50​:03 GMT. ref = CGI​::Cookie

It is missing the testcookie definition. If configured so that %cookies = (NAME => $cookie);\, it returns​:

cookie = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu\, 10-Aug-2000 01 :46​:02 GMT. ref(cookie) = CGI​::Cookie testcookie = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu\, 10-Aug-200 0 01​:46​:02 GMT. ref(testcookie) = CGI​::Cookie foreach​:%cookies{NAME} = crazystuff=mash&MASH&foo&FOO&bar&BAR; path=/; expires=Thu \, 10-Aug-2000 01​:46​:02 GMT\, ref = CGI​::Cookie scalar​: cookie = . ref =

It is missing the scalar definition.

My analysis therefore is that there is a bug in the hash derefrencing operator which causes a static tick (') delimited string to not equal a constant string. This gives a null reference when trying to dereference by the value not used to create the hash.

Perl Info ``` Site configuration information for perl 5.00503: Configured by root at Wed Feb 2 15:34:50 EST 2000. Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration: Platform: osname=linux, osvers=2.2.5-22smp, archname=i386-linux uname='linux porky.devel.redhat.com 2.2.5-22smp #1 smp wed jun 2 09:11:51 edt 1999 i686 unknown ' hint=recommended, useposix=true, d_sigaction=define usethreads=undef useperlio=undef d_sfio=undef Compiler: cc='cc', optimize='-O2 -m486 -fno-strength-reduce', gccversion=egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) cppflags='-Dbool=char -DHAS_BOOL -I/usr/local/include' ccflags ='-Dbool=char -DHAS_BOOL -I/usr/local/include' stdchar='char', d_stdstdio=undef, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 alignbytes=4, usemymalloc=n, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldl -lm -lc -lposix -lcrypt libc=, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl 5.00503: /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005 . Environment for perl 5.00503: HOME=/home/jtate LANG=en_US LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=.:/home/jtate/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11R6/bin PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 24 years ago

From @tamias

On Tue\, Aug 08\, 2000 at 10​:01​:51PM -0400\, Joseph Tate wrote​:

I tried to retrieve a cookie from the hash returned from the CGI​:Cookie module using the following code​: --BEGIN CODE-- use constant AUTHENTCOOKIE => 'foo'; \<---SNIP--> my %cookies = CGI​::Cookie->parse($request->header_in('Cookie')); my $cookie = $cookies{AUTHENTCOOKIE}; --END CODE-- but never could get a value for $cookie. It was undefined\, even though there was a value referenced by AUTHENTCOOKIE in the hash.

$cookies{AUTHENTCOOKIE} looks up the key 'AUTHENTCOOKIE'\, not the key 'foo'. If you want to use a function call in a hash index\, you have to make it an expression\, instead of a bareword. For example​: $cookies{+AUTHENTCOOKIE}

Ronald