bugfix: reading binary profile data on windows (#1906)

On Windows, we ran into the problem that the execution of inherited profiles would (sometimes) not work. This was due to the use of `File.read` and `File.write` and handling inside the file provider, which works in most cases (especially *nix systems), but does not behave as expected on Windows. A better and more correct way of treating these files is via binary read and write mode, which changes the underlying encoding of both strings that are passed along.

Signed-off-by: Dominik Richter <dominik.richter@gmail.com>
This commit is contained in:
Dominik Richter 2017-06-08 10:19:09 +02:00 committed by Christoph Hartmann
parent 4f34e3eb83
commit ffdce8ab5f
2 changed files with 23 additions and 2 deletions

View file

@ -24,10 +24,21 @@ module Inspec
def initialize(_path)
end
# Read the contents of a file. This will typically refer to a text
# file reading a string.
#
# @param _file [String] path of the file to be read
# @return [String] contents of the file described
def read(_file)
raise "#{self} does not implement `read(...)`. This is required."
end
# Provide a method for reading binary contents from a file.
# It will default to #read if not defined. For most streams that implement
# it, it will be the same. For some special cases, it will add change the
# way in which encoding of the returned data structure is handled.
alias binread read
def files
raise "Fetcher #{self} does not implement `files()`. This is required."
end
@ -65,6 +76,12 @@ module Inspec
return nil unless File.file?(file)
File.read(file)
end
def binread(file)
return nil unless files.include?(file)
return nil unless File.file?(file)
File.binread(file)
end
end
class ZipProvider < FileProvider
@ -163,6 +180,10 @@ module Inspec
parent.read(abs_path(file))
end
def binread(file)
parent.binread(abs_path(file))
end
private
def get_prefix(fs)

View file

@ -37,7 +37,7 @@ module Inspec
cache = file_provider.files.find_all do |entry|
entry.start_with?('vendor')
end
content = Hash[cache.map { |x| [x, file_provider.read(x)] }]
content = Hash[cache.map { |x| [x, file_provider.binread(x)] }]
keys = content.keys
keys.each do |key|
next if content[key].nil?
@ -47,7 +47,7 @@ module Inspec
FileUtils.mkdir_p tar.dirname.to_s
Inspec::Log.debug "Copy #{tar} to cache directory"
File.write(tar.to_s, content[key].force_encoding('UTF-8'))
File.binwrite(tar.to_s, content[key])
end
end