From 95807328146ba440843e3703ce36b51b0147d36e Mon Sep 17 00:00:00 2001 From: Adam Leff Date: Tue, 11 Jul 2017 15:33:55 -0400 Subject: [PATCH] Source reader should not hand back files with nil contents (#2003) If a profile has a data files directory that looks like this: ``` files/platforms/one/data.json files/platforms/two/data.json files/platforms/three/data.json ``` ... the source reader will return the directories in the list of files but with nil contents. This causes an issue when Inspec::Profile tries to create a sha256 checksum of the profile contents only to try to cast nil to a string when building the null-delimited profile contents string. Files that are empty will have an empty string as its contents, so it's safe to assume that file entries with nil contents are actually a directory and have no affect on the profile's checksum. Therefore, this change will eliminate any file entries in responses from the source readers where the contents are nil. Signed-off-by: Adam Leff --- lib/source_readers/inspec.rb | 6 +++--- test/unit/dsl/other_keywords_test.rb | 2 +- test/unit/file_provider_test.rb | 9 ++++++--- .../complete-profile/files/a_sub_dir/sub_items.conf | 2 ++ test/unit/profiles/profile_test.rb | 2 +- test/unit/source_readers/inspec_test.rb | 5 +++-- 6 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 test/unit/mock/profiles/complete-profile/files/a_sub_dir/sub_items.conf diff --git a/lib/source_readers/inspec.rb b/lib/source_readers/inspec.rb index b208bfd99..0d040ce12 100644 --- a/lib/source_readers/inspec.rb +++ b/lib/source_readers/inspec.rb @@ -54,21 +54,21 @@ module SourceReaders tests = @target.files.find_all do |path| path.start_with?('controls') && path.end_with?('.rb') end - Hash[tests.map { |x| [x, @target.read(x)] }] + Hash[tests.map { |x| [x, @target.read(x)] }.delete_if { |_file, contents| contents.nil? }] end def load_libs tests = @target.files.find_all do |path| path.start_with?('libraries') && path.end_with?('.rb') end - Hash[tests.map { |x| [x, @target.read(x)] }] + Hash[tests.map { |x| [x, @target.read(x)] }.delete_if { |_file, contents| contents.nil? }] end def load_data_files files = @target.files.find_all do |path| path.start_with?('files' + File::SEPARATOR) end - Hash[files.map { |x| [x, @target.read(x)] }] + Hash[files.map { |x| [x, @target.read(x)] }.delete_if { |_file, contents| contents.nil? }] end end end diff --git a/test/unit/dsl/other_keywords_test.rb b/test/unit/dsl/other_keywords_test.rb index f43860036..cefaad159 100644 --- a/test/unit/dsl/other_keywords_test.rb +++ b/test/unit/dsl/other_keywords_test.rb @@ -46,7 +46,7 @@ describe 'inspec keyword' do end it 'lists all profile files when calling #files' do - load_in_profile('inspec.profile.files').must_equal %w{items.conf} + load_in_profile('inspec.profile.files').must_equal %w{a_sub_dir/sub_items.conf items.conf} end end diff --git a/test/unit/file_provider_test.rb b/test/unit/file_provider_test.rb index a0b4a3be3..fd9a50a7c 100644 --- a/test/unit/file_provider_test.rb +++ b/test/unit/file_provider_test.rb @@ -86,7 +86,8 @@ describe Inspec::ZipProvider do it 'must contain all files' do subject.files.sort.must_equal %w{inspec.yml libraries libraries/testlib.rb - controls controls/filesystem_spec.rb files files/items.conf}.sort + controls controls/filesystem_spec.rb files files/a_sub_dir + files/a_sub_dir/sub_items.conf files/items.conf}.sort end it 'must not read if the file isnt included' do @@ -108,7 +109,8 @@ describe Inspec::ZipProvider do it 'must contain all files' do subject.files.sort.must_equal %w{inspec.yml libraries libraries/testlib.rb - controls controls/filesystem_spec.rb files files/items.conf}.sort + controls controls/filesystem_spec.rb files files/a_sub_dir + files/a_sub_dir/sub_items.conf files/items.conf}.sort end it 'must not read if the file isnt included' do @@ -129,7 +131,8 @@ describe Inspec::TarProvider do it 'must contain all files' do subject.files.sort.must_equal %w{inspec.yml libraries libraries/testlib.rb - controls controls/filesystem_spec.rb files files/items.conf}.sort + controls controls/filesystem_spec.rb files files/a_sub_dir + files/a_sub_dir/sub_items.conf files/items.conf}.sort end it 'must not read if the file isnt included' do diff --git a/test/unit/mock/profiles/complete-profile/files/a_sub_dir/sub_items.conf b/test/unit/mock/profiles/complete-profile/files/a_sub_dir/sub_items.conf new file mode 100644 index 000000000..43b252ccd --- /dev/null +++ b/test/unit/mock/profiles/complete-profile/files/a_sub_dir/sub_items.conf @@ -0,0 +1,2 @@ +[section] +key = value diff --git a/test/unit/profiles/profile_test.rb b/test/unit/profiles/profile_test.rb index a14796622..9bd412601 100644 --- a/test/unit/profiles/profile_test.rb +++ b/test/unit/profiles/profile_test.rb @@ -70,7 +70,7 @@ describe Inspec::Profile do end it 'works on a complete profile' do - MockLoader.load_profile('complete-profile').sha256.must_equal 'b3dc0ec4603499ca9613e34da4a9476266875b8361b16be9284b39d1beacddd3' + MockLoader.load_profile('complete-profile').sha256.must_equal '5a129bd0a06f3d27589871a8dc8c65361d3730e802b926755191b610b7f99d3a' end end diff --git a/test/unit/source_readers/inspec_test.rb b/test/unit/source_readers/inspec_test.rb index 6b5900edd..659177917 100644 --- a/test/unit/source_readers/inspec_test.rb +++ b/test/unit/source_readers/inspec_test.rb @@ -36,8 +36,9 @@ describe SourceReaders::InspecReader do end it 'retrieves all extra files' do - _(res.data_files.keys).must_equal %w{files/items.conf} - _(res.data_files.values[0]).must_equal "one\ntwo\nthree\n" + _(res.data_files.keys).must_equal %w{files/a_sub_dir/sub_items.conf files/items.conf} + _(res.data_files['files/items.conf']).must_equal "one\ntwo\nthree\n" + _(res.data_files['files/a_sub_dir/sub_items.conf']).must_equal "[section]\nkey = value\n" end end