953942694f
ZipKit::FileReader raises MissingEOCD for truncated, corrupted, or non-zip files. This exception is a direct StandardError subclass, not a subclass of InvalidStructure or ReadError, so it escaped as an unhandled job failure instead of being caught and surfaced to the user. Broaden the rescue in ZipFile::Reader#initialize to catch ReadError (parent of InvalidStructure), MissingEOCD, and UnsupportedFeature.
29 lines
867 B
Ruby
29 lines
867 B
Ruby
class ZipFile::Reader
|
|
def initialize(io)
|
|
@io = io
|
|
@reader = ZipKit::FileReader.read_zip_structure(io: io)
|
|
rescue ZipKit::FileReader::ReadError, ZipKit::FileReader::MissingEOCD, ZipKit::FileReader::UnsupportedFeature => e
|
|
raise ZipFile::InvalidFileError, e.message
|
|
end
|
|
|
|
def read(file_path)
|
|
entry = @reader.find { |e| e.filename == file_path }
|
|
raise ArgumentError, "File not found in zip: #{file_path}" unless entry
|
|
raise ArgumentError, "Cannot read directory entry: #{file_path}" if entry.filename.end_with?("/")
|
|
|
|
if block_given?
|
|
yield ZipFile::Reader::IO.new(entry, @io)
|
|
else
|
|
entry.extractor_from(@io).extract
|
|
end
|
|
end
|
|
|
|
def glob(pattern)
|
|
@reader.map(&:filename).select { |name| File.fnmatch(pattern, name) }.sort
|
|
end
|
|
|
|
def exists?(file_path)
|
|
@reader.any? { |e| e.filename == file_path }
|
|
end
|
|
end
|