Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repeated spaces on shebang line stops option parsing #7416

Closed
p5pRT opened this issue Jul 9, 2004 · 10 comments
Closed

Repeated spaces on shebang line stops option parsing #7416

p5pRT opened this issue Jul 9, 2004 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 9, 2004

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

Searchable as RT30660$

@p5pRT
Copy link
Author

p5pRT commented Jul 9, 2004

From tim@consultix-inc.com

Created by tim@consultix-inc.com

I've either found a bug in Perl, or there's an undocumented
"feature" that I've suddenly run into for the first time.
Either way, /I don't like it/! 8-{

In short, a parsing rule (or bug) seems to be operating that says
after two (or more) spaces are seen on the shebang line, no
additional options are recognized! So when one tries to use -s
for switch processing, and that switch is preceded by two spaces,
the result is that the -switch=whatever argument
is /retained/ on the command line, rather than used to set a
variable! When the -w option is in the ignored position, that
fails to enable warnings.

AFAIK, this is not documented behavior, and IMHO, it is not
/desirable/ behavior.

I've included sample programs and output below, and confirmed that
the same results are obtained with Perl versions 5.8.4 and 5.8.2.

-Tim Maher
tim@​teachmeperl.com

PROGRAMS​:

The _sw ending on a test program means the -s option is first,
and the -w second, and vice versa. The program invocation in each
case is "./scriptname -switch", which should set the $switch
variable in the script to 1. Note that there's nothing
switch-specific about this "two-space" bug -- that's just the
context in which I originally found it, and it demonstrates the
faulty behavior well, by (erroneously) leaving the -switch
argument in @​ARGV, and triggering a "possible typo" warning
regarding $switch in that case.

The two_space* versions of the programs are expected to work like
the one_space ones, but they don't.

2004-07-05 12​:31 one_space_sw Page 1

#! /usr/bin/perl -s -w
$switch == 1;
warn "Arguments are​: @​ARGV";

2004-07-05 12​:31 one_space_ws Page 1

#! /usr/bin/perl -w -s
$switch == 1;
warn "Arguments are​: @​ARGV";

2004-07-05 12​:32 two_spaces_sw Page 1

#! /usr/bin/perl -s -w
$switch == 1;
warn "Arguments are​: @​ARGV";

2004-07-05 12​:32 two_spaces_ws Page 1

#! /usr/bin/perl -w -s
$switch == 1;
warn "Arguments are​: @​ARGV";

OUTPUT​:

RUNNING 'one_space_sw'​:
Useless use of numeric eq (==) in void context at ./one_space_sw line 3.
Arguments are​: at ./one_space_sw line 5.

(That's the correct result; warnings enabled, and switch-argument processed)

RUNNING 'one_space_ws'​:
Useless use of numeric eq (==) in void context at ./one_space_ws line 3.
Arguments are​: at ./one_space_ws line 5.

(That's the correct result; warnings enabled, and switch-argument processed)

RUNNING 'two_spaces_sw'​:
Arguments are​: at ./two_spaces_sw line 5.

(That's the WRONG result; warnings DISabled;
  only switch-option recognized)

RUNNING 'two_spaces_ws'​:
Useless use of numeric eq (==) in void context at ./two_spaces_ws line 3.
Name "main​::switch" used only once​: possible typo at ./two_spaces_ws line 3.
Use of uninitialized value in numeric eq (==) at ./two_spaces_ws line 3.
Arguments are​: -switch at ./two_spaces_ws line 5.

(That's the WRONG result; switch not processed;
  only warning option recognized)

==============================================================
| Tim Maher, Ph.D. tim(AT)TeachMePerl.com |
| Seattle Perl Users Group http​://www.SeattlePerl.com |
| SPUG Wiki Site http​://Spugwiki.Perlocity.org |
| Perl Certification Site http​://Perlcert.Perlocity.org |

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.8.2:

Configured by root at Sat Nov 15 08:54:26 PST 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
  Platform:
    osname=linux, osvers=2.4.19-4gb, archname=i686-linux-thread-multi
    uname='linux jumpy 2.4.19-4gb #1 mon aug 4 23:38:42 utc 2003 i686 unknown '
    config_args='-Dusethreads'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O3',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing'
    ccversion='', gccversion='3.2', 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='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/ucblib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.2.5'
  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 v5.8.2:
    /local/perl5/site_perl/5.8.2
    /usr/lib/perl5/site_perl/5.8.2
    /local/perl5/site_perl/5.8.0
    /usr/lib/perl5/site_perl/5.8.0
    /local/perl5/site_perl/5.6.0
    /local/perl5/site_perl/5.005
    /local/perl5/site_perl/i386-linux
    /usr/lib/perl5/site_perl/5.8.0/i586-linux-thread-multi
    /usr/local/lib/perl5/5.8.2/i686-linux-thread-multi
    /usr/local/lib/perl5/5.8.2
    /usr/local/lib/perl5/site_perl/5.8.2/i686-linux-thread-multi
    /usr/local/lib/perl5/site_perl/5.8.2
    /usr/local/lib/perl5/site_perl
    /local/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl/5.8.0 /local/perl5/site_perl/5.6.0 /local/perl5/site_perl/i386-linux /local/perl5/site_perl/5.005
    .


Environment for perl v5.8.2:
    HOME=/home/tim
    LANG=en_US
    LANGUAGE (unset)
    LC_COLLATE=POSIX
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/tim/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/games:/opt/gnome2/bin:/opt/gnome/bin:/opt/kde3/bin:/opt/kde2/bin:/usr/lib/java/bin:.:/usr/X11R6/bin:/opt/kde/bin:/local/timbin:/local/dtp:/home/tim/bin:/usr/X11R6/bin:/opt/kde/bin:/local/timbin:/local/dtp:/home/tim/bin
    PERL5LIB=:/local/perl5/site_perl/5.8.2:/usr/lib/perl5/site_perl/5.8.2:/local/perl5/site_perl/5.8.0:/usr/lib/perl5/site_perl/5.8.0:/local/perl5/site_perl/5.6.0:/local/perl5/site_perl/5.005:/local/perl5/site_perl/i386-linux:/usr/lib/perl5/site_perl/5.8.0/i586-linux-thread-multi
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2008

From renee.baecker@smart-websolutions.de

Make perl recognize additional switches when more than one space is used...

--


renee.baecker@​smart-websolutions.de

Perl-Magazin​: http​://foo-magazin.de
Perl-Nachrichten​: http​://perl-nachrichten.de

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2008

From renee.baecker@smart-websolutions.de

perl.c.patch
--- perl.c.old	2008-08-25 10:35:38.000000000 +0200
+++ perl.c	2008-08-25 10:26:22.000000000 +0200
@@ -3370,8 +3370,10 @@
 	return s;
     case '*':
     case ' ':
-	if (s[1] == '-')	/* Additional switches on #! line. */
-	    return s+2;
+        while( *s && isSPACE(*s) )
+          ++s;
+	if (s[0] == '-')	/* Additional switches on #! line. */
+	    return s+1;
 	break;
     case '-':
     case 0:

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2008

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

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2008

From @nwc10

On Mon, Aug 25, 2008 at 10​:47​:31AM +0200, Rene Bcker wrote​:

Make perl recognize additional switches when more than one space is used...

Do you have an example of what this is solving? It seems a logical change to
make, but I'm guessing as to what the problem is.

--- perl.c.old 2008-08-25 10​:35​:38.000000000 +0200
+++ perl.c 2008-08-25 10​:26​:22.000000000 +0200
@​@​ -3370,8 +3370,10 @​@​
return s;
case '*'​:
case ' '​:
- if (s[1] == '-') /* Additional switches on #! line. */
- return s+2;
+ while( *s && isSPACE(*s) )
+ ++s;

That can be

  while( isSPACE(*s) )
  ++s;

because isSPACE('\0') is going to be false.

But is using isSPACE() correct, given that '\r', '\n' and particularly '\t'
are handled differently in code below?
(And no, I'm not intimately familiar with what it is doing, or why)

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Aug 26, 2008

From renee.baecker@smart-websolutions.de

Nicholas Clark wrote​:

On Mon, Aug 25, 2008 at 10​:47​:31AM +0200, Rene Bcker wrote​:

Make perl recognize additional switches when more than one space is used...

Do you have an example of what this is solving? It seems a logical change to
make, but I'm guessing as to what the problem is.

Attached is a small script. Without this patch it just recognizes the -s
switch but not the -w switch.

--- perl.c.old 2008-08-25 10​:35​:38.000000000 +0200
+++ perl.c 2008-08-25 10​:26​:22.000000000 +0200
@​@​ -3370,8 +3370,10 @​@​
return s;
case '*'​:
case ' '​:
- if (s[1] == '-') /* Additional switches on #! line. */
- return s+2;
+ while( *s && isSPACE(*s) )
+ ++s;

That can be

   while\( isSPACE\(\*s\) \)
     \+\+s;

because isSPACE('\0') is going to be false.

But is using isSPACE() correct, given that '\r', '\n' and particularly '\t'
are handled differently in code below?
(And no, I'm not intimately familiar with what it is doing, or why)

So this should be rewritten as

  while( *s && ( s[0] == ' ' ) )
  ++s;

Nicholas Clark

Renee

@p5pRT
Copy link
Author

p5pRT commented Aug 26, 2008

@p5pRT
Copy link
Author

p5pRT commented Aug 26, 2008

From @Tux

On Tue, 26 Aug 2008 08​:43​:55 +0200, Renée Bäcker
<renee.baecker@​smart-websolutions.de> wrote​:

Nicholas Clark wrote​:

On Mon, Aug 25, 2008 at 10​:47​:31AM +0200, Rene Bcker wrote​:

Make perl recognize additional switches when more than one space is used...

Do you have an example of what this is solving? It seems a logical change to
make, but I'm guessing as to what the problem is.

Attached is a small script. Without this patch it just recognizes the -s
switch but not the -w switch.

--- perl.c.old 2008-08-25 10​:35​:38.000000000 +0200
+++ perl.c 2008-08-25 10​:26​:22.000000000 +0200
@​@​ -3370,8 +3370,10 @​@​
return s;
case '*'​:
case ' '​:
- if (s[1] == '-') /* Additional switches on #! line. */
- return s+2;
+ while( *s && isSPACE(*s) )
+ ++s;

That can be

   while\( isSPACE\(\*s\) \)
     \+\+s;

because isSPACE('\0') is going to be false.

But is using isSPACE() correct, given that '\r', '\n' and particularly '\t'
are handled differently in code below?
(And no, I'm not intimately familiar with what it is doing, or why)

So this should be rewritten as

while( *s && ( s[0] == ' ' ) )
++s;

That is just one test too many, as it is effectively the same as

  while (*s == ' ') s++;

if *s == (char)0, *s == ' ' will be false
If you also want to allow tabs,

  while (*s == ' ' || *s == '\t') s++;

--
H.Merijn Brand Amsterdam Perl Mongers http​://amsterdam.pm.org/
using & porting perl 5.6.2, 5.8.x, 5.10.x, 5.11.x on HP-UX 10.20, 11.00,
11.11, 11.23, and 11.31, SuSE 10.1, 10.2, and 10.3, AIX 5.2, and Cygwin.
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/
http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Aug 28, 2008

From @nwc10

On Tue, Aug 26, 2008 at 09​:16​:16AM +0200, H.Merijn Brand wrote​:

On Tue, 26 Aug 2008 08​:43​:55 +0200, Renée Bäcker
<renee.baecker@​smart-websolutions.de> wrote​:

Do you have an example of what this is solving? It seems a logical change to
make, but I'm guessing as to what the problem is.

Attached is a small script. Without this patch it just recognizes the -s
switch but not the -w switch.

Thanks. I used a variant in my test.

That can be

   while\( isSPACE\(\*s\) \)
     \+\+s;

because isSPACE('\0') is going to be false.

But is using isSPACE() correct, given that '\r', '\n' and particularly '\t'
are handled differently in code below?
(And no, I'm not intimately familiar with what it is doing, or why)

So this should be rewritten as

while( *s && ( s[0] == ' ' ) )
++s;

That is just one test too many, as it is effectively the same as

while \(\*s == ' '\) s\+\+;

if *s == (char)0, *s == ' ' will be false
If you also want to allow tabs,

while \(\*s == ' ' || \*s == '\\t'\) s\+\+;

Tabs are handled differently in the code below

  case '\n'​:
  case '\t'​:
  break;

so it didn't seem logical to include them here.

I applied the appended change.

Nicholas Clark

Change 34234 by nicholas@​nicholas-saigo on 2008/08/28 13​:11​:44

  Fix #30660​: Repeated spaces on shebang line stops option parsing
  From a patch and test sent by Renée Bäcker in
  <48B271A3.80808@​smart-websolutions.de>

Affected files ...

... //depot/perl/perl.c#874 edit
... //depot/perl/t/run/switches.t#28 edit

Differences ...

==== //depot/perl/perl.c#874 (text) ====

@​@​ -3431,8 +3431,10 @​@​
  return s;
  case '*'​:
  case ' '​:
- if (s[1] == '-') /* Additional switches on #! line. */
- return s+2;
+ while( *s == ' ' )
+ ++s;
+ if (s[0] == '-') /* Additional switches on #! line. */
+ return s+1;
  break;
  case '-'​:
  case 0​:

==== //depot/perl/t/run/switches.t#28 (text) ====

@​@​ -11,7 +11,7 @​@​

BEGIN { require "./test.pl"; }

-plan(tests => 69);
+plan(tests => 70);

use Config;

@​@​ -350,3 +350,19 @​@​
  stdin => 'zomtek',
);
is( $r, "affe\n", '-E works outside of the block created by -n' );
+
+# RT #30660
+
+$filename = tempfile();
+SKIP​: {
+ open my $f, ">$filename" or skip( "Can't write temp file $filename​: $!" );
+ print $f <<'SWTEST';
+#!perl -w -iok
+print "$^I\n";
+SWTEST
+ close $f or die "Could not close​: $!";
+ $r = runperl(
+ progfile => $filename,
+ );
+ like( $r, qr/ok/, 'Spaces on the #! line (#30660)' );
+}

@p5pRT
Copy link
Author

p5pRT commented Aug 28, 2008

module@renee-baecker.de - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant