]> gitweb.fluxo.info Git - puppet-stdlib.git/commitdiff
(#12357) Add validate_absolute_path() function
authorJeff McCune <jeff@puppetlabs.com>
Wed, 7 Mar 2012 19:52:30 +0000 (11:52 -0800)
committerJeff McCune <jeff@puppetlabs.com>
Wed, 7 Mar 2012 19:58:47 +0000 (11:58 -0800)
This patch adds a new function to validate if a string is an absolute
filesystem path or not.

The intent of this is to make this functionality generic and reusable.
Josh left a comment in another pull request I had:

    If node_installdir or $node_vardir is not defined, then we should
    raise an error, otherwise we may create a scheduled task to an
    untrusted directory.

One solution to this comment is to validate the Puppet variable is an
absolute path.

Examples of this function look like:

    function_validate_absolute_path
      Using Puppet::Parser::Scope.new
        Garbage inputs
          validate_absolute_path(nil) should fail
          validate_absolute_path([nil]) should fail
          validate_absolute_path({"foo"=>"bar"}) should fail
          validate_absolute_path({}) should fail
          validate_absolute_path("") should fail
        relative paths
          validate_absolute_path("relative1") should fail
          validate_absolute_path(".") should fail
          validate_absolute_path("..") should fail
          validate_absolute_path("./foo") should fail
          validate_absolute_path("../foo") should fail
          validate_absolute_path("etc/puppetlabs/puppet") should fail
          validate_absolute_path("opt/puppet/bin") should fail
        absolute paths
          validate_absolute_path("C:/") should not fail
          validate_absolute_path("C:\\") should not fail
          validate_absolute_path("C:\\WINDOWS\\System32") should not fail
          validate_absolute_path("C:/windows/system32") should not fail
          validate_absolute_path("X:/foo/bar") should not fail
          validate_absolute_path("X:\\foo\\bar") should not fail
          validate_absolute_path("/var/tmp") should not fail
          validate_absolute_path("/var/lib/puppet") should not fail
          validate_absolute_path("/var/opt/../lib/puppet") should not fail
          validate_absolute_path("C:\\Program Files (x86)\\Puppet Labs\\Puppet Enterprise") should not fail
          validate_absolute_path("C:/Program Files (x86)/Puppet Labs/Puppet Enterprise") should not fail

    Finished in 0.05637 seconds
    23 examples, 0 failures

lib/puppet/parser/functions/validate_absolute_path.rb [new file with mode: 0644]
spec/unit/puppet/parser/functions/validate_absolute_path_spec.rb [new file with mode: 0644]

diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb
new file mode 100644 (file)
index 0000000..46f86ec
--- /dev/null
@@ -0,0 +1,38 @@
+module Puppet::Parser::Functions
+  newfunction(:validate_absolute_path, :doc => <<-'ENDHEREDOC') do |args|
+    Validate the string represents an absolute path in the filesystem.  This function works
+    for windows and unix style paths.
+
+    The following values will pass:
+
+        $my_path = "C:/Program Files (x86)/Puppet Labs/Puppet"
+        validate_absolute_path($my_path)
+        $my_path2 = "/var/lib/puppet"
+        validate_absolute_path($my_path2)
+
+
+    The following values will fail, causing compilation to abort:
+
+        validate_absolute_path(true)
+        validate_absolute_path([ 'var/lib/puppet', '/var/foo' ])
+        validate_absolute_path([ '/var/lib/puppet', 'var/foo' ])
+        $undefined = undef
+        validate_absolute_path($undefined)
+
+    ENDHEREDOC
+
+    require 'puppet/util'
+
+    unless args.length > 0 then
+      raise Puppet::ParseError, ("validate_absolute_path(): wrong number of arguments (#{args.length}; must be > 0)")
+    end
+
+    args.each do |arg|
+      # This logic was borrowed from
+      # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb)
+      unless Puppet::Util.absolute_path?(arg, :posix) or Puppet::Util.absolute_path?(arg, :windows)
+        raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.")
+      end
+    end
+  end
+end
diff --git a/spec/unit/puppet/parser/functions/validate_absolute_path_spec.rb b/spec/unit/puppet/parser/functions/validate_absolute_path_spec.rb
new file mode 100644 (file)
index 0000000..2b44f50
--- /dev/null
@@ -0,0 +1,76 @@
+require 'spec_helper'
+
+describe Puppet::Parser::Functions.function(:validate_absolute_path) do
+  before :all do
+    Puppet::Parser::Functions.autoloader.loadall
+  end
+
+  let(:scope) do
+    scope = Puppet::Parser::Scope.new
+  end
+
+  # The subject of these examplres is the method itself.
+  subject do
+    scope.method :function_validate_absolute_path
+  end
+
+  context 'Using Puppet::Parser::Scope.new' do
+
+    describe 'Garbage inputs' do
+      paths = [
+        nil,
+        [ nil ],
+        { 'foo' => 'bar' },
+        { },
+        '',
+      ]
+
+      paths.each do |path|
+        it "validate_absolute_path(#{path.inspect}) should fail" do
+          expect { subject.call [path] }.to raise_error Puppet::ParseError
+        end
+      end
+    end
+    describe 'relative paths' do
+      paths = %w{
+        relative1
+        .
+        ..
+        ./foo
+        ../foo
+        etc/puppetlabs/puppet
+        opt/puppet/bin
+      }
+
+      paths.each do |path|
+        it "validate_absolute_path(#{path.inspect}) should fail" do
+          expect { subject.call [path] }.to raise_error Puppet::ParseError
+        end
+      end
+    end
+    describe 'absolute paths' do
+      paths = %w{
+        C:/
+        C:\\
+        C:\\WINDOWS\\System32
+        C:/windows/system32
+        X:/foo/bar
+        X:\\foo\\bar
+        /var/tmp
+        /var/lib/puppet
+        /var/opt/../lib/puppet
+      }
+
+      paths = paths + [
+        'C:\\Program Files (x86)\\Puppet Labs\\Puppet Enterprise',
+        'C:/Program Files (x86)/Puppet Labs/Puppet Enterprise',
+      ]
+
+      paths.each do |path|
+        it "validate_absolute_path(#{path.inspect}) should not fail" do
+          expect { subject.call [path] }.not_to raise_error
+        end
+      end
+    end
+  end
+end