Skip to content
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

Allow array of pathes in validate_absolute_path #372

Merged
merged 1 commit into from Dec 17, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 28 additions & 21 deletions README.markdown
Expand Up @@ -461,27 +461,34 @@ You can also use this with arrays. For example, `unique(["a","a","b","b","c","c"

* `uriescape`: Urlencodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue

* `validate_absolute_path`: Validate that 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)
```

*Type*: statement
* `validate_absolute_path`: 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)
$my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet']
validate_absolute_path($my_path3)
$my_path4 = ['/var/lib/puppet','/usr/share/puppet']
validate_absolute_path($my_path4)
```

The following values will fail, causing compilation to abort:

```
validate_absolute_path(true)
validate_absolute_path('../var/lib/puppet')
validate_absolute_path('var/lib/puppet')
validate_absolute_path([ 'var/lib/puppet', '/var/foo' ])
validate_absolute_path([ '/var/lib/puppet', 'var/foo' ])
$undefined = undef
validate_absolute_path($undefined)
```

*Type*: statement

* `validate_array`: Validate that all passed values are array data structures. Abort catalog compilation if any value fails this check.

Expand Down
61 changes: 37 additions & 24 deletions lib/puppet/parser/functions/validate_absolute_path.rb
Expand Up @@ -5,15 +5,20 @@ module Puppet::Parser::Functions

The following values will pass:

$my_path = "C:/Program Files (x86)/Puppet Labs/Puppet"
$my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet'
validate_absolute_path($my_path)
$my_path2 = "/var/lib/puppet"
$my_path2 = '/var/lib/puppet'
validate_absolute_path($my_path2)

$my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet']
validate_absolute_path($my_path3)
$my_path4 = ['/var/lib/puppet','/usr/share/puppet']
validate_absolute_path($my_path4)

The following values will fail, causing compilation to abort:

validate_absolute_path(true)
validate_absolute_path('../var/lib/puppet')
validate_absolute_path('var/lib/puppet')
validate_absolute_path([ 'var/lib/puppet', '/var/foo' ])
validate_absolute_path([ '/var/lib/puppet', 'var/foo' ])
$undefined = undef
Expand All @@ -28,28 +33,36 @@ module Puppet::Parser::Functions
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)

# Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise.
if Puppet::Util.respond_to?(:absolute_path?) then
unless Puppet::Util.absolute_path?(arg, :posix) or Puppet::Util.absolute_path?(arg, :windows)
raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.")
# put arg to candidate var to be able to replace it
candidates = arg
# if arg is just a string with a path to test, convert it to an array
# to avoid test code duplication
unless arg.is_a?(Array) then
candidates = Array.new(1,arg)
end
# iterate over all pathes within the candidates array
candidates.each do |path|
# This logic was borrowed from
# [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb)
# Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise.
if Puppet::Util.respond_to?(:absolute_path?) then
unless Puppet::Util.absolute_path?(path, :posix) or Puppet::Util.absolute_path?(path, :windows)
raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.")
end
else
# This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path?
# Determine in a platform-specific way whether a path is absolute. This
# defaults to the local platform if none is specified.
# Escape once for the string literal, and once for the regex.
slash = '[\\\\/]'
name = '[^\\\\/]+'
regexes = {
:windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i,
:posix => %r!^/!,
}
rval = (!!(path =~ regexes[:posix])) || (!!(path =~ regexes[:windows]))
rval or raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.")
end
else
# This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path?
# Determine in a platform-specific way whether a path is absolute. This
# defaults to the local platform if none is specified.
# Escape once for the string literal, and once for the regex.
slash = '[\\\\/]'
name = '[^\\\\/]+'
regexes = {
:windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i,
:posix => %r!^/!,
}

rval = (!!(arg =~ regexes[:posix])) || (!!(arg =~ regexes[:windows]))
rval or raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.")
end
end
end
Expand Down
38 changes: 29 additions & 9 deletions spec/functions/validate_absolute_path_spec.rb
Expand Up @@ -39,6 +39,11 @@ def self.valid_paths
expect { subject.call [path] }.not_to raise_error
end
end
valid_paths do
it "validate_absolute_path(#{valid_paths.inspect}) should not fail" do
expect { subject.call [valid_paths] }.not_to raise_error
end
end
end

context "Puppet without mocking" do
Expand All @@ -47,6 +52,11 @@ def self.valid_paths
expect { subject.call [path] }.not_to raise_error
end
end
valid_paths do
it "validate_absolute_path(#{valid_paths.inspect}) should not fail" do
expect { subject.call [valid_paths] }.not_to raise_error
end
end
end
end

Expand All @@ -55,6 +65,7 @@ def self.valid_paths
[
nil,
[ nil ],
[ nil, nil ],
{ 'foo' => 'bar' },
{ },
'',
Expand All @@ -66,19 +77,28 @@ def self.valid_paths
end

context 'Relative paths' do
%w{
relative1
.
..
./foo
../foo
etc/puppetlabs/puppet
opt/puppet/bin
}.each do |path|
def self.rel_paths
%w{
relative1
.
..
./foo
../foo
etc/puppetlabs/puppet
opt/puppet/bin
}
end
rel_paths.each do |path|
it "validate_absolute_path(#{path.inspect}) should fail" do
expect { subject.call [path] }.to raise_error Puppet::ParseError
end
end
rel_paths do
it "validate_absolute_path(#{rel_paths.inspect}) should fail" do
expect { subject.call [rel_paths] }.to raise_error Puppet::ParseError
end
end
end
end
end