diff --git a/lib/zip/input_stream.rb b/lib/zip/input_stream.rb index a901703..e417916 100644 --- a/lib/zip/input_stream.rb +++ b/lib/zip/input_stream.rb @@ -130,25 +130,30 @@ module Zip 'General purpose flag Bit 3 is set so not possible to get proper info from local header.' \ 'Please use ::Zip::File instead of ::Zip::InputStream' end + @decrypted_io = get_decrypted_io @decompressor = get_decompressor flush @current_entry end + def get_decrypted_io + header = @archive_io.read(@decrypter.header_bytesize) + @decrypter.reset!(header) + + ::Zip::DecryptedIo.new(@archive_io, @decrypter) + end + def get_decompressor - if @current_entry.nil? - ::Zip::NullDecompressor - elsif @current_entry.compression_method == ::Zip::Entry::STORED + return ::Zip::NullDecompressor if @current_entry.nil? + + if @current_entry.compression_method == ::Zip::Entry::STORED if @current_entry.incomplete? && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry - ::Zip::PassThruDecompressor.new(@archive_io, @complete_entry.size) + ::Zip::PassThruDecompressor.new(@decrypted_io, @complete_entry.size) else - ::Zip::PassThruDecompressor.new(@archive_io, @current_entry.size) + ::Zip::PassThruDecompressor.new(@decrypted_io, @current_entry.size) end elsif @current_entry.compression_method == ::Zip::Entry::DEFLATED - header = @archive_io.read(@decrypter.header_bytesize) - @decrypter.reset!(header) - decrypted_io = ::Zip::DecryptedIo.new(@archive_io, @decrypter) - ::Zip::Inflater.new(decrypted_io) + ::Zip::Inflater.new(@decrypted_io) else raise ::Zip::CompressionMethodError, "Unsupported compression method #{@current_entry.compression_method}" diff --git a/test/data/zipWithStoredCompression.zip b/test/data/zipWithStoredCompression.zip new file mode 100644 index 0000000..045ab9d Binary files /dev/null and b/test/data/zipWithStoredCompression.zip differ diff --git a/test/data/zipWithStoredCompressionAndEncryption.zip b/test/data/zipWithStoredCompressionAndEncryption.zip new file mode 100644 index 0000000..2fd545e Binary files /dev/null and b/test/data/zipWithStoredCompressionAndEncryption.zip differ diff --git a/test/stored_support_test.rb b/test/stored_support_test.rb new file mode 100644 index 0000000..8260e4a --- /dev/null +++ b/test/stored_support_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class StoredSupportTest < MiniTest::Test + STORED_ZIP_TEST_FILE = 'test/data/zipWithStoredCompression.zip' + ENCRYPTED_STORED_ZIP_TEST_FILE = 'test/data/zipWithStoredCompressionAndEncryption.zip' + INPUT_FILE1 = 'test/data/file1.txt' + INPUT_FILE2 = 'test/data/file2.txt' + + def test_read + Zip::InputStream.open(STORED_ZIP_TEST_FILE) do |zis| + entry = zis.get_next_entry + assert_equal 'file1.txt', entry.name + assert_equal 1327, entry.size + assert_equal open(INPUT_FILE1, 'r').read, zis.read + entry = zis.get_next_entry + assert_equal 'file2.txt', entry.name + assert_equal 41234, entry.size + assert_equal open(INPUT_FILE2, 'r').read, zis.read + end + end + + def test_encrypted_read + Zip::InputStream.open(ENCRYPTED_STORED_ZIP_TEST_FILE, 0, Zip::TraditionalDecrypter.new('password')) do |zis| + entry = zis.get_next_entry + assert_equal 'file1.txt', entry.name + assert_equal 1327, entry.size + assert_equal open(INPUT_FILE1, 'r').read, zis.read + entry = zis.get_next_entry + assert_equal 'file2.txt', entry.name + assert_equal 41234, entry.size + assert_equal open(INPUT_FILE2, 'r').read, zis.read + end + end +end