Perl / perl5

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

Bug report: infinite loop in `perl -c -e "e's a cm..\"frus..\""` #13152

Closed p5pRT closed 11 years ago

p5pRT commented 11 years ago

Migrated from rt.perl.org#119181 (status was 'rejected')

Searchable as RT119181$

p5pRT commented 11 years ago

From ericp@ActiveState.com

Created by ericp@activestate.com

Running `perl X.pl` or `perl -c X.pl` never halts\, where X.pl contains the following single line​:

e's a cm.."frus.."

Perl Info ``` Flags: category=core severity=low Site configuration information for perl 5.14.2: Configured by Debian Project at Tue Nov 27 00:34:23 UTC 2012. Summary of my perl5 (revision 5 version 14 subversion 2) configuration: Platform: osname=linux, osvers=2.6.42-32-generic, archname=x86_64-linux-gnu-thread-multi uname='linux allspice 2.6.42-32-generic #51-ubuntu smp wed sep 26 21:33:09 utc 2012 x86_64 x86_64 x86_64 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14 -Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2 -Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.14.2 -des' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -g', cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.6.3', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=, so=so, useshrplib=true, libperl=libperl.so.5.14.2 gnulibc_version='2.15' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector' Locally applied patches: @INC for perl 5.14.2: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl . Environment for perl 5.14.2: HOME=/home/ericp LANG=en_CA.UTF-8 LANGUAGE=en_CA:en LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/ericp/.local/bin:/home/ericp/opt/node-0.8.0/bin:/home/ericp/opt/ActivePython-2.7.2.5/bin:/home/ericp/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/ericp/svn/apps/komodo/util/black:/home/ericp/opt/ActivePython-3.2.2.3/bin:/home/ericp/opt/ActiveTcl8.5.12.0.296033/bin PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 11 years ago

From @Hugmeir

On Tue Aug 06 12​:26​:27 2013\, ericp wrote​:

This is a bug report for perl from ericp@​activestate.com\, generated with the help of perlbug 1.39 running under perl 5.14.2.

----------------------------------------------------------------- [Please describe your issue here]

Running `perl X.pl` or `perl -c X.pl` never halts\, where X.pl contains the following single line​:

e's a cm.."frus.."

[Please do not change anything below this line] ----------------------------------------------------------------- --- Flags​: category=core severity=low --- Site configuration information for perl 5.14.2​:

Configured by Debian Project at Tue Nov 27 00​:34​:23 UTC 2012.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration​:

Platform​: osname=linux\, osvers=2.6.42-32-generic\, archname=x86_64-linux- gnu-thread-multi uname='linux allspice 2.6.42-32-generic #51-ubuntu smp wed sep 26 21​:33​:09 utc 2012 x86_64 x86_64 x86_64 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14 -Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2 -Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.14.2 -des' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=define\, use64bitall=define\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler​: cc='cc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion=''\, gccversion='4.6.3'\, gccosandvers='' intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16 ivtype='long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=8\, prototype=define Linker and Libraries​: ld='cc'\, ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=\, so=so\, useshrplib=true\, libperl=libperl.so.5.14.2 gnulibc_version='2.15' Dynamic Linking​: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector'

Locally applied patches​:

--- @​INC for perl 5.14.2​: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .

--- Environment for perl 5.14.2​: HOME=/home/ericp LANG=en_CA.UTF-8 LANGUAGE=en_CA​:en LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/ericp/.local/bin​:/home/ericp/opt/node- 0.8.0/bin​:/home/ericp/opt/ActivePython-

2.7.2.5/bin​:/home/ericp/bin​:/usr/lib/lightdm/lightdm​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games​:/home/ericp/svn/apps/komodo/util/black​:/home/ericp/opt/ActivePython- 3.2.2.3/bin​:/home/ericp/opt/ActiveTcl8.5.12.0.296033/bin PERL_BADLANG (unset) SHELL=/bin/bash

This isn't really an infinite loop\, it's just going to take a long\, long time before it finishes. The "e's a" is a red herring (it's actually calling the method e​::s on 'a')\, the important bit is the cm.."frus.."\, which is creating a list of strings from "cm" to "zzzzzz" using the magic autoincrement.

This might be easier to see if you "deparse" it​:

a->e​::s( "cm".."frus.." );

Whose non-weird cousin might look like this​:

Alphabet->fill( "a".."z" );

This is similar to other constructs that take a long time\, like 1..1e10 or (1..100) x 1e8

Even though the autoincrement will try reaching "frus.." and fail\, since it'll always go through a-z and never use a period\, it's not an infinite loop because after "zzzzzz" it'll get "aaaaaaa"\, which is longer than the original string\, and stop there.

So I think this ticket can be closed\, since it's not really a bug (just a shoot-your-own-foot\, as it were).

--hugmeir

p5pRT commented 11 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 11 years ago

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

p5pRT commented 11 years ago

From @ikegami

On Tue\, Aug 6\, 2013 at 7​:49 PM\, Brian Fraser via RT \< perlbug-followup@​perl.org> wrote​:

On Tue Aug 06 12​:26​:27 2013\, ericp wrote​:

This is a bug report for perl from ericp@​activestate.com\, generated with the help of perlbug 1.39 running under perl 5.14.2.

Running `perl X.pl` or `perl -c X.pl` never halts\, where X.pl contains the following single line​:

e's a cm.."frus.."

This isn't really an infinite loop\, it's just going to take a long\, long time before it finishes. The "e's a" is a red herring (it's actually calling the method e​::s on 'a')\, the important bit is the cm.."frus.."\, which is creating a list of strings from "cm" to "zzzzzz" using the magic autoincrement.

This might be easier to see if you "deparse" it​:

a->e​::s( "cm".."frus.." );

Whose non-weird cousin might look like this​:

Alphabet->fill( "a".."z" );

This is similar to other constructs that take a long time\, like 1..1e10 or (1..100) x 1e8

Even though the autoincrement will try reaching "frus.." and fail\, since it'll always go through a-z and never use a period\, it's not an infinite loop because after "zzzzzz" it'll get "aaaaaaa"\, which is longer than the original string\, and stop there.

And the reason C\<\< perl -c X.pl >> never ends is that CONST..CONST is flattened at compile-time.

p5pRT commented 11 years ago

From ericp@ActiveState.com

Thanks for the explanation. I was thrown off by the second pair of ".."\, but that's just used to extend the second argument to ".." so it will take a long time to produce the list.

A more straightforward "f(cm..'fsur..')" exhibits the same behavior; yes\, that Ada-influenced single-quote was just a red herring.

p5pRT commented 11 years ago

From @nwc10

On Tue\, Aug 06\, 2013 at 11​:01​:52PM -0400\, Eric Brine wrote​:

On Tue\, Aug 6\, 2013 at 7​:49 PM\, Brian Fraser via RT \< perlbug-followup@​perl.org> wrote​:

On Tue Aug 06 12​:26​:27 2013\, ericp wrote​:

This is a bug report for perl from ericp@​activestate.com\, generated with the help of perlbug 1.39 running under perl 5.14.2.

Running `perl X.pl` or `perl -c X.pl` never halts\, where X.pl contains the following single line​:

e's a cm.."frus.."

This isn't really an infinite loop\, it's just going to take a long\, long time before it finishes. The "e's a" is a red herring (it's actually calling the method e​::s on 'a')\, the important bit is the cm.."frus.."\, which is creating a list of strings from "cm" to "zzzzzz" using the magic autoincrement.

This might be easier to see if you "deparse" it​:

a->e​::s( "cm".."frus.." );

Whose non-weird cousin might look like this​:

Alphabet->fill( "a".."z" );

This is similar to other constructs that take a long time\, like 1..1e10 or (1..100) x 1e8

Even though the autoincrement will try reaching "frus.." and fail\, since it'll always go through a-z and never use a period\, it's not an infinite loop because after "zzzzzz" it'll get "aaaaaaa"\, which is longer than the original string\, and stop there.

And the reason C\<\< perl -c X.pl >> never ends is that CONST..CONST is flattened at compile-time.

It would end (rather early\, with an out of memory error) if this code in pp_flop knew how to (attempt to) pre-extend the stack​:

  STRLEN len\, llen;   const char * const lpv = SvPV_nomg_const(left\, llen);   const char * const tmps = SvPV_nomg_const(right\, len);

  SV *sv = newSVpvn_flags(lpv\, llen\, SvUTF8(left)|SVs_TEMP);   while (!SvNIOKp(sv) && SvCUR(sv) \<= len) {   XPUSHs(sv);   if (strEQ(SvPVX_const(sv)\,tmps))   break;   sv = sv_2mortal(newSVsv(sv));   sv_inc(sv);   }

but it's quite hard to work out how many entries there will be in the range. For example\, "cm" .. ".." will be different from "c1" .. "..".

Nicholas Clark