diff options
author | Jay Mundrawala <jdmundrawala@gmail.com> | 2016-02-16 19:55:23 -0800 |
---|---|---|
committer | Jay Mundrawala <jdmundrawala@gmail.com> | 2016-02-16 19:55:23 -0800 |
commit | e48aee5eae2191cf5755697d3f4407827945b0e9 (patch) | |
tree | 7be29c2e270499ea5bfdd7e3f2831b8f8d88cf23 | |
parent | a028bda72981a9b58427054d51d69a58b45badc2 (diff) | |
parent | 4db706fcce25b6d269a1b232e316083ae1a45b9b (diff) | |
download | chef-e48aee5eae2191cf5755697d3f4407827945b0e9.tar.gz |
Merge pull request #4569 from chef/jdm/4915
Fix databag globbing issues for chef-solo on windows
-rw-r--r-- | chef-config/lib/chef-config/path_helper.rb | 8 | ||||
-rw-r--r-- | chef-config/spec/unit/path_helper_spec.rb | 17 | ||||
-rw-r--r-- | lib/chef/data_bag.rb | 5 |
3 files changed, 28 insertions, 2 deletions
diff --git a/chef-config/lib/chef-config/path_helper.rb b/chef-config/lib/chef-config/path_helper.rb index 7fc79ba4a9..10384974c7 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..399b3dc965 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 without using backslashes for path separators" 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..fb6615d741 100644 --- a/lib/chef/data_bag.rb +++ b/lib/chef/data_bag.rb @@ -99,7 +99,8 @@ class Chef 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 +126,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 |