Perl / perl5

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

REGEXP bug in perl 5.6.1 #4242

Closed p5pRT closed 20 years ago

p5pRT commented 22 years ago

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

Searchable as RT7337$

p5pRT commented 22 years ago

From szhlys@yahoo.com

Hello\,

I have discovered what I belive is a bug in Perl version 5.6.1. At least\, the behavior is bizarre enough that I would appreciate knowing if this is supposed to be a feature.

The problem seems to lie in regexps with multi-line matching. I've written a small perl program (included) which demonstrates the bug and it can be reproduced. I have tried this on two different machines (x86 Solaris 8 & x86 Linux 2.4.4) with the same results.

The situation occurs when using /o in a regexp. Specifically I am using /mos\, and the bug does not show up if I change the regexp to /ms. My understanding is /o means 'compile pattern once'. But since I am doing this in a subroutine\, I was expecting the regexp to go out of scope when the subroutine ended.

What happens in test #2 is almost certainly a bug since I am passing in two different strings and the second string is being modified in a place where the first string had been changed. I think it's probably easier just to show an example output​:

============BEGIN TEST 1 ============ ModifyX()​: replace 'brown' with 'purple'

BEFORE​: The quick brown fox jumps over the lazy dawg

AFTER​: The quick purple fox jumps over the lazy dawg

====END ModifyX()====

ModifyX()​: replace 'over' with 'into'

BEFORE​: The quick purple fox jumps over the lazy dawg

AFTER​: The quick purple fox jumps over the lazy dawg

====END ModifyX()====

============BEGIN TEST 2 ============

===Replace 'brown' with 'purple'===

BEFORE​: The quick brown fox jumps over the lazy dawg

AFTER​: The quick purple fox jumps over the lazy dawg

==END ModAnyString()==

===Replace 'over' with 'into'===

BEFORE​: The quick brown fox jumps over the lazy dawg

AFTER​: The quick into fox jumps over the lazy dawg

==END ModAnyString()==

What follows is the program I wrote to do this test\, an output from running 'perl -Dr' to show the pattern matching\, and the obligatory dump as requested from 'perlbug'.

Thank you\,

Stuart Lory Zurich Switzerland

#!/usr/bin/perl

$X=$Y=$Z="The quick\nbrown fox jumps\nover the\nlazy dawg\n";

test1(); test2();

sub test1 {   print "============BEGIN TEST 1 ============\n";   ModifyX('brown'\,'purple');   ModifyX('over'\,'into'); } sub test2 {   print "============BEGIN TEST 2 ============\n";   ModAnyString($Y\,'brown'\,'purple');   ModAnyString($Z\,'over' \,'into' ); } sub ModifyX {   #   # specifically modifies $X   #   my ($old\,$new)=@​_;   print "ModifyX()​: replace '$old' with '$new'\n\n";   print "BEFORE​: $X";   $X=~s/\A(.+)$old/\1$new/mos;   print "\nAFTER​: $X\n====END ModifyX()====\n\n"; } sub ModAnyString {   #   # modifies first string in @​_   #   my ($target\,$old\,$new)=@​_;   print "\n===Replace '$old' with '$new'===\n\n";   print "BEFORE​: $target";   $target=~s/\A(.+)$old/\1$new/mos;   print "\nAFTER​: $target\n==END ModAnyString()==\n\n"; }

Script started on Wed 25 Jul 2001 03​:41​:33 AM MEST $ perl -Dr bug.pl Omitting $` $& $' support.

EXECUTING...

============BEGIN TEST 1 ============ ModifyX()​: replace 'brown' with 'purple'

BEFORE​: The quick brown fox jumps over the lazy dawg Compiling REx `\A(.+)brown' size 11 first at 2 rarest char w at 3   1​: SBOL(2)   2​: OPEN1(4)   4​: PLUS(6)   5​: SANY(0)   6​: CLOSE1(8)   8​: EXACT \(11)   11​: END(0) floating `brown' at 1..2147483647 (checking floating) anchored(SBOL) minlen 6 Guessing start of match\, REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg '... Found floating substr `brown' at offset 10... Guessed​: match at offset 0 Matching REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg '   Setting an EVAL scope\, savestack=22   0 \<> \<The quick br> | 1​: SBOL   0 \<> \<The quick br> | 2​: OPEN1   0 \<> \<The quick br> | 4​: PLUS   SANY can match 45 times out of 32767...   Setting an EVAL scope\, savestack=22   45 \<e lazy dawg

\<> | 6​: CLOSE1   45 \<e lazy dawg \<> | 8​: EXACT \   failed...   44 \<e lazy dawg> \< | 6​: CLOSE1   44 \<e lazy dawg> \< | 8​: EXACT \   failed...   43 \<e lazy daw> \<g | 6​: CLOSE1   43 \<e lazy daw> \<g | 8​: EXACT \   failed...   42 \<e lazy da> \<wg | 6​: CLOSE1   42 \<e lazy da> \<wg | 8​: EXACT \   failed...   41 \<e lazy d> \<awg | 6​: CLOSE1   41 \<e lazy d> \<awg | 8​: EXACT \   failed...   40 \<e lazy > \<dawg | 6​: CLOSE1   40 \<e lazy > \<dawg | 8​: EXACT \   failed...   39 \<e lazy> \< dawg | 6​: CLOSE1   39 \<e lazy> \< dawg | 8​: EXACT \   failed...   38 \<e laz> \<y dawg | 6​: CLOSE1   38 \<e laz> \<y dawg | 8​: EXACT \   failed...   37 \<he la> \ | 6​: CLOSE1   37 \<he la> \ | 8​: EXACT \   failed...   36 \<the l> \ | 6​: CLOSE1   36 \<the l> \ | 8​: EXACT \   failed...   35 \< the \ | 6​: CLOSE1   35 \< the \ | 8​: EXACT \   failed...   34 \ \< lazy d> | 6​: CLOSE1   34 \ \< lazy d> | 8​: EXACT \   failed...   33 \ \<e lazy > | 6​: CLOSE1   33 \ \<e lazy > | 8​: EXACT \   failed...   32 \ \<he lazy> | 6​: CLOSE1   32 \ \<he lazy> | 8​: EXACT \   failed...   31 \ \<the laz> | 6​: CLOSE1   31 \ \<the laz> | 8​: EXACT \   failed...   30 \< over> \< the la> | 6​: CLOSE1   30 \< over> \< the la> | 8​: EXACT \   failed...   29 \<s ove> \<r the l> | 6​: CLOSE1   29 \<s ove> \<r the l> | 8​: EXACT \   failed...   28 \<ps ov> \<er the | 6​: CLOSE1   28 \<ps ov> \<er the | 8​: EXACT \   failed...   27 \<mps o> \ | 6​: CLOSE1   27 \<mps o> \ | 8​: EXACT \   failed...   26 \<umps \ | 6​: CLOSE1   26 \<umps \ | 8​: EXACT \   failed...   25 \ \< over t> | 6​: CLOSE1   25 \ \< over t> | 8​: EXACT \   failed...   24 \< jump> \<s over > | 6​: CLOSE1   24 \< jump> \<s over > | 8​: EXACT \   failed...   23 \ \<ps over> | 6​: CLOSE1   23 \ \<ps over> | 8​: EXACT \   failed...   22 \ \<mps ove> | 6​: CLOSE1   22 \ \<mps ove> | 8​: EXACT \   failed...   21 \ \<umps ov> | 6​: CLOSE1   21 \ \<umps ov> | 8​: EXACT \   failed...   20 \< fox > \<jumps o> | 6​: CLOSE1   20 \< fox > \<jumps o> | 8​: EXACT \   failed...   19 \ \< jumps | 6​: CLOSE1   19 \ \< jumps | 8​: EXACT \   failed...   18 \ \ | 6​: CLOSE1   18 \ \ | 8​: EXACT \   failed...   17 \ \ | 6​: CLOSE1   17 \ \ | 8​: EXACT \   failed...   16 \ \ | 6​: CLOSE1   16 \ \ | 8​: EXACT \   failed...   15 \ \< fox ju> | 6​: CLOSE1   15 \ \< fox ju> | 8​: EXACT \   failed...   14 \< brow> \ | 6​: CLOSE1   14 \< brow> \ | 8​: EXACT \   failed...   13 \<k bro> \ | 6​: CLOSE1   13 \<k bro> \ | 8​: EXACT \   failed...   12 \<ck br> \ | 6​: CLOSE1   12 \<ck br> \ | 8​: EXACT \   failed...   11 \<ick b> \ | 6​: CLOSE1   11 \<ick b> \ | 8​: EXACT \   failed...   10 \<uick \ | 6​: CLOSE1   10 \<uick \ | 8​: EXACT \   15 \ \< fox ju> | 11​: END Match successful!

AFTER​: The quick purple fox jumps over the lazy dawg

====END ModifyX()====

ModifyX()​: replace 'over' with 'into'

BEFORE​: The quick purple fox jumps over the lazy dawg Guessing start of match\, REx `\A(.+)brown' against `The quick purple fox jumps over the lazy dawg '... Did not find floating substr `brown'... Match rejected by optimizer

AFTER​: The quick purple fox jumps over the lazy dawg

====END ModifyX()====

============BEGIN TEST 2 ============

===Replace 'brown' with 'purple'===

BEFORE​: The quick brown fox jumps over the lazy dawg Compiling REx `\A(.+)brown' size 11 first at 2 rarest char w at 3   1​: SBOL(2)   2​: OPEN1(4)   4​: PLUS(6)   5​: SANY(0)   6​: CLOSE1(8)   8​: EXACT \(11)   11​: END(0) floating `brown' at 1..2147483647 (checking floating) anchored(SBOL) minlen 6 Guessing start of match\, REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg '... Found floating substr `brown' at offset 10... Guessed​: match at offset 0 Matching REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg '   Setting an EVAL scope\, savestack=24   0 \<> \<The quick br> | 1​: SBOL   0 \<> \<The quick br> | 2​: OPEN1   0 \<> \<The quick br> | 4​: PLUS   SANY can match 45 times out of 32767...   Setting an EVAL scope\, savestack=24   45 \<e lazy dawg

\<> | 6​: CLOSE1   45 \<e lazy dawg \<> | 8​: EXACT \   failed...   44 \<e lazy dawg> \< | 6​: CLOSE1   44 \<e lazy dawg> \< | 8​: EXACT \   failed...   43 \<e lazy daw> \<g | 6​: CLOSE1   43 \<e lazy daw> \<g | 8​: EXACT \   failed...   42 \<e lazy da> \<wg | 6​: CLOSE1   42 \<e lazy da> \<wg | 8​: EXACT \   failed...   41 \<e lazy d> \<awg | 6​: CLOSE1   41 \<e lazy d> \<awg | 8​: EXACT \   failed...   40 \<e lazy > \<dawg | 6​: CLOSE1   40 \<e lazy > \<dawg | 8​: EXACT \   failed...   39 \<e lazy> \< dawg | 6​: CLOSE1   39 \<e lazy> \< dawg | 8​: EXACT \   failed...   38 \<e laz> \<y dawg | 6​: CLOSE1   38 \<e laz> \<y dawg | 8​: EXACT \   failed...   37 \<he la> \ | 6​: CLOSE1   37 \<he la> \ | 8​: EXACT \   failed...   36 \<the l> \ | 6​: CLOSE1   36 \<the l> \ | 8​: EXACT \   failed...   35 \< the \ | 6​: CLOSE1   35 \< the \ | 8​: EXACT \   failed...   34 \ \< lazy d> | 6​: CLOSE1   34 \ \< lazy d> | 8​: EXACT \   failed...   33 \ \<e lazy > | 6​: CLOSE1   33 \ \<e lazy > | 8​: EXACT \   failed...   32 \ \<he lazy> | 6​: CLOSE1   32 \ \<he lazy> | 8​: EXACT \   failed...   31 \ \<the laz> | 6​: CLOSE1   31 \ \<the laz> | 8​: EXACT \   failed...   30 \< over> \< the la> | 6​: CLOSE1   30 \< over> \< the la> | 8​: EXACT \   failed...   29 \<s ove> \<r the l> | 6​: CLOSE1   29 \<s ove> \<r the l> | 8​: EXACT \   failed...   28 \<ps ov> \<er the | 6​: CLOSE1   28 \<ps ov> \<er the | 8​: EXACT \   failed...   27 \<mps o> \ | 6​: CLOSE1   27 \<mps o> \ | 8​: EXACT \   failed...   26 \<umps \ | 6​: CLOSE1   26 \<umps \ | 8​: EXACT \   failed...   25 \ \< over t> | 6​: CLOSE1   25 \ \< over t> | 8​: EXACT \   failed...   24 \< jump> \<s over > | 6​: CLOSE1   24 \< jump> \<s over > | 8​: EXACT \   failed...   23 \ \<ps over> | 6​: CLOSE1   23 \ \<ps over> | 8​: EXACT \   failed...   22 \ \<mps ove> | 6​: CLOSE1   22 \ \<mps ove> | 8​: EXACT \   failed...   21 \ \<umps ov> | 6​: CLOSE1   21 \ \<umps ov> | 8​: EXACT \   failed...   20 \< fox > \<jumps o> | 6​: CLOSE1   20 \< fox > \<jumps o> | 8​: EXACT \   failed...   19 \ \< jumps | 6​: CLOSE1   19 \ \< jumps | 8​: EXACT \   failed...   18 \ \ | 6​: CLOSE1   18 \ \ | 8​: EXACT \   failed...   17 \ \ | 6​: CLOSE1   17 \ \ | 8​: EXACT \   failed...   16 \ \ | 6​: CLOSE1   16 \ \ | 8​: EXACT \   failed...   15 \ \< fox ju> | 6​: CLOSE1   15 \ \< fox ju> | 8​: EXACT \   failed...   14 \< brow> \ | 6​: CLOSE1   14 \< brow> \ | 8​: EXACT \   failed...   13 \<k bro> \ | 6​: CLOSE1   13 \<k bro> \ | 8​: EXACT \   failed...   12 \<ck br> \ | 6​: CLOSE1   12 \<ck br> \ | 8​: EXACT \   failed...   11 \<ick b> \ | 6​: CLOSE1   11 \<ick b> \ | 8​: EXACT \   failed...   10 \<uick \ | 6​: CLOSE1   10 \<uick \ | 8​: EXACT \   15 \ \< fox ju> | 11​: END Match successful!

AFTER​: The quick purple fox jumps over the lazy dawg

==END ModAnyString()==

===Replace 'over' with 'into'===

BEFORE​: The quick brown fox jumps over the lazy dawg Guessing start of match\, REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg '... Found floating substr `brown' at offset 10... Guessed​: match at offset 0 Matching REx `\A(.+)brown' against `The quick brown fox jumps over the lazy dawg '   Setting an EVAL scope\, savestack=24   0 \<> \<The quick br> | 1​: SBOL   0 \<> \<The quick br> | 2​: OPEN1   0 \<> \<The quick br> | 4​: PLUS   SANY can match 45 times out of 32767...   Setting an EVAL scope\, savestack=24   45 \<e lazy dawg

\<> | 6​: CLOSE1   45 \<e lazy dawg \<> | 8​: EXACT \   failed...   44 \<e lazy dawg> \< | 6​: CLOSE1   44 \<e lazy dawg> \< | 8​: EXACT \   failed...   43 \<e lazy daw> \<g | 6​: CLOSE1   43 \<e lazy daw> \<g | 8​: EXACT \   failed...   42 \<e lazy da> \<wg | 6​: CLOSE1   42 \<e lazy da> \<wg | 8​: EXACT \   failed...   41 \<e lazy d> \<awg | 6​: CLOSE1   41 \<e lazy d> \<awg | 8​: EXACT \   failed...   40 \<e lazy > \<dawg | 6​: CLOSE1   40 \<e lazy > \<dawg | 8​: EXACT \   failed...   39 \<e lazy> \< dawg | 6​: CLOSE1   39 \<e lazy> \< dawg | 8​: EXACT \   failed...   38 \<e laz> \<y dawg | 6​: CLOSE1   38 \<e laz> \<y dawg | 8​: EXACT \   failed...   37 \<he la> \ | 6​: CLOSE1   37 \<he la> \ | 8​: EXACT \   failed...   36 \<the l> \ | 6​: CLOSE1   36 \<the l> \ | 8​: EXACT \   failed...   35 \< the \ | 6​: CLOSE1   35 \< the \ | 8​: EXACT \   failed...   34 \ \< lazy d> | 6​: CLOSE1   34 \ \< lazy d> | 8​: EXACT \   failed...   33 \ \<e lazy > | 6​: CLOSE1   33 \ \<e lazy > | 8​: EXACT \   failed...   32 \ \<he lazy> | 6​: CLOSE1   32 \ \<he lazy> | 8​: EXACT \   failed...   31 \ \<the laz> | 6​: CLOSE1   31 \ \<the laz> | 8​: EXACT \   failed...   30 \< over> \< the la> | 6​: CLOSE1   30 \< over> \< the la> | 8​: EXACT \   failed...   29 \<s ove> \<r the l> | 6​: CLOSE1   29 \<s ove> \<r the l> | 8​: EXACT \   failed...   28 \<ps ov> \<er the | 6​: CLOSE1   28 \<ps ov> \<er the | 8​: EXACT \   failed...   27 \<mps o> \ | 6​: CLOSE1   27 \<mps o> \ | 8​: EXACT \   failed...   26 \<umps \ | 6​: CLOSE1   26 \<umps \ | 8​: EXACT \   failed...   25 \ \< over t> | 6​: CLOSE1   25 \ \< over t> | 8​: EXACT \   failed...   24 \< jump> \<s over > | 6​: CLOSE1   24 \< jump> \<s over > | 8​: EXACT \   failed...   23 \ \<ps over> | 6​: CLOSE1   23 \ \<ps over> | 8​: EXACT \   failed...   22 \ \<mps ove> | 6​: CLOSE1   22 \ \<mps ove> | 8​: EXACT \   failed...   21 \ \<umps ov> | 6​: CLOSE1   21 \ \<umps ov> | 8​: EXACT \   failed...   20 \< fox > \<jumps o> | 6​: CLOSE1   20 \< fox > \<jumps o> | 8​: EXACT \   failed...   19 \ \< jumps | 6​: CLOSE1   19 \ \< jumps | 8​: EXACT \   failed...   18 \ \ | 6​: CLOSE1   18 \ \ | 8​: EXACT \   failed...   17 \ \ | 6​: CLOSE1   17 \ \ | 8​: EXACT \   failed...   16 \ \ | 6​: CLOSE1   16 \ \ | 8​: EXACT \   failed...   15 \ \< fox ju> | 6​: CLOSE1   15 \ \< fox ju> | 8​: EXACT \   failed...   14 \< brow> \ | 6​: CLOSE1   14 \< brow> \ | 8​: EXACT \   failed...   13 \<k bro> \ | 6​: CLOSE1   13 \<k bro> \ | 8​: EXACT \   failed...   12 \<ck br> \ | 6​: CLOSE1   12 \<ck br> \ | 8​: EXACT \   failed...   11 \<ick b> \ | 6​: CLOSE1   11 \<ick b> \ | 8​: EXACT \   failed...   10 \<uick \ | 6​: CLOSE1   10 \<uick \ | 8​: EXACT \   15 \ \< fox ju> | 11​: END Match successful!

AFTER​: The quick into fox jumps over the lazy dawg

==END ModAnyString()==

$ exit script done on Wed 25 Jul 2001 03​:41​:41 AM MEST


Flags​:   category=   severity=


Site configuration information for perl v5.6.1​:

Configured by stuart at Sun Jul 22 02​:48​:43 MEST 2001.

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration​:   Platform​:   osname=solaris\, osvers=2.8\, archname=i86pc-solaris   uname='sunos oryx 5.8 generic_108529-05 i86pc i386 i86pc '   config_args='-Dcc=gcc'   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef   useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef   use64bitint=undef use64bitall=undef uselongdouble=undef   Compiler​:   cc='gcc'\, ccflags ='-DDEBUGGING -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\,   optimize='-O'\,   cppflags='-DDEBUGGING'   ccversion=''\, gccversion='2.95.2 19991024 (release)'\, gccosandvers='solaris2.8'   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\, usemymalloc=y\, prototype=define   Linker and Libraries​:   ld='gcc'\, ldflags =' -L/usr/local/lib '   libpth=/usr/local/lib /usr/lib /usr/ccs/lib   libs=-lsocket -lnsl -ldl -lm -lc   perllibs=-lsocket -lnsl -ldl -lm -lc   libc=/lib/libc.so\, so=so\, useshrplib=false\, libperl=libperl.a   Dynamic Linking​:   dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags=' '   cccdlflags='-fPIC'\, lddlflags='-G -L/usr/local/lib'

Locally applied patches​:  


@​INC for perl v5.6.1​:   /usr/local/lib/perl5/5.6.1/i86pc-solaris   /usr/local/lib/perl5/5.6.1   /usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris   /usr/local/lib/perl5/site_perl/5.6.1   /usr/local/lib/perl5/site_perl   .


Environment for perl v5.6.1​:   HOME=/home/stuart   LANG=en_US.ISO8859-1   LANGUAGE (unset)   LC_COLLATE=en_US.ISO8859-1   LC_CTYPE=en_US.ISO8859-1   LC_MESSAGES=C   LC_MONETARY=en_US.ISO8859-1   LC_NUMERIC=en_US.ISO8859-1   LC_TIME=en_US.ISO8859-1   LD_LIBRARY_PATH (unset)   LOGDIR (unset)  
PATH=/usr/samba/bin​:/opt/sfw/gnome/bin​:/usr/j2se/bin​:/opt/SUNWspro/bin​:/usr/ccs/bin​:/opt/sfw/bin​:/sbin​:/usr/sbin​:/usr/bin​:/usr/dt/bin​:/usr/openwin/bin​:/bin​:/usr/ucb​:/usr/local/bin​:.   PERL_BADLANG (unset)   SHELL=/bin/ksh

Complete configuration data for perl v5.6.1​:

Author='' CONFIG='true' CONFIGDOTSH='true' Date='$Date' Header='' Id='$Id' Locker='' Log='$Log' Mcc='Mcc' PATCHLEVEL='6' PERL_API_REVISION='5' PERL_API_SUBVERSION='0' PERL_API_VERSION='5' PERL_REVISION='5' PERL_SUBVERSION='1' PERL_VERSION='6' RCSfile='$RCSfile' Revision='$Revision' SUBVERSION='1' Source='' State='' _a='.a' _exe='' _o='.o' afs='false' alignbytes='4' ansi2knr='' aphostname='/usr/bin/hostname' api_revision='5' api_subversion='0' api_version='5' api_versionstring='5.005' ar='ar' archlib='/usr/local/lib/perl5/5.6.1/i86pc-solaris' archlibexp='/usr/local/lib/perl5/5.6.1/i86pc-solaris' archname='i86pc-solaris' archname64='' archobjs='' awk='awk' baserev='5.0' bash='' bin='/usr/local/bin' bincompat5005='define' binexp='/usr/local/bin' bison='bison' byacc='byacc' byteorder='1234' c='\c' castflags='0' cat='cat' cc='gcc' cccdlflags='-fPIC' ccdlflags=' ' ccflags='-DDEBUGGING -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' ccflags_uselargefiles='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' ccname='gcc' ccsymbols='__GNUC__=2 __GNUC_MINOR__=95 __i386=1 __i386__=1 __sun=1 __sun__=1 __SVR4=1 __svr4__=1 __unix=1 __unix__=1 cpu=i386 machine=i386 system=svr4' ccversion='' cf_by='stuart' cf_email='stuart@​oryx.onyx.ch' cf_time='Sun Jul 22 02​:48​:43 MEST 2001' charsize='1' chgrp='' chmod='' chown='' clocktype='clock_t' comm='comm' compress='' config_arg0='Configure' config_arg1='-Dcc=gcc' config_argc='1' config_args='-Dcc=gcc' contains='grep' cp='cp' cpio='' cpp='cpp' cpp_stuff='42' cppccsymbols='i386=1 sun=1 unix=1' cppflags='-DDEBUGGING' cpplast='-' cppminus='-' cpprun='gcc -E' cppstdin='gcc -E' cppsymbols='_FILE_OFFSET_BITS=64 __GNUC__=2 __GNUC_MINOR__=95 __i386=1 __i386__=1 _ILP32=1 _LARGEFILE64_SOURCE=1 _LARGEFILE_SOURCE=1 _LITTLE_ENDIAN=1 __STDC__=1 __sun=1 __sun__=1 __SVR4=1 __svr4__=1 __unix=1 __unix__=1' crosscompile='' cryptlib='' csh='csh' d_Gconvert='gconvert((x)\,(n)\,(t)\,(b))' d_PRIEUldbl='define' d_PRIFUldbl='define' d_PRIGUldbl='define' d_PRIXU64='define' d_PRId64='define' d_PRIeldbl='define' d_PRIfldbl='define' d_PRIgldbl='define' d_PRIi64='define' d_PRIo64='define' d_PRIu64='define' d_PRIx64='define' d_SCNfldbl='define' d__fwalk='' d_access='define' d_accessx='' d_alarm='define' d_archlib='define' d_atolf='' d_atoll='define' d_attribut='define' d_bcmp='define' d_bcopy='define' d_bincompat5005='define' d_bsd='' d_bsdgetpgrp='' d_bsdsetpgrp='' d_bzero='define' d_casti32='' d_castneg='define' d_charvspr='' d_chown='define' d_chroot='define' d_chsize='' d_closedir='define' d_const='define' d_crypt='define' d_csh='define' d_cuserid='define' d_dbl_dig='define' d_difftime='define' d_dirnamlen='' d_dlerror='define' d_dlopen='define' d_dlsymun='' d_dosuid='' d_drand48proto='define' d_dup2='define' d_eaccess='' d_endgrent='define' d_endhent='define' d_endnent='define' d_endpent='define' d_endpwent='define' d_endsent='define' d_eofnblk='define' d_eunice='' d_fchmod='define' d_fchown='define' d_fcntl='define' d_fcntl_can_lock='define' d_fd_macros='define' d_fd_set='define' d_fds_bits='define' d_fgetpos='define' d_flexfnam='define' d_flock='' d_fork='define' d_fpathconf='define' d_fpos64_t='define' d_frexpl='' d_fs_data_s='' d_fseeko='define' d_fsetpos='define' d_fstatfs='define' d_fstatvfs='define' d_fsync='define' d_ftello='define' d_ftime='' d_getcwd='define' d_getespwnam='' d_getfsstat='' d_getgrent='define' d_getgrps='define' d_gethbyaddr='define' d_gethbyname='define' d_gethent='define' d_gethname='define' d_gethostprotos='define' d_getlogin='define' d_getmnt='' d_getmntent='define' d_getnbyaddr='define' d_getnbyname='define' d_getnent='define' d_getnetprotos='define' d_getpagsz='define' d_getpbyname='define' d_getpbynumber='define' d_getpent='define' d_getpgid='define' d_getpgrp='define' d_getpgrp2='' d_getppid='define' d_getprior='define' d_getprotoprotos='define' d_getprpwnam='' d_getpwent='define' d_getsbyname='define' d_getsbyport='define' d_getsent='define' d_getservprotos='define' d_getspnam='define' d_gettimeod='define' d_gnulibc='' d_grpasswd='define' d_hasmntopt='define' d_htonl='define' d_iconv='define' d_index='' d_inetaton='' d_int64_t='define' d_isascii='define' d_isnan='define' d_isnanl='' d_killpg='define' d_lchown='define' d_ldbl_dig='define' d_link='define' d_locconv='define' d_lockf='define' d_longdbl='define' d_longlong='define' d_lseekproto='define' d_lstat='define' d_madvise='define' d_mblen='define' d_mbstowcs='define' d_mbtowc='define' d_memchr='define' d_memcmp='define' d_memcpy='define' d_memmove='define' d_memset='define' d_mkdir='define' d_mkdtemp='' d_mkfifo='define' d_mkstemp='define' d_mkstemps='' d_mktime='define' d_mmap='define' d_modfl='' d_mprotect='define' d_msg='define' d_msg_ctrunc='define' d_msg_dontroute='define' d_msg_oob='define' d_msg_peek='define' d_msg_proxy='' d_msgctl='define' d_msgget='define' d_msgrcv='define' d_msgsnd='define' d_msync='define' d_munmap='define' d_mymalloc='define' d_nice='define' d_nv_preserves_uv='define' d_nv_preserves_uv_bits='32' d_off64_t='define' d_old_pthread_create_joinable='' d_oldpthreads='' d_oldsock='' d_open3='define' d_pathconf='define' d_pause='define' d_perl_otherlibdirs='' d_phostname='' d_pipe='define' d_poll='define' d_portable='define' d_pthread_yield='' d_pwage='define' d_pwchange='' d_pwclass='' d_pwcomment='define' d_pwexpire='' d_pwgecos='define' d_pwpasswd='define' d_pwquota='' d_qgcvt='define' d_quad='define' d_readdir='define' d_readlink='define' d_rename='define' d_rewinddir='define' d_rmdir='define' d_safebcpy='define' d_safemcpy='' d_sanemcmp='define' d_sbrkproto='define' d_sched_yield='' d_scm_rights='define' d_seekdir='define' d_select='define' d_sem='define' d_semctl='define' d_semctl_semid_ds='define' d_semctl_semun='define' d_semget='define' d_semop='define' d_setegid='define' d_seteuid='define' d_setgrent='define' d_setgrps='define' d_sethent='define' d_setlinebuf='define' d_setlocale='define' d_setnent='define' d_setpent='define' d_setpgid='define' d_setpgrp='define' d_setpgrp2='' d_setprior='define' d_setproctitle='' d_setpwent='define' d_setregid='define' d_setresgid='' d_setresuid='' d_setreuid='define' d_setrgid='' d_setruid='' d_setsent='define' d_setsid='define' d_setvbuf='define' d_sfio='' d_shm='define' d_shmat='define' d_shmatprototype='define' d_shmctl='define' d_shmdt='define' d_shmget='define' d_sigaction='define' d_sigsetjmp='define' d_socket='define' d_socklen_t='define' d_sockpair='define' d_socks5_init='' d_sqrtl='' d_statblks='define' d_statfs_f_flags='' d_statfs_s='define' d_statvfs='define' d_stdio_cnt_lval='define' d_stdio_ptr_lval='define' d_stdio_ptr_lval_nochange_cnt='define' d_stdio_ptr_lval_sets_cnt='' d_stdio_stream_array='define' d_stdiobase='define' d_stdstdio='define' d_strchr='define' d_strcoll='define' d_strctcpy='define' d_strerrm='strerror(e)' d_strerror='define' d_strtod='define' d_strtol='define' d_strtold='' d_strtoll='define' d_strtoul='define' d_strtoull='define' d_strtouq='' d_strxfrm='define' d_suidsafe='define' d_symlink='define' d_syscall='define' d_sysconf='define' d_sysernlst='' d_syserrlst='define' d_system='define' d_tcgetpgrp='define' d_tcsetpgrp='define' d_telldir='define' d_telldirproto='define' d_time='define' d_times='define' d_truncate='define' d_tzname='define' d_umask='define' d_uname='define' d_union_semun='' d_ustat='define' d_vendorarch='' d_vendorbin='' d_vendorlib='' d_vfork='' d_void_closedir='' d_voidsig='define' d_voidtty='' d_volatile='define' d_vprintf='define' d_wait4='define' d_waitpid='define' d_wcstombs='define' d_wctomb='define' d_xenix='' date='date' db_hashtype='u_int32_t' db_prefixtype='size_t' defvoidused='15' direntrytype='struct dirent' dlext='so' dlsrc='dl_dlopen.xs' doublesize='8' drand01='drand48()' dynamic_ext='B ByteLoader Data/Dumper Devel/DProf Devel/Peek Fcntl File/Glob IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket Sys/Hostname Sys/Syslog attrs re' eagain='EAGAIN' ebcdic='' echo='echo' egrep='egrep' emacs='' eunicefix='​:' exe_ext='' expr='expr' extensions='B ByteLoader Data/Dumper Devel/DProf Devel/Peek Fcntl File/Glob IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket Sys/Hostname Sys/Syslog attrs re Errno' fflushNULL='' fflushall='' find='' firstmakefile='makefile' flex='' fpossize='8' fpostype='fpos_t' freetype='void' full_ar='/usr/ccs/bin/ar' full_csh='/usr/bin/csh' full_sed='/usr/bin/sed' gccosandvers='solaris2.8' gccversion='2.95.2 19991024 (release)' gidformat='"ld"' gidsign='-1' gidsize='4' gidtype='gid_t' glibpth='/usr/shlib /usr/lib /usr/lib/386 /lib/386 /usr/ccs/lib /usr/local/lib' grep='grep' groupcat='cat /etc/group' groupstype='gid_t' gzip='gzip' h_fcntl='true' h_sysfile='false' hint='recommended' hostcat='cat /etc/hosts' i16size='2' i16type='short' i32size='4' i32type='long' i64size='8' i64type='long long' i8size='1' i8type='char' i_arpainet='define' i_bsdioctl='' i_db='' i_dbm='' i_dirent='define' i_dld='' i_dlfcn='define' i_fcntl='define' i_float='define' i_gdbm='' i_grp='define' i_iconv='define' i_ieeefp='define' i_inttypes='define' i_libutil='' i_limits='define' i_locale='define' i_machcthr='' i_malloc='define' i_math='define' i_memory='' i_mntent='' i_ndbm='define' i_netdb='define' i_neterrno='' i_netinettcp='define' i_niin='define' i_poll='define' i_prot='' i_pthread='define' i_pwd='define' i_rpcsvcdbm='define' i_sfio='' i_sgtty='' i_shadow='define' i_socks='' i_stdarg='define' i_stddef='define' i_stdlib='define' i_string='define' i_sunmath='' i_sysaccess='' i_sysdir='' i_sysfile='' i_sysfilio='define' i_sysin='' i_sysioctl='define' i_syslog='define' i_sysmman='define' i_sysmode='define' i_sysmount='define' i_sysndir='' i_sysparam='define' i_sysresrc='define' i_syssecrt='' i_sysselct='define' i_syssockio='' i_sysstat='define' i_sysstatfs='define' i_sysstatvfs='define' i_systime='define' i_systimek='' i_systimes='define' i_systypes='define' i_sysuio='define' i_sysun='define' i_sysutsname='define' i_sysvfs='define' i_syswait='define' i_termio='' i_termios='define' i_time='' i_unistd='define' i_ustat='define' i_utime='define' i_values='define' i_varargs='' i_varhdr='stdarg.h' i_vfork='' ignore_versioned_solibs='' inc_version_list=' ' inc_version_list_init='0' incpath='' inews='' installarchlib='/usr/local/lib/perl5/5.6.1/i86pc-solaris' installbin='/usr/local/bin' installman1dir='/usr/local/man/man1' installman3dir='/usr/local/man/man3' installprefix='/usr/local' installprefixexp='/usr/local' installprivlib='/usr/local/lib/perl5/5.6.1' installscript='/usr/local/bin' installsitearch='/usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris' installsitebin='/usr/local/bin' installsitelib='/usr/local/lib/perl5/site_perl/5.6.1' installstyle='lib/perl5' installusrbinperl='define' installvendorarch='' installvendorbin='' installvendorlib='' intsize='4' issymlink='test -h' ivdformat='"ld"' ivsize='4' ivtype='long' known_extensions='B ByteLoader DB_File Data/Dumper Devel/DProf Devel/Peek Fcntl File/Glob GDBM_File IO IPC/SysV NDBM_File ODBM_File Opcode POSIX SDBM_File Socket Sys/Hostname Sys/Syslog Thread attrs re' ksh='' ld='gcc' lddlflags='-G -L/usr/local/lib' ldflags=' -L/usr/local/lib ' ldflags_uselargefiles='' ldlibpthname='LD_LIBRARY_PATH' less='less' lib_ext='.a' libc='/lib/libc.so' libperl='libperl.a' libpth='/usr/local/lib /usr/lib /usr/ccs/lib' libs='-lsocket -lnsl -ldl -lm -lc' libsdirs=' /usr/lib' libsfiles=' libsocket.so.1 libnsl.so.1 libdl.so.1 libm.so.1 libc.so.1' libsfound=' /usr/lib/libsocket.so.1 /usr/lib/libnsl.so.1 /usr/lib/libdl.so.1 /usr/lib/libm.so.1 /usr/lib/libc.so.1' libspath=' /usr/local/lib /usr/lib /usr/ccs/lib' libswanted='sfio socket bind inet nsl nm ndbm gdbm dbm db dl dld sun m c cposix posix ndir dir bsd BSD PW x iconv util ' libswanted_uselargefiles='' line='' lint='' lkflags='' ln='ln' lns='/usr/bin/ln -s' locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include' loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib' longdblsize='12' longlongsize='8' longsize='4' lp='' lpr='' ls='ls' lseeksize='8' lseektype='off_t' mail='' mailx='' make='make' make_set_make='#' mallocobj='malloc.o' mallocsrc='malloc.c' malloctype='void *' man1dir='/usr/local/man/man1' man1direxp='/usr/local/man/man1' man1ext='1' man3dir='/usr/local/man/man3' man3direxp='/usr/local/man/man3' man3ext='3' mips_type='' mkdir='mkdir' mmaptype='caddr_t' modetype='mode_t' more='more' multiarch='' mv='' myarchname='i86pc-solaris' mydomain='.onyx.ch' myhostname='oryx' myuname='sunos oryx 5.8 generic_108529-05 i86pc i386 i86pc ' n='' netdb_hlen_type='int' netdb_host_type='const char *' netdb_name_type='const char *' netdb_net_type='in_addr_t' nm='nm' nm_opt='-p' nm_so_opt='' nonxs_ext='Errno' nroff='nroff' nvEUformat='"E"' nvFUformat='"F"' nvGUformat='"G"' nveformat='"e"' nvfformat='"f"' nvgformat='"g"' nvsize='8' nvtype='double' o_nonblock='O_NONBLOCK' obj_ext='.o' old_pthread_create_joinable='' optimize='-O' orderlib='false' osname='solaris' osvers='2.8' otherlibdirs=' ' package='perl5' pager='/usr/bin/less' passcat='cat /etc/passwd' patchlevel='6' path_sep='​:' perl='' perl5='/usr/local/bin/perl' perladmin='stuart@​oryx.onyx.ch' perllibs='-lsocket -lnsl -ldl -lm -lc' perlpath='/usr/local/bin/perl' pg='pg' phostname='hostname' pidtype='pid_t' plibpth='' pm_apiversion='5.005' pmake='' pr='' prefix='/usr/local' prefixexp='/usr/local' privlib='/usr/local/lib/perl5/5.6.1' privlibexp='/usr/local/lib/perl5/5.6.1' prototype='define' ptrsize='4' quadkind='3' quadtype='long long' randbits='48' randfunc='drand48' randseedtype='long' ranlib='​:' rd_nodata='-1' revision='5' rm='rm' rmail='' runnm='true' sPRIEUldbl='"LE"' sPRIFUldbl='"LF"' sPRIGUldbl='"LG"' sPRIXU64='"llX"' sPRId64='"lld"' sPRIeldbl='"Le"' sPRIfldbl='"Lf"' sPRIgldbl='"Lg"' sPRIi64='"lli"' sPRIo64='"llo"' sPRIu64='"llu"' sPRIx64='"llx"' sSCNfldbl='"Lf"' sched_yield='' scriptdir='/usr/local/bin' scriptdirexp='/usr/local/bin' sed='sed' seedfunc='srand48' selectminbits='32' selecttype='fd_set *' sendmail='' sh='/bin/sh' shar='' sharpbang='#!' shmattype='void *' shortsize='2' shrpenv='' shsharp='true' sig_count='46' sig_name='ZERO HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1 USR2 CHLD PWR WINCH URG IO STOP TSTP CONT TTIN TTOU VTALRM PROF XCPU XFSZ WAITING LWP FREEZE THAW CANCEL LOST RTMIN NUM39 NUM40 NUM41 NUM42 NUM43 NUM44 RTMAX IOT CLD POLL ' sig_name_init='"ZERO"\, "HUP"\, "INT"\, "QUIT"\, "ILL"\, "TRAP"\, "ABRT"\, "EMT"\, "FPE"\, "KILL"\, "BUS"\, "SEGV"\, "SYS"\, "PIPE"\, "ALRM"\, "TERM"\, "USR1"\, "USR2"\, "CHLD"\, "PWR"\, "WINCH"\, "URG"\, "IO"\, "STOP"\, "TSTP"\, "CONT"\, "TTIN"\, "TTOU"\, "VTALRM"\, "PROF"\, "XCPU"\, "XFSZ"\, "WAITING"\, "LWP"\, "FREEZE"\, "THAW"\, "CANCEL"\, "LOST"\, "RTMIN"\, "NUM39"\, "NUM40"\, "NUM41"\, "NUM42"\, "NUM43"\, "NUM44"\, "RTMAX"\, "IOT"\, "CLD"\, "POLL"\, 0' sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 6 18 22 ' sig_num_init='0\, 1\, 2\, 3\, 4\, 5\, 6\, 7\, 8\, 9\, 10\, 11\, 12\, 13\, 14\, 15\, 16\, 17\, 18\, 19\, 20\, 21\, 22\, 23\, 24\, 25\, 26\, 27\, 28\, 29\, 30\, 31\, 32\, 33\, 34\, 35\, 36\, 37\, 38\, 39\, 40\, 41\, 42\, 43\, 44\, 45\, 6\, 18\, 22\, 0' signal_t='void' sitearch='/usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris' sitearchexp='/usr/local/lib/perl5/site_perl/5.6.1/i86pc-solaris' sitebin='/usr/local/bin' sitebinexp='/usr/local/bin' sitelib='/usr/local/lib/perl5/site_perl/5.6.1' sitelib_stem='/usr/local/lib/perl5/site_perl' sitelibexp='/usr/local/lib/perl5/site_perl/5.6.1' siteprefix='/usr/local' siteprefixexp='/usr/local' sizesize='4' sizetype='size_t' sleep='' smail='' so='so' sockethdr='' socketlib='' socksizetype='int' sort='sort' spackage='Perl5' spitshell='cat' src='.' ssizetype='ssize_t' startperl='#!/usr/local/bin/perl' startsh='#!/bin/sh' static_ext=' ' stdchar='unsigned char' stdio_base='((fp)->_base)' stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)' stdio_cnt='((fp)->_cnt)' stdio_filbuf='' stdio_ptr='((fp)->_ptr)' stdio_stream_array='__iob' strings='/usr/include/string.h' submit='' subversion='1' sysman='/usr/man/man1' tail='' tar='' tbl='' tee='' test='test' timeincl='/usr/include/sys/time.h ' timetype='time_t' touch='touch' tr='tr' trnl='\n' troff='' u16size='2' u16type='unsigned short' u32size='4' u32type='unsigned long' u64size='8' u64type='unsigned long long' u8size='1' u8type='unsigned char' uidformat='"ld"' uidsign='-1' uidsize='4' uidtype='uid_t' uname='uname' uniq='uniq' uquadtype='unsigned long long' use5005threads='' use64bitall='' use64bitint='' usedl='define' useithreads='' uselargefiles='define' uselongdouble='' usemorebits='' usemultiplicity='' usemymalloc='y' usenm='true' useopcode='true' useperlio='' useposix='true' usesfio='false' useshrplib='false' usesocks='' usethreads='' usevendorprefix='' usevfork='false' usrinc='/usr/include' uuname='' uvXUformat='"lX"' uvoformat='"lo"' uvsize='4' uvtype='unsigned long' uvuformat='"lu"' uvxformat='"lx"' vendorarch='' vendorarchexp='' vendorbin='' vendorbinexp='' vendorlib='' vendorlib_stem='' vendorlibexp='' vendorprefix='' vendorprefixexp='' version='5.6.1' versiononly='' vi='' voidflags='15' xlibpth='/usr/lib/386 /lib/386' xs_apiversion='5.005' yacc='yacc' yaccflags='' zcat='' zip='zip'

__________________________________________________ Do You Yahoo!? Make international calls for as low as $.04/minute with Yahoo! Messenger http​://phonecard.yahoo.com/

p5pRT commented 22 years ago

From [Unknown Contact. See original ticket]

On Jul 24\, stuart lory said​:

The situation occurs when using /o in a regexp. Specifically I am using /mos\, and the bug does not show up if I change the regexp to /ms. My understanding is /o means 'compile pattern once'. But since I am doing this in a subroutine\, I was expecting the regexp to go out of scope when the subroutine ended.

What happens in test #2 is almost certainly a bug since I am passing in two different strings and the second string is being modified in a place where the first string had been changed. I think it's probably easier just to show an example output​:

Long story short​:

The /o modifier is SUPREME. If you write​:

  sub foo {   $x =~ /$y/o;   }

then the first time foo() is called\, the regex is compiled. Never again will it be compiled. Thus\, this behavior is not buggy.

In your case\, your regex is compiled as

  /brown/

all the time. However\, the RIGHT-HAND SIDE of your regex is not bound by the /o rule\, and thus\, you get the behavior​:

  for ( [ brown => 'purple' ]\, [ over => 'into' ] ) {   my ($find\, $replace) = @​$_;   $X =~ s/$find/$replace/o;   }

First\, $X gets "brown" replaced with "purple". Next\, it TRIES to replace "brown" with "into"\, but fails\, since there's no more brown to be found. It uses "brown" because the regex will ONLY BE COMPILED ONCE.

Let's examine your second case​:

  for ( [ \$Y\, brown => 'purple' ]\, [ \$Z\, over => 'into' ] ) {   my ($str\, $find\, $replace) = @​$_;   $$str =~ s/$find/$replace/o;   }

On the first iteration\, $Y is changed -- "brown" becomes "purple". On the second iteration\, $Z is changed -- "brown" becomes "into". Why? Because the regex (/$find/) was ONLY compiled ONCE.

Does this clarify the behavior?