Permalink
Browse files

fully rewrite of quoter and glob_quoter, prepare for release to CPAN

  • Loading branch information...
1 parent 2e5a795 commit 84a0d5bf6b18b33630511815e0ce3fa209d83e7f @salva committed May 15, 2011
Showing with 56 additions and 19 deletions.
  1. +3 −2 Changes
  2. +40 −10 lib/Net/OpenSSH.pm
  3. +13 −7 t/1_run.t
View
5 Changes
@@ -1,7 +1,8 @@
Revision history for Perl extension Net::OpenSSH.
-0.53_01
- - quoter was not handling \n correctly (bug report and work
+0.53_01 May 15, 2011
+ - quoter and glob_quoter fully rewritten from scratch
+ - quoter was not handling "\n" correctly (bug report and work
around by Skeeve)
- minor doc improvements
View
50 lib/Net/OpenSSH.pm
@@ -1,6 +1,6 @@
package Net::OpenSSH;
-our $VERSION = '0.53';
+our $VERSION = '0.53_01';
use strict;
use warnings;
@@ -872,23 +872,53 @@ sub _load_module {
1
}
+my $noquote_class = '\\w/\\-=@';
+my $glob_class = '*?\\[\\],{}:!.^~';
+
sub _arg_quoter {
sub {
- my $arg = join '',
- map { ( m|^'$| ? "\\'" :
- m|^[\w/\-=\@]*$| ? $_ :
- "'$_'" ) } split /(')/, $_[0];
- length $arg ? $arg : "''";
+ my $quoted = join '',
+ map { ( m|^'$| ? "\\'" :
+ m|^[$noquote_class]*$|o ? $_ :
+ "'$_'" ) } split /(')/, $_[0];
+ length $quoted ? $quoted : "''";
}
}
sub _arg_quoter_glob {
sub {
my $arg = shift;
- return $arg if $arg =~ m|^[\w/\-+=?\[\],{}\@!.^~]+$|;
- return "''" if $arg eq '';
- $arg =~ s|(?<!\\)([^\w/\-+=*?\[\],{}:\@!.^\\~])|ord($1) > 127 ? $1 : $1 eq "\n" ? "'\n'" : "\\$1"|ge;
- $arg;
+ my @parts;
+ while ((pos $arg ||0) < length $arg) {
+ if ($arg =~ m|\G'|gc) {
+ push @parts, "\\'";
+ }
+ elsif ($arg =~ m|\G([$noquote_class$glob_class]+)|gco) {
+ push @parts, $1;
+ }
+ elsif ($arg =~ m|\G(\\[$glob_class\\])|gco) {
+ push @parts, $1;
+ }
+ elsif ($arg =~ m|\G\\|gc) {
+ push @parts, '\\\\'
+ }
+ elsif ($arg =~ m|\G([^$glob_class\\']+)|gco) {
+ push @parts, "'$1'";
+ }
+ else {
+ require Data::Dumper;
+ $arg =~ m|\G(.+)|gc;
+ die "Internal error: unquotable string:\n". Data::Dumper::Dumper($1) ."\n";
+ }
+ }
+ my $quoted = join('', @parts);
+ length $quoted ? $quoted : "''";
+
+ # my $arg = shift;
+ # return $arg if $arg =~ m|^[\w/\-+=?\[\],{}\@!.^~]+$|;
+ # return "''" if $arg eq '';
+ # $arg =~ s|(?<!\\)([^\w/\-+=*?\[\],{}:\@!.^\\~])|ord($1) > 127 ? $1 : $1 eq "\n" ? "'\n'" : "\\$1"|ge;
+ # $arg;
}
}
View
20 t/1_run.t
@@ -79,7 +79,7 @@ if ($ssh->error and $num > 4.7) {
plan skip_all => 'Unable to establish SSH connection to localhost!'
if $ssh->error;
-plan tests => 45;
+plan tests => 46;
sub shell_quote {
my $txt = shift;
@@ -166,20 +166,26 @@ $output = $ssh->capture(echo => $string);
chomp $output;
is ($output, $string, "quote_args");
+$string .= "\nline1\nline2";
+
+$output = $ssh->capture(echo => $string);
+chomp $output;
+is ($output, $string, "quote_args with new lines");
+
eval { $ssh->capture({foo => 1}, 'bar') };
ok($@ =~ /option/ and $@ =~ /foo/);
is ($ssh->shell_quote('/foo/'), '/foo/');
-is ($ssh->shell_quote('./foo*/bar&biz;'), './foo\\*/bar\\&biz\\;');
-is (Net::OpenSSH->shell_quote('./foo*/bar&biz;'), './foo\\*/bar\\&biz\\;');
-is ($ssh->_quote_args({quote_args => 1, glob_quoting => 1}, './foo*/bar&biz;'), './foo*/bar\\&biz\\;');
-is ($ssh->shell_quote_glob('./foo*/bar&biz;'), './foo*/bar\\&biz\\;');
-is (Net::OpenSSH->shell_quote_glob('./foo*/bar&biz;'), './foo*/bar\\&biz\\;');
+is ($ssh->shell_quote('./foo*/bar&biz;'), "'./foo*/bar&biz;'");
+is (Net::OpenSSH->shell_quote('./foo*/bar&biz;'), "'./foo*/bar&biz;'");
+is ($ssh->_quote_args({quote_args => 1, glob_quoting => 1}, './foo*/bar&biz;'), "./foo*/bar'&biz;'");
+is ($ssh->shell_quote_glob('./foo*/bar&biz;'), "./foo*/bar'&biz;'");
+is (Net::OpenSSH->shell_quote_glob('./foo*/bar&biz;'), "./foo*/bar'&biz;'");
$ssh->set_expand_vars(1);
$ssh->set_var(FOO => 'Bar');
is ($ssh->shell_quote(\\'foo%FOO%foo%%foo'), 'fooBarfoo%foo');
-is ($ssh->shell_quote('foo%FOO%foo%%foo'), 'fooBarfoo\%foo');
+is ($ssh->shell_quote('foo%FOO%foo%%foo'), "'fooBarfoo\%foo'");
$ssh->set_expand_vars(0);
is ($ssh->shell_quote(\\'foo%FOO%foo%%foo'), 'foo%FOO%foo%%foo');
is (Net::OpenSSH->shell_quote(\\'foo%FOO%foo%%foo'), 'foo%FOO%foo%%foo');

0 comments on commit 84a0d5b

Please sign in to comment.