Perl / perl5

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

bleadperl@7050 late evaluation of $& #2614

Closed p5pRT closed 11 years ago

p5pRT commented 23 years ago

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

Searchable as RT4289$

p5pRT commented 23 years ago

From @vanstyn

crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' Uv crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | hd 00000000 00 55 17 0a crypt%

I'm not quite sure what it thinks it is printing here\, but it looks no more than a whisker shy of a coredump.

I don't know what this should be doing​: ideally it would say "bar"\, but other reasonable options are 'Use of uninitialised value at ...' (warning) or 'Too late for $& at ...' (fatal).

This is reproducible back to 5.004_05\, which for some reason prints '$&' - perhaps q{} doesn't exist yet in that version?

Hugo


Summary of my perl5 (revision 5.0 version 7 subversion 0) configuration​:   Platform​:   osname=linux\, osvers=2.2.5-16\, archname=i686-linux-64int   uname='linux crypt.compulink.co.uk 2.2.5-16 #1 sun may 30 23​:00​:18 bst 1999 i686 unknown '   config_args='-des -Doptimize=-g -O6 -Dprefix=/opt/bleadperl.64bit -Duse64bitint -Dusedevel'   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef   useperlio=undef d_sfio=undef uselargefiles=define   use64bitint=define use64bitall=undef uselongdouble=undef usesocks=undef   Compiler​:   cc='cc'\, optimize='-g -O6'\, gccversion=egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)\, gccosandvers=   cppflags='-DDEBUGGING -fno-strict-aliasing'   ccflags ='-DDEBUGGING -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'   stdchar='char'\, d_stdstdio=define\, usevfork=false   intsize=4\, longsize=4\, ptrsize=4\, doublesize=8   d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12   ivtype='long long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8   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 -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt -lutil   libc=/lib/libc-2.1.1.so\, 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'

Characteristics of this binary (from libperl)​:   Compile-time options​: DEBUGGING USE_64_BIT_INT USE_LARGE_FILES   Locally applied patches​:   DEVEL7050   Built under linux   Compiled at Sep 11 2000 11​:16​:16   @​INC​:   /opt/bleadperl.64bit/lib/5.7.0/i686-linux-64int   /opt/bleadperl.64bit/lib/5.7.0   /opt/bleadperl.64bit/lib/site_perl/5.7.0/i686-linux-64int   /opt/bleadperl.64bit/lib/site_perl/5.7.0   /opt/bleadperl.64bit/lib/site_perl   .

p5pRT commented 20 years ago

From @schwern

5.6.0 (OS X's) and 5.8.0 both print "$&" for me. 5.8.1 RC1 prints "(ev" which seems extremely wrong.

Obviously $& is pointing to some bit of memory that got deleted.

I'm upping the severity on this one as it screams memory leak.

p5pRT commented 20 years ago

From @schwern

This is pretty odd\, too

$ perl5.8.1 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' $& ;

Yep\, that's "$&\n;\n"

p5pRT commented 20 years ago

From @rgs

Michael G Schwern wrote​:

http​://bugs6.perl.org/rt2/Ticket/Display.html?id=4289 This one screams memory leak. Could someone investigate?

$ perl5.8.1 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' $& ;

$ perl5.8.1 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' (ev

Thats reads a chunk of memory that has been deleted (see valgrind report below). More precisely\, the subbeg doesn't appear to have been copied.

Adding a 'print $&' or changing the regexp to /(.*)/ works around the problem.

The un-copying of subbeg is due to PL_sawampersand not being set.

How to solve this ? Should we somehow disallow using $& in an eval(STRING) if it hasn't been seen in the compiled main program ? This sounds like the best option.

$ valgrind ./perl -wle '$foo="this";$foo=~/.*/;undef$foo;print eval q{$&}' ==5029== Memcheck\, a.k.a. Valgrind\, a memory error detector for x86-linux. ==5029== Copyright (C) 2002\, and GNU GPL'd\, by Julian Seward. ==5029== Using valgrind-1.9.6\, a program instrumentation system for x86-linux. ==5029== Copyright (C) 2000-2002\, and GNU GPL'd\, by Julian Seward. ==5029== Estimated CPU clock rate is 804 MHz ==5029== For more details\, rerun with​: -v ==5029== ==5029== Invalid read of size 1 ==5029== at 0x402FE515​: memmove (in /lib/libc-2.2.5.so) ==5029== by 0x80DCFEB​: Perl_sv_setpvn (sv.c​:4256) ==5029== by 0x80BCF0B​: Perl_magic_get (mg.c​:727) ==5029== by 0x80BBCA7​: Perl_mg_get (mg.c​:136) ==5029== Address 0x4118BA9C is 0 bytes inside a block of size 5 free'd ==5029== at 0x40165ACE​: free (vg_clientfuncs.c​:185) ==5029== by 0x80B4D67​: Perl_safesysfree (util.c​:143) ==5029== by 0x80EA6A0​: Perl_pp_undef (pp.c​:825) ==5029== by 0x80B449C​: Perl_runops_debug (dump.c​:1432) this ==5029== ==5029== ERROR SUMMARY​: 4 errors from 1 contexts (suppressed​: 0 from 0) ==5029== malloc/free​: in use at exit​: 52624 bytes in 696 blocks. ==5029== malloc/free​: 970 allocs\, 274 frees\, 74320 bytes allocated. ==5029== For a detailed leak analysis\, rerun with​: --leak-check=yes ==5029== For counts of detected errors\, rerun with​: -v

p5pRT commented 17 years ago

From @nwc10

Created by @nwc10

Jarkko found this back in 2005\, and it still appears to be an issue​:

$ cat badread.pl $_ = 'a'; s/a/xx/g; my $f = eval q{ $& }; __END__ $ valgrind --tool=memcheck --num-callers=20 ./perl badread.pl ==7550== Memcheck\, a memory error detector for x86-linux. ==7550== Copyright (C) 2002-2004\, and GNU GPL'd\, by Julian Seward et al. ==7550== Using valgrind-2.2.0\, a program supervision framework for x86-linux. ==7550== Copyright (C) 2000-2004\, and GNU GPL'd\, by Julian Seward et al. ==7550== For more details\, rerun with​: -v ==7550== ==7550== Invalid read of size 1 ==7550== at 0x1B9F7AFA​: memmove (in /lib/tls/libc-2.3.3.so) ==7550== by 0x808EFB8​: Perl_reg_numbered_buff_get (regcomp.c​:4769) ==7550== by 0x80B918B​: Perl_magic_get (mg.c​:885) ==7550== by 0x80B72A9​: Perl_mg_get (mg.c​:174) ==7550== by 0x80FF796​: Perl_sv_setsv_flags (sv.c​:3451) ==7550== by 0x810FFE7​: Perl_sv_mortalcopy (sv.c​:6838) ==7550== by 0x815DC23​: Perl_pp_leaveeval (pp_ctl.c​:3540) ==7550== by 0x80AB7C9​: Perl_runops_debug (dump.c​:1902) ==7550== by 0x80D544A​: S_run_body (perl.c​:2407) ==7550== by 0x80D4A94​: perl_run (perl.c​:2327) ==7550== by 0x805EAF2​: main (perlmain.c​:113) ==7550== Address 0x1BAD2DE0 is 0 bytes inside a block of size 4 free'd ==7550== at 0x1B903349​: free (vg_replace_malloc.c​:153) ==7550== by 0x80AC110​: Perl_safesysfree (util.c​:250) ==7550== by 0x80E9CDB​: Perl_pp_subst (pp_hot.c​:2274) ==7550== by 0x80AB7C9​: Perl_runops_debug (dump.c​:1902) ==7550== by 0x80D544A​: S_run_body (perl.c​:2407) ==7550== by 0x80D4A94​: perl_run (perl.c​:2327) ==7550== by 0x805EAF2​: main (perlmain.c​:113) ==7550== ==7550== ERROR SUMMARY​: 1 errors from 1 contexts (suppressed​: 25 from 1) ==7550== malloc/free​: in use at exit​: 82871 bytes in 568 blocks. ==7550== malloc/free​: 873 allocs\, 305 frees\, 108641 bytes allocated. ==7550== For a detailed leak analysis\, rerun with​: --leak-check=yes ==7550== For counts of detected errors\, rerun with​: -v

Perl Info ``` Flags: category=core severity=low Site configuration information for perl 5.9.5: Configured by nick at Thu Mar 1 14:44:38 CET 2007. Summary of my perl5 (revision 5 version 9 subversion 5) configuration: Platform: osname=linux, osvers=2.6.8.1-10mdk, archname=i686-linux uname='linux fangorn.maddingue.net 2.6.8.1-10mdk #1 wed sep 8 17:00:52 cest 2004 i686 amd athlon(tm) xp 2200+ unknown gnulinux ' config_args='-Dusedevel=y -Dcc=ccache gcc -Dld=gcc -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@ccl4.org -Dperladmin=nick@ccl4.org -Dinc_version_list= -Dinc_version_list_init=0 -Doptimize=-g -Uusethreads -Uuse64bitint -Uuselongdouble -Uusemymalloc -Duseperlio -Dprefix=~/Sandpit/snap5.9.x-30437 -Dinstallman1dir=none -Dinstallman3dir=none -de' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='ccache gcc', ccflags ='-DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='-g', cppflags='-DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lndbm -lgdbm -ldl -lm -lcrypt -lutil -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=/lib/libc-2.3.3.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.3.3' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: DEVEL @INC for perl 5.9.5: lib /home/nick/Sandpit/snap5.9.x-30437/lib/perl5/5.9.5/i686-linux /home/nick/Sandpit/snap5.9.x-30437/lib/perl5/5.9.5 /home/nick/Sandpit/snap5.9.x-30437/lib/perl5/site_perl/5.9.5/i686-linux /home/nick/Sandpit/snap5.9.x-30437/lib/perl5/site_perl/5.9.5 . Environment for perl 5.9.5: HOME=/home/nick LANG=fr_FR LANGUAGE=fr_FR:fr LC_ADDRESS=fr_FR LC_COLLATE=fr_FR LC_CTYPE=fr_FR LC_IDENTIFICATION=fr_FR LC_MEASUREMENT=fr_FR LC_MESSAGES=fr_FR LC_MONETARY=fr_FR LC_NAME=fr_FR LC_NUMERIC=fr_FR LC_PAPER=fr_FR LC_SOURCED=1 LC_TELEPHONE=fr_FR LC_TIME=fr_FR LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/nick/bin:/usr/local/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/sbin:/usr/games:/Applications/Java/default/bin:/usr/local/sbin:/sbin:/usr/sbin PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 17 years ago

From @nwc10

On Thu\, Mar 01\, 2007 at 06​:07​:26AM -0800\, Nicholas Clark wrote​:

Jarkko found this back in 2005\, and it still appears to be an issue​:

$ cat badread.pl $_ = 'a'; s/a/xx/g; my $f = eval q{ $& }; __END__

Jarkko added

: I'm afraid not. This one was actually found from t/op/subst.t\, and : curiously not from a single test case but instead from a combination : of two different test cases. The key *seems* to be a length-growing : s/// followed by an eval of $& AND an assignment of the eval result : to a lexical. But that's just my quick analysis and understanding. : The /g in the s/// is not needed\, it seems\, so this works equally : "well"​:

Nicholas Clark

p5pRT commented 15 years ago

From p5p@spam.wizbit.be

Not sure if this is fixed or not...

First one from Hugo​:

perl-5.8.8 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@​^A^T

perl-5.8.9-tobe -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@​M-*^S

perl-5.10.0 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&

perl-blead -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&

Second one from Hugo​:

perl-5.8.8 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@​^A^T

perl-5.8.9-tobe -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@​M-*^S

perl-5.10.0 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&

perl-blead -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&

The one from Schwern​:

perl-5.8.8 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v ^@​^A^T^H

perl-5.8.9-tobe -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v ^@​^@​^@​^@​

perl-5.10.0 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v ^@​M-Z^[@​

perl-blead -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v $& ;

p5pRT commented 13 years ago

From @cpansprout

On Mon Sep 11 12​:23​:39 2000\, hv@​crypt.compulink.co.uk wrote​:

crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' Uv crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | hd 00000000 00 55 17 0a crypt%

I'm not quite sure what it thinks it is printing here\, but it looks no more than a whisker shy of a coredump.

I don't know what this should be doing​: ideally it would say "bar"\, but other reasonable options are 'Use of uninitialised value at ...' (warning) or 'Too late for $& at ...' (fatal).

I think the variables should be undefined\, with perhaps a warning when they are accessed; but I have no idea what the wording or category should be.

p5pRT commented 11 years ago

From @cpansprout

On Mon Sep 11 12​:23​:39 2000\, hv@​crypt.compulink.co.uk wrote​:

crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' Uv crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | hd 00000000 00 55 17 0a crypt%

I'm not quite sure what it thinks it is printing here\, but it looks no more than a whisker shy of a coredump.

I don't know what this should be doing​: ideally it would say "bar"\, but other reasonable options are 'Use of uninitialised value at ...' (warning) or 'Too late for $& at ...' (fatal).

As of commit 1a904fc8 it does say bar. As is typical of me\, I put a typo in the commit message. The instructions for reënabling the bug say to use -Accflags=PERL_SAWAMPERSAND instead of -Accflags=-DPERL_SAWAMPERSAND.  

--

Father Chrysostomos

p5pRT commented 11 years ago

@cpansprout - Status changed from 'open' to 'resolved'