Rename `GPFBit3Error` to `StreamingError`.

`GPFBit3Error` doesn't really mean anything to the general user, and
it's not descriptive of the issue at hand. This error is raised when a
zip file cannot be streamed via `InputStream`, so `StreamingError` makes
more sense.

Also standardize the error message while we're about it.
This commit is contained in:
Robert Haines 2021-11-28 16:51:06 +00:00
parent 2e4dd9e0aa
commit 03a9ee6b8a
5 changed files with 29 additions and 15 deletions

View File

@ -185,7 +185,7 @@ There is one exception where it can not work however, and this is if the file do
> If bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written. The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure (optionally preceded by a 4-byte signature) immediately after the compressed data.
If `Zip::InputStream` finds such an entry in the zip archive it will raise an exception (`Zip::GPFBit3Error`).
If `Zip::InputStream` finds such an entry in the zip archive it will raise an exception (`Zip::StreamingError`).
`Zip::InputStream` is not designed to be used for random access in a zip file. When performing any operations on an entry that you are accessing via `Zip::InputStream.get_next_entry` then you should complete any such operations before the next call to `get_next_entry`.

View File

@ -7,7 +7,6 @@ module Zip
class EntryNameError < Error; end
class EntrySizeError < Error; end
class InternalError < Error; end
class GPFBit3Error < Error; end
class DecompressionError < Error; end
class SplitArchiveError < Error; end
@ -23,4 +22,19 @@ module Zip
"Unsupported compression method: #{COMPRESSION_METHODS[@compression_method]}."
end
end
class StreamingError < Error
attr_reader :entry
def initialize(entry)
super()
@entry = entry
end
def message
"The local header of this entry ('#{@entry.name}') does not contain " \
'the correct metadata for `Zip::InputStream` to be able to ' \
'uncompress it. Please use `Zip::File` instead of `Zip::InputStream`.'
end
end
end

View File

@ -70,12 +70,7 @@ module Zip
# Returns nil when there are no more entries.
def get_next_entry
unless @current_entry.nil?
if @current_entry.incomplete?
raise GPFBit3Error,
'It is not possible to get complete info from the local ' \
'header to extract this entry (GP flags bit 3 is set). ' \
'Please use `Zip::File` instead of `Zip::InputStream`.'
end
raise StreamingError, @current_entry if @current_entry.incomplete?
@archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET)
end
@ -151,10 +146,7 @@ module Zip
if @current_entry.incomplete? && @current_entry.compressed_size == 0 \
&& !@complete_entry
raise GPFBit3Error,
'It is not possible to get complete info from the local ' \
'header to extract this entry (GP flags bit 3 is set). ' \
'Please use `Zip::File` instead of `Zip::InputStream`.'
raise StreamingError, @current_entry
end
@decrypted_io = get_decrypted_io

View File

@ -46,9 +46,13 @@ class ZipFileTest < MiniTest::Test
def test_get_input_stream_stored_with_gpflag_bit3
::Zip::File.open('test/data/gpbit3stored.zip') do |zf|
zis = zf.get_input_stream('file1.txt')
assert_raises(::Zip::GPFBit3Error) do
error = assert_raises(::Zip::StreamingError) do
zis.get_next_entry
end
assert_match(/file1\.txt/, error.message)
assert_equal('file1.txt', error.entry.name)
zf.get_input_stream('file2.txt')
end
end

View File

@ -69,17 +69,21 @@ class ZipInputStreamTest < MiniTest::Test
def test_open_file_with_gp3bit_set
::Zip::InputStream.open('test/data/gpbit3stored.zip') do |zis|
assert_raises(::Zip::GPFBit3Error) do
error = assert_raises(::Zip::StreamingError) do
zis.get_next_entry
end
assert_match(/file1\.txt/, error.message)
assert_equal('file1.txt', error.entry.name)
end
end
def test_open_file_with_gp3bit_set_created_by_osx_archive
::Zip::InputStream.open('test/data/osx-archive.zip') do |zis|
assert_raises(::Zip::GPFBit3Error) do
error = assert_raises(::Zip::StreamingError) do
zis.get_next_entry
end
assert_match(/1\.txt/, error.message)
assert_equal('1.txt', error.entry.name)
end
end