bugfix: empty file strings from archive readers (#2027)

* bugfix: empty file strings from archive readers

Empty files in archives are sometimes possible (we just ran into this with TGZ), but is never a valid file to extract. So remove it and discount it altogether. Changed structure to support testing of these global calls.

Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

* lint and rebuild

Signed-off-by: Dominik Richter <dominik.richter@gmail.com>
This commit is contained in:
Dominik Richter 2017-07-24 09:37:13 -07:00 committed by GitHub
parent 885a7e90ca
commit a4bd38915c
2 changed files with 55 additions and 6 deletions

View file

@ -97,9 +97,10 @@ module Inspec
@path = path
@contents = {}
@files = []
::Zip::InputStream.open(@path) do |io|
walk_zip(@path) do |io|
while (entry = io.get_next_entry)
@files.push(entry.name.sub(%r{/+$}, ''))
name = entry.name.sub(%r{/+$}, '')
@files.push(name) unless name.empty?
end
end
end
@ -110,10 +111,14 @@ module Inspec
private
def walk_zip(path, &callback)
::Zip::InputStream.open(path, &callback)
end
def read_from_zip(file)
return nil unless @files.include?(file)
res = nil
::Zip::InputStream.open(@path) do |io|
walk_zip(@path) do |io|
while (entry = io.get_next_entry)
next unless file == entry.name
res = io.read
@ -131,8 +136,8 @@ module Inspec
@path = path
@contents = {}
@files = []
Gem::Package::TarReader.new(Zlib::GzipReader.open(@path)) do |tar|
@files = tar.map(&:full_name)
walk_tar(@path) do |tar|
@files = tar.map(&:full_name).find_all { |x| !x.empty? }
end
end
@ -142,11 +147,15 @@ module Inspec
private
def walk_tar(path, &callback)
Gem::Package::TarReader.new(Zlib::GzipReader.open(path), &callback)
end
def read_from_tar(file)
return nil unless @files.include?(file)
res = nil
# NB `TarReader` includes `Enumerable` beginning with Ruby 2.x
Gem::Package::TarReader.new(Zlib::GzipReader.open(@path)) do |tar|
walk_tar(@path) do |tar|
tar.each do |entry|
next unless entry.file? && file == entry.full_name
res = entry.read

View file

@ -98,6 +98,28 @@ describe Inspec::ZipProvider do
subject.read('inspec.yml').must_match(/^name: complete$/)
end
end
describe 'applied to a zip with an empty filename' do
# Just a placeholder, it will be ignored anyway:
let(:cls) {
class MockZipProvider < Inspec::ZipProvider
Entry = Struct.new(:name)
class List < Array
alias :get_next_entry :pop
end
private
def walk_zip(path, &callback)
list = List.new([Entry.new(''), Entry.new('zipzip'), Entry.new('')])
callback.call(list)
end
end
MockZipProvider
}
it 'must contain all files' do
cls.new(rand.to_s).files.must_equal %w{zipzip}
end
end
end
@ -143,6 +165,24 @@ describe Inspec::TarProvider do
subject.read('inspec.yml').must_match(/^name: complete$/)
end
end
describe 'applied to a tar with an empty filename' do
# Just a placeholder, it will be ignored anyway:
let(:cls) {
class MockTarProvider < Inspec::TarProvider
Entry = Struct.new(:full_name)
private
def walk_tar(path, &callback)
callback.call([Entry.new(''), Entry.new('tartar'), Entry.new('')])
end
end
MockTarProvider
}
it 'must contain all files' do
cls.new(rand.to_s).files.must_equal %w{tartar}
end
end
end
describe Inspec::RelativeFileProvider do