Skip Menu |
Report information
Id: 129336
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: dcollinsn [at] gmail.com
Cc:
AdminCc:

Operating System: All
PatchStatus: (no value)
Severity: low
Type:
Perl Version: 5.25.5
Fixed In: (no value)

Attachments
0001-rt-129336-perl-i-u-erroneously-interpreted-as-u.patch



Subject: [PATCH] "#!perl -i whatever" is interpreted as "#!perl -i -whatever"
Download (untitled) / with headers
text/plain 1.5k
Hello, There is a bug in argument parsing of the -i flag. Perl_moreswitches processes a single switch, and returns a pointer to the start of the next switch. It can return either the a pointer to the next flag itself: #!perl -n -p ^ Can point here Or, to the space before the next "arg": #!perl -n -p ^ Can point here (Where the next call to Perl_moreswitches will consume " -".) In the case of -i[extension], the pointer is by default pointing at the space after the end of the argument. The current code tries to do the former, by unconditionally advancing the pointer, and then advancing it again if it is on a '-'. But that is incorrect: #!perl -i p ^ Will point here, but that isn't a flag This is a problem if -i is the last argument before either a file name, or a malformed argument. This normally isn't a problem on the command line because Perl_moreswitches operates on elements of `argv` one at a time. However, someone who typed `perl "-ifoo Vbar.pl"` into bash, or someone who has a messed up #! line, will encounter this. I could fix this by removing the unconditional s++, and having it increment by 2 if *(s+1)=='-', but this work isn't actually necessary - it's better to just remove the special-casing for -i and leave it pointing at the space after the argument. Found with AFL, believe it or not. This is not a regression, and all tests pass for me. I've added a test for this, it basically makes sure that `#!perl -i u` does /not/ crash. Clicking submit so I get an RT number. -- Respectfully, Dan Collins
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.6k
On Thu Sep 22 23:22:45 2016, dcollinsn@gmail.com wrote: Show quoted text
> Hello, > > There is a bug in argument parsing of the -i flag. Perl_moreswitches > processes a single switch, and returns a pointer to the start of the > next switch. It can return either the a pointer to the next flag > itself: > > #!perl -n -p > ^ Can point here > > Or, to the space before the next "arg": > > #!perl -n -p > ^ Can point here > > (Where the next call to Perl_moreswitches will consume " -".) > > In the case of -i[extension], the pointer is by default pointing at > the space after the end of the argument. The current code tries to do > the former, by unconditionally advancing the pointer, and then > advancing it again if it is on a '-'. But that is incorrect: > > #!perl -i p > ^ Will point here, but that isn't a flag > > This is a problem if -i is the last argument before either a file > name, or a malformed argument. This normally isn't a problem on the > command line because Perl_moreswitches operates on elements of `argv` > one at a time. However, someone who typed `perl "-ifoo Vbar.pl"` into > bash, or someone who has a messed up #! line, will encounter this. > > I could fix this by removing the unconditional s++, and having it > increment by 2 if *(s+1)=='-', but this work isn't actually necessary > - it's better to just remove the special-casing for -i and leave it > pointing at the space after the argument. > > Found with AFL, believe it or not. This is not a regression, and all > tests pass for me. I've added a test for this, it basically makes sure > that `#!perl -i u` does /not/ crash. > > Clicking submit so I get an RT number.
Patch attached. -- Respectfully, Dan Collins
Subject: 0001-rt-129336-perl-i-u-erroneously-interpreted-as-u.patch
From 757b1c7109f3e69d2717b5187e58e78537dd5101 Mon Sep 17 00:00:00 2001 From: Dan Collins <dcollinsn@gmail.com> Date: Fri, 23 Sep 2016 01:21:20 -0400 Subject: [PATCH] [rt #129336] #!perl -i u erroneously interpreted as -u Perl_moreswitches processes a single switch, and returns a pointer to the start of the next switch. It can return either the a pointer to the next flag itself: #!perl -n -p ^ Can point here Or, to the space before the next "arg": #!perl -n -p ^ Can point here (Where the next call to Perl_moreswitches will consume " -".) In the case of -i[extension], the pointer is by default pointing at the space after the end of the argument. The current code tries to do the former, by unconditionally advancing the pointer, and then advancing it again if it is on a '-'. But that is incorrect: #!perl -i p ^ Will point here, but that isn't a flag I could fix this by removing the unconditional s++, and having it increment by 2 if *(s+1)=='-', but this work isn't actually necessary - it's better to just leave it pointing at the space after the argument. --- perl.c | 5 ----- t/op/lex.t | 9 ++++++++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/perl.c b/perl.c index 07b8523..ba6d5af 100644 --- a/perl.c +++ b/perl.c @@ -3349,11 +3349,6 @@ Perl_moreswitches(pTHX_ const char *s) PL_inplace = savepvn(start, s - start); } - if (*s) { - ++s; - if (*s == '-') /* Additional switches on #! line. */ - s++; - } return s; case 'I': /* -I handled both here and in parse_body() */ forbid_setid('I', FALSE); diff --git a/t/op/lex.t b/t/op/lex.t index a667183..9696669 100644 --- a/t/op/lex.t +++ b/t/op/lex.t @@ -7,7 +7,7 @@ use warnings; BEGIN { chdir 't' if -d 't'; require './test.pl'; } -plan(tests => 30); +plan(tests => 31); { no warnings 'deprecated'; @@ -241,3 +241,10 @@ fresh_perl_is( {}, '[perl #129069] - "Missing name" warning and valgrind clean' ); + +fresh_perl_like( + "#!perl -i u\nprint 'OK'", + qr/OK/, + {}, + '[perl #129336] - #!perl -i argument handling' +); -- 2.9.3
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 141b
On Thu Sep 22 23:25:11 2016, dcollinsn@gmail.com wrote: Show quoted text
> Patch attached.
Thanks, applied as f54cfdacff1f3744ef08fc70f1f3bc6c7d862e83. Tony
Download (untitled) / with headers
text/plain 313b
Thank you for filing this report. You have helped make Perl better. With the release today of Perl 5.26.0, this and 210 other issues have been resolved. Perl 5.26.0 may be downloaded via: https://metacpan.org/release/XSAWYERX/perl-5.26.0 If you find that the problem persists, feel free to reopen this ticket.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org