Prior to this commit, if Vagrant received checksum options from Vagrant Cloud that were simply empty strings, it would try to validate its checksum with those options. This commit fixes that by ignoring empty string values.
75 lines
1.8 KiB
Ruby
75 lines
1.8 KiB
Ruby
# This is an "interface" that should be implemented by any digest class
|
|
# passed into FileChecksum. Note that this isn't strictly enforced at
|
|
# the moment, and this class isn't directly used. It is merely here for
|
|
# documentation of structure of the class.
|
|
|
|
require "vagrant/errors"
|
|
|
|
class DigestClass
|
|
def update(string); end
|
|
def hexdigest; end
|
|
end
|
|
|
|
class FileChecksum
|
|
BUFFER_SIZE = 1024 * 8
|
|
|
|
# Supported file checksum
|
|
CHECKSUM_MAP = {
|
|
:md5 => Digest::MD5,
|
|
:sha1 => Digest::SHA1,
|
|
:sha256 => Digest::SHA256,
|
|
:sha384 => Digest::SHA384,
|
|
:sha512 => Digest::SHA512
|
|
}.freeze
|
|
|
|
# Initializes an object to calculate the checksum of a file. The given
|
|
# ``digest_klass`` should implement the ``DigestClass`` interface. Note
|
|
# that the built-in Ruby digest classes duck type this properly:
|
|
# Digest::MD5, Digest::SHA1, etc.
|
|
def initialize(path, digest_klass)
|
|
if digest_klass.is_a?(Class)
|
|
@digest_klass = digest_klass
|
|
else
|
|
@digest_klass = load_digest(digest_klass)
|
|
end
|
|
|
|
@path = path
|
|
end
|
|
|
|
# This calculates the checksum of the file and returns it as a
|
|
# string.
|
|
#
|
|
# @return [String]
|
|
def checksum
|
|
digest = @digest_klass.new
|
|
buf = ''
|
|
|
|
File.open(@path, "rb") do |f|
|
|
while !f.eof
|
|
begin
|
|
f.readpartial(BUFFER_SIZE, buf)
|
|
digest.update(buf)
|
|
rescue EOFError
|
|
# Although we check for EOF earlier, this seems to happen
|
|
# sometimes anyways [GH-2716].
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
digest.hexdigest
|
|
end
|
|
|
|
private
|
|
|
|
def load_digest(type)
|
|
digest = CHECKSUM_MAP[type.to_s.to_sym]
|
|
if digest.nil?
|
|
raise Vagrant::Errors::BoxChecksumInvalidType,
|
|
type: type.to_s,
|
|
types: CHECKSUM_MAP.keys.join(', ')
|
|
end
|
|
digest
|
|
end
|
|
end
|