+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
-~----------~----~----~----~------~----~------~--~---

Reply via email to