summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryoungjl1 <luke.young@gmail.com>2015-12-16 23:05:24 -0500
committerJay Mundrawala <jdmundrawala@gmail.com>2016-02-16 19:07:55 -0800
commit8417850f5b3bba689694a4114502034600a44602 (patch)
treeb45461c929a04614dce91c3d18c7bc0c9d53a449
parenta028bda72981a9b58427054d51d69a58b45badc2 (diff)
downloadchef-8417850f5b3bba689694a4114502034600a44602.tar.gz
Fix databag globbing issues for chef-solo on windows
Backslashes should not be passed to Dir, as it does not work when globbing in many cases. Created new function that can be used with dir on windows. `escape_glob_dir` should be used when the result is going to be passed into Dir. Fixes #4194 Replaces #4195
-rw-r--r--chef-config/lib/chef-config/path_helper.rb8
-rw-r--r--chef-config/spec/unit/path_helper_spec.rb17
-rw-r--r--lib/chef/data_bag.rb6
3 files changed, 28 insertions, 3 deletions
diff --git a/chef-config/lib/chef-config/path_helper.rb b/chef-config/lib/chef-config/path_helper.rb
index 7fc79ba4a9..8fc6fbdff8 100644
--- a/chef-config/lib/chef-config/path_helper.rb
+++ b/chef-config/lib/chef-config/path_helper.rb
@@ -141,6 +141,7 @@ module ChefConfig
canonical_path(path1) == canonical_path(path2)
end
+ # Note: this method is deprecated. Please use escape_glob_dirs
# Paths which may contain glob-reserved characters need
# to be escaped before globbing can be done.
# http://stackoverflow.com/questions/14127343
@@ -149,6 +150,13 @@ module ChefConfig
path.gsub(/[\\\{\}\[\]\*\?]/) { |x| "\\" + x }
end
+ # This function does not switch to backslashes for windows
+ # This is because only forwardslashes should be used with dir (even for windows)
+ def self.escape_glob_dir(*parts)
+ path = Pathname.new(join(*parts)).cleanpath.to_s
+ path.gsub(/[\\\{\}\[\]\*\?]/) { |x| "\\"+x }
+ end
+
def self.relative_path_from(from, to)
Pathname.new(cleanpath(to)).relative_path_from(Pathname.new(cleanpath(from)))
end
diff --git a/chef-config/spec/unit/path_helper_spec.rb b/chef-config/spec/unit/path_helper_spec.rb
index b67a074f9e..9cdc7a6d9c 100644
--- a/chef-config/spec/unit/path_helper_spec.rb
+++ b/chef-config/spec/unit/path_helper_spec.rb
@@ -266,6 +266,23 @@ RSpec.describe ChefConfig::PathHelper do
end
end
+ describe "escape_glob_dir" do
+ it "escapes characters reserved by glob" do
+ path = "C:\\this\\*path\\[needs]\\escaping?"
+ escaped_path = "C:\\\\this\\\\\\*path\\\\\\[needs\\]\\\\escaping\\?"
+ expect(path_helper.escape_glob_dir(path)).to eq(escaped_path)
+ end
+
+ context "when given more than one argument" do
+ it "joins, cleanpaths, and escapes characters reserved by glob" do
+ args = ["this/*path", "[needs]", "escaping?"]
+ escaped_path = "this/\\*path/\\[needs\\]/escaping\\?"
+ expect(path_helper).to receive(:join).with(*args).and_call_original
+ expect(path_helper.escape_glob_dir(*args)).to eq(escaped_path)
+ end
+ end
+ end
+
describe "all_homes" do
before do
stub_const("ENV", env)
diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb
index d17dd8dc90..2852055203 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -98,8 +98,8 @@ class Chef
unless File.directory?(path)
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' is invalid"
end
-
- names += Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(path), "*")).map { |f| File.basename(f) }.sort
+
+ names += Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(path), "*")).map{|f|File.basename(f)}.sort
end
names.inject({}) { |h, n| h[n] = n; h }
else
@@ -125,7 +125,7 @@ class Chef
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' is invalid"
end
- Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(path, name.to_s), "*.json")).inject({}) do |bag, f|
+ Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(path, name.to_s), "*.json")).inject({}) do |bag, f|
item = Chef::JSONCompat.parse(IO.read(f))
# Check if we have multiple items with similar names (ids) and raise if their content differs