lib/inspec/file_provider.rb in inspec-2.2.78 vs lib/inspec/file_provider.rb in inspec-2.2.101

- old
+ new

@@ -103,10 +103,26 @@ @files.push(name) unless name.empty? end end end + def extract(destination_path = '.') + FileUtils.mkdir_p(destination_path) + + Zip::File.open(@path) do |archive| + archive.each do |file| + final_path = File.join(destination_path, file.name) + + # This removes the top level directory (and any other files) to ensure + # extracted files do not conflict. + FileUtils.remove_entry(final_path) if File.exist?(final_path) + + archive.extract(file, final_path) + end + end + end + def read(file) @contents[file] ||= read_from_zip(file) end private @@ -148,17 +164,38 @@ # replace all items of the array simply with the relative filename of the file @files.map! { |x| Pathname.new(x.full_name).relative_path_from(Pathname.new('.')).to_s } end end + def extract(destination_path = '.') + FileUtils.mkdir_p(destination_path) + + walk_tar(@path) do |files| + files.each do |file| + next unless @files.include?(file.full_name) + final_path = File.join(destination_path, file.full_name) + + # This removes the top level directory (and any other files) to ensure + # extracted files do not conflict. + FileUtils.remove_entry(final_path) if File.exist?(final_path) + + FileUtils.mkdir_p(File.dirname(final_path)) + File.open(final_path, 'wb') { |f| f.write(file.read) } + end + end + end + def read(file) @contents[file] ||= read_from_tar(file) end private def walk_tar(path, &callback) - Gem::Package::TarReader.new(Zlib::GzipReader.open(path), &callback) + tar_file = Zlib::GzipReader.open(path) + Gem::Package::TarReader.new(tar_file, &callback) + ensure + tar_file.close end def read_from_tar(file) return nil unless @files.include?(file) res = nil