+1 On Aug 4, 2009, at 5:47 AM, Thomas Bellman wrote:
> > > This adds a new function shellquote() which can be used for quoting > arguments in shell commands used in the exec type. > > This only supports Unixoid operating systems. Other systems would > likely require some other quoting. > > Signed-off-by: Thomas Bellman <[email protected]> > --- > lib/puppet/parser/functions/shellquote.rb | 41 +++++++++++++ > spec/unit/parser/functions/shellquote.rb | 92 ++++++++++++++++++++ > +++++++++ > 2 files changed, 133 insertions(+), 0 deletions(-) > create mode 100644 lib/puppet/parser/functions/shellquote.rb > create mode 100755 spec/unit/parser/functions/shellquote.rb > > diff --git a/lib/puppet/parser/functions/shellquote.rb b/lib/puppet/ > parser/functions/shellquote.rb > new file mode 100644 > index 0000000..6c99452 > --- /dev/null > +++ b/lib/puppet/parser/functions/shellquote.rb > @@ -0,0 +1,41 @@ > +module Puppet::Parser::Functions > + > + Safe = 'a-za-z...@%_+=:,./-' # Safe unquoted > + Dangerous = '!"`$\\' # Unsafe inside double quotes > + > + newfunction(:shellquote, :type => :rvalue, :doc => "\ > + Quote and concatenate arguments for use in Bourne shell. > + > + Each argument is quoted separately, and then all are > concatenated > + with spaces. If an argument is an array, the elements of > that > + array is interpolated within the rest of the arguments; > this makes > + it possible to have an array of arguments and pass that > array to > + shellquote() instead of having to specify specify each > argument > + individually in the call. > + ") \ > + do |args| > + > + result = [] > + args.flatten.each do |word| > + if word.length != 0 and word.count(Safe) == word.length > + result << word > + elsif word.count(Dangerous) == 0 > + result << ('"' + word + '"') > + elsif word.count("'") == 0 > + result << ("'" + word + "'") > + else > + r = '"' > + word.each_byte() do |c| > + if Dangerous.include?(c) > + r += "\\" > + end > + r += c.chr() > + end > + r += '"' > + result << r > + end > + end > + > + return result.join(" ") > + end > +end > diff --git a/spec/unit/parser/functions/shellquote.rb b/spec/unit/ > parser/functions/shellquote.rb > new file mode 100755 > index 0000000..283a4de > --- /dev/null > +++ b/spec/unit/parser/functions/shellquote.rb > @@ -0,0 +1,92 @@ > +#! /usr/bin/env ruby > + > +require File.dirname(__FILE__) + '/../../../spec_helper' > + > +describe "the shellquote function" do > + > + before :each do > + @scope = Puppet::Parser::Scope.new() > + end > + > + it "should exist" do > + Puppet::Parser::Functions.function("shellquote").should == > "function_shellquote" > + end > + > + > + it "should handle no arguments" do > + result = @scope.function_shellquote([]) > + result.should(eql("")) > + end > + > + it "should handle several simple arguments" do > + result = @scope.function_shellquote( > + ['foo', '[email protected]', 'localhost:/dev/null', 'xyzzy > +-4711,23']) > + result.should(eql( > + 'foo [email protected] localhost:/dev/null xyzzy > +-4711,23')) > + end > + > + it "should handle array arguments" do > + result = @scope.function_shellquote( > + ['foo', ['[email protected]', 'localhost:/dev/null'], > + 'xyzzy+-4711,23']) > + result.should(eql( > + 'foo [email protected] localhost:/dev/null xyzzy > +-4711,23')) > + end > + > + it "should quote unsafe characters" do > + result = @scope.function_shellquote( > + ['/etc/passwd ', '(ls)', '*', '[?]', "'&'"]) > + result.should(eql( > + '"/etc/passwd " "(ls)" "*" "[?]" "\'&\'"')) > + end > + > + it "should deal with double quotes" do > + result = @scope.function_shellquote( > + ['"foo"bar"']) > + result.should(eql( > + '\'"foo"bar"\'')) > + end > + > + it "should cope with dollar signs" do > + result = @scope.function_shellquote( > + ['$PATH', 'foo$bar', '"x$"']) > + result.should(eql( > + "'$PATH' 'foo$bar' '\"x$\"'")) > + end > + > + it "should deal with apostrophes (single quotes)" do > + result = @scope.function_shellquote( > + ["'foo'bar'", "`$'EDITOR'`"]) > + result.should(eql( > + '"\'foo\'bar\'" "\\`\\$\'EDITOR\'\\`"')) > + end > + > + it "should cope with grave accents (backquotes)" do > + result = @scope.function_shellquote( > + ['`echo *`', '`ls "$MAILPATH"`']) > + result.should(eql( > + "'`echo *`' '`ls \"$MAILPATH\"`'")) > + end > + > + it "should deal with both single and double quotes" do > + result = @scope.function_shellquote( > + ['\'foo"bar"xyzzy\'', '"foo\'bar\'xyzzy"']) > + result.should(eql( > + '"\'foo\\"bar\\"xyzzy\'" "\\"foo\'bar\'xyzzy\\""')) > + end > + > + it "should handle multiple quotes *and* dollars and backquotes" > do > + result = @scope.function_shellquote( > + ['\'foo"$x`bar`"xyzzy\'']) > + result.should(eql( > + '"\'foo\\"\\$x\\`bar\\`\\"xyzzy\'"')) > + end > + > + it "should handle linefeeds" do > + result = @scope.function_shellquote( > + ["foo \n bar"]) > + result.should(eql( > + "\"foo \n bar\"")) > + end > + > +end > -- > 1.6.0.6 > > > > -- Everything that is really great and inspiring is created by the individual who can labor in freedom. -- Albert Einstein --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en -~----------~----~----~----~------~----~------~--~---
