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
shellwords.pl and tainting #7722
Comments
From perl-5.8.0@ton.iguana.beCreated by perl-5.8.0@ton.iguana.beWhile debugging why commandline input to CGI.pm wasn't tainted, I found #!/usr/bin/perl -Tlw require "shellwords.pl"; Below is an updated version of shellwords.pl with the following - keep taint ;# shellwords.pl sub shellwords { s/\A\s+//; Perl Info
|
From @rgsperl-5.8.0@ton.iguana.be (via RT) wrote:
Thanks, applied as #23681 to blead.
|
The RT System itself - Status changed from 'new' to 'open' |
@rgs - Status changed from 'open' to 'resolved' |
From at@altlinux.ruOn Fri, Dec 24, 2004 at 03:19:40PM +0100, Rafael Garcia-Suarez wrote:
Hi,
- fix also Text::ParseWords which has basically the same code Inline Patch--- perl-5.9.2.23688/lib/Text/ParseWords.pm- 2004-07-07 02:03:53 +0400
+++ perl-5.9.2.23688/lib/Text/ParseWords.pm 2004-12-28 22:25:07 +0300
@@ -12,7 +12,7 @@ use Exporter;
sub shellwords {
- local(@lines) = @_;
+ my(@lines) = @_;
$lines[$#lines] =~ s/\s+$//;
return(quotewords('\s+', 0, @lines));
}
@@ -22,7 +22,6 @@ sub shellwords {
sub quotewords {
my($delim, $keep, @lines) = @_;
my($line, @words, @allwords);
-
foreach $line (@lines) {
@words = parse_line($delim, $keep, $line);
@@ -37,7 +36,7 @@ sub quotewords {
sub nested_quotewords {
my($delim, $keep, @lines) = @_;
my($i, @allwords);
-
+
for ($i = 0; $i < @lines; $i++) {
@{$allwords[$i]} = parse_line($delim, $keep, $lines[$i]);
return() unless (@{$allwords[$i]} || !length($lines[$i]));
@@ -48,13 +47,11 @@ sub nested_quotewords {
sub parse_line {
- # We will be testing undef strings
- no warnings;
- use re 'taint'; # if it's tainted, leave it as such
-
my($delimiter, $keep, $line) = @_;
my($word, @pieces);
+ no warnings 'uninitialized'; # we will be testing undef strings
+
while (length($line)) {
$line =~ s/^(["']) # a $quote
((?:\\.|(?!\1)[^\\])*) # and $quoted text
@@ -77,6 +74,7 @@ sub parse_line {
$quoted =~ s/\\([\\'])/$1/g if ( $PERL_SINGLE_QUOTE && $quote eq "'");
}
}
+ $word .= substr($line, 0, 0); # leave results tainted
$word .= defined $quote ? $quoted : $unquoted;
if (length($delim)) {
@@ -100,41 +98,48 @@ sub old_shellwords {
# @words = old_shellwords($line);
# or
# @words = old_shellwords(@lines);
+ # or
+ # @words = old_shellwords(); # defaults to $_ (and clobbers it)
- local($_) = join('', @_);
- my(@words,$snippet,$field);
+ no warnings 'uninitialized'; # we will be testing undef strings
+ local *_ = \join('', @_) if @_;
+ my (@words, $snippet);
- s/^\s+//;
+ s/\A\s+//;
while ($_ ne '') {
- $field = '';
+ my $field = substr($_, 0, 0); # leave results tainted
for (;;) {
- if (s/^"(([^"\\]|\\.)*)"//) {
- ($snippet = $1) =~ s#\\(.)#$1#g;
+ if (s/\A"(([^"\\]|\\.)*)"//s) {
+ ($snippet = $1) =~ s#\\(.)#$1#sg;
}
- elsif (/^"/) {
+ elsif (/\A"/) {
+ require Carp;
+ Carp::carp("Unmatched double quote: $_");
return();
}
- elsif (s/^'(([^'\\]|\\.)*)'//) {
- ($snippet = $1) =~ s#\\(.)#$1#g;
+ elsif (s/\A'(([^'\\]|\\.)*)'//s) {
+ ($snippet = $1) =~ s#\\(.)#$1#sg;
}
- elsif (/^'/) {
+ elsif (/\A'/) {
+ require Carp;
+ Carp::carp("Unmatched single quote: $_");
return();
}
- elsif (s/^\\(.)//) {
+ elsif (s/\A\\(.)//s) {
$snippet = $1;
}
- elsif (s/^([^\s\\'"]+)//) {
+ elsif (s/\A([^\s\\'"]+)//) {
$snippet = $1;
}
else {
- s/^\s+//;
+ s/\A\s+//;
last;
}
$field .= $snippet;
}
push(@words, $field);
}
- @words;
+ return @words;
}
1;
--- perl-5.9.2.23688/lib/Text/ParseWords/taint.t- 2004-12-28 21:21:26 +0300
+++ perl-5.9.2.23688/lib/Text/ParseWords/taint.t 2004-12-28 21:39:56 +0300
@@ -0,0 +1,23 @@
+#!./perl -Tw
+# [perl #33173] shellwords.pl and tainting
+
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ require Config;
+ if ($Config::Config{extensions} !~ /\bList\/Util\b/) {
+ print "1..0 # Skip: Scalar::Util was not built\n";
+ exit 0;
+ }
+}
+
+use Text::ParseWords qw(shellwords old_shellwords);
+use Scalar::Util qw(tainted);
+
+print "1..2\n";
+
+print "not " if grep { not tainted($_) } shellwords("$0$^X");
+print "ok 1\n";
+
+print "not " if grep { not tainted($_) } old_shellwords("$0$^X");
+print "ok 2\n";
--- perl-5.9.2.23688/lib/shellwords.pl- 2004-12-24 17:21:02 +0300
+++ perl-5.9.2.23688/lib/shellwords.pl 2004-12-28 21:35:07 +0300
@@ -8,40 +8,7 @@
;# or
;# @words = shellwords(); # defaults to $_ (and clobbers it)
-sub shellwords {
- local *_ = \join('', @_) if @_;
- my (@words, $snippet);
+require Text::ParseWords;
+*shellwords = \&Text::ParseWords::old_shellwords;
- s/\A\s+//;
- while ($_ ne '') {
- my $field = substr($_, 0, 0); # leave results tainted
- for (;;) {
- if (s/\A"(([^"\\]|\\.)*)"//s) {
- ($snippet = $1) =~ s#\\(.)#$1#sg;
- }
- elsif (/\A"/) {
- die "Unmatched double quote: $_\n";
- }
- elsif (s/\A'(([^'\\]|\\.)*)'//s) {
- ($snippet = $1) =~ s#\\(.)#$1#sg;
- }
- elsif (/\A'/) {
- die "Unmatched single quote: $_\n";
- }
- elsif (s/\A\\(.)//s) {
- $snippet = $1;
- }
- elsif (s/\A([^\s\\'"]+)//) {
- $snippet = $1;
- }
- else {
- s/\A\s+//;
- last;
- }
- $field .= $snippet;
- }
- push(@words, $field);
- }
- return @words;
-}
1; |
From chromatic@wgz.orgOn Tue, 2004-12-28 at 22:29 +0300, Alexey Tourbin wrote:
This being a module, it's okay to use at least test.pl here, if not -- c |
From perl5-porters@ton.iguana.be(in sub old_shellwords)
Where would undef strings ever appear ? Except of course for the join of
|
From at@altlinux.ruOn Tue, Dec 28, 2004 at 08:09:44PM +0000, Ton Hospel wrote:
This is analogous to `sub parse_line' which had `no warnings' at all; |
From at@altlinux.ruOn Tue, Dec 28, 2004 at 11:38:22AM -0800, chromatic wrote:
[...]
lib/Text/ParseWords/taint.t was quickly made after lib/Text/ParseWords.t, (I placed it into separate file because it is impossible to enabled Anyway, I can't see the reason for using Test::More offhand.
|
From @rgsAlexey Tourbin wrote:
Thanks, applied as #23838. |
Migrated from rt.perl.org#33173 (status was 'resolved')
Searchable as RT33173$
The text was updated successfully, but these errors were encountered: