Merge remote-tracking branch 'remotes/matsu911/master'
This commit is contained in:
		
						commit
						71225dc628
					
				|  | @ -12,7 +12,7 @@ module Zip | ||||||
|   class NullEncrypter < Encrypter |   class NullEncrypter < Encrypter | ||||||
|     include NullEncryption |     include NullEncryption | ||||||
| 
 | 
 | ||||||
|     def header(crc32) |     def header(mtime) | ||||||
|       '' |       '' | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -20,6 +20,10 @@ module Zip | ||||||
|       data |       data | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  |     def data_descriptor(crc32, compressed_size, uncomprssed_size) | ||||||
|  |       '' | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|     def reset! |     def reset! | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ module Zip | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def gp_flags |     def gp_flags | ||||||
|       1 |       0x0001 | 0x0008 | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     protected |     protected | ||||||
|  | @ -39,12 +39,13 @@ module Zip | ||||||
|   class TraditionalEncrypter < Encrypter |   class TraditionalEncrypter < Encrypter | ||||||
|     include TraditionalEncryption |     include TraditionalEncryption | ||||||
| 
 | 
 | ||||||
|     def header(crc32) |     def header(mtime) | ||||||
|       [].tap do |header| |       [].tap do |header| | ||||||
|         (header_bytesize - 1).times do |         (header_bytesize - 2).times do | ||||||
|           header << Random.rand(0..255) |           header << Random.rand(0..255) | ||||||
|         end |         end | ||||||
|         header << (crc32 >> 24) |         header << (mtime.to_binary_dos_time & 0xff) | ||||||
|  |         header << (mtime.to_binary_dos_time >> 8) | ||||||
|       end.map{|x| encode x}.pack("C*") |       end.map{|x| encode x}.pack("C*") | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -52,6 +53,10 @@ module Zip | ||||||
|       data.unpack("C*").map{|x| encode x}.pack("C*") |       data.unpack("C*").map{|x| encode x}.pack("C*") | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  |     def data_descriptor(crc32, compressed_size, uncomprssed_size) | ||||||
|  |       [0x08074b50, crc32, compressed_size, uncomprssed_size].pack("VVVV") | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|     def reset! |     def reset! | ||||||
|       reset_keys! |       reset_keys! | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ module Zip | ||||||
|       super() |       super() | ||||||
|       @output_stream = output_stream |       @output_stream = output_stream | ||||||
|       @zlib_deflater = ::Zlib::Deflate.new(level, -::Zlib::MAX_WBITS) |       @zlib_deflater = ::Zlib::Deflate.new(level, -::Zlib::MAX_WBITS) | ||||||
|       @size          = encrypter.header_bytesize |       @size          = 0 | ||||||
|       @crc           = ::Zlib.crc32 |       @crc           = ::Zlib.crc32 | ||||||
|       @encrypter     = encrypter |       @encrypter     = encrypter | ||||||
|       @buffer_stream = ::StringIO.new('') |       @buffer_stream = ::StringIO.new('') | ||||||
|  | @ -19,7 +19,6 @@ module Zip | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def finish |     def finish | ||||||
|       @output_stream << @encrypter.header(@crc) |  | ||||||
|       @output_stream << @encrypter.encrypt(@buffer_stream.string) |       @output_stream << @encrypter.encrypt(@buffer_stream.string) | ||||||
|       @output_stream << @encrypter.encrypt(@zlib_deflater.finish) until @zlib_deflater.finished? |       @output_stream << @encrypter.encrypt(@zlib_deflater.finish) until @zlib_deflater.finished? | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  | @ -143,7 +143,7 @@ module Zip | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def next_header_offset #:nodoc:all |     def next_header_offset #:nodoc:all | ||||||
|       local_entry_offset + self.compressed_size |       local_entry_offset + self.compressed_size + data_descriptor_size | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     # Extracts entry to file dest_path (defaults to @name). |     # Extracts entry to file dest_path (defaults to @name). | ||||||
|  | @ -648,6 +648,10 @@ module Zip | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  |     def data_descriptor_size | ||||||
|  |       (@gp_flags & 0x0008) > 0 ? 16 : 0 | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|     # create a zip64 extra information field if we need one |     # create a zip64 extra information field if we need one | ||||||
|     def prep_zip64_extra(for_local_header) #:nodoc:all |     def prep_zip64_extra(for_local_header) #:nodoc:all | ||||||
|       return unless ::Zip.write_zip64_support |       return unless ::Zip.write_zip64_support | ||||||
|  |  | ||||||
|  | @ -123,10 +123,12 @@ module Zip | ||||||
| 
 | 
 | ||||||
|     def finalize_current_entry |     def finalize_current_entry | ||||||
|       return unless @current_entry |       return unless @current_entry | ||||||
|  |       @output_stream << @encrypter.header(@current_entry.mtime) | ||||||
|       finish |       finish | ||||||
|       @current_entry.compressed_size = @output_stream.tell - @current_entry.local_header_offset - @current_entry.calculate_local_header_size |       @current_entry.compressed_size = @output_stream.tell - @current_entry.local_header_offset - @current_entry.calculate_local_header_size | ||||||
|       @current_entry.size = @compressor.size |       @current_entry.size = @compressor.size | ||||||
|       @current_entry.crc = @compressor.crc |       @current_entry.crc = @compressor.crc | ||||||
|  |       @output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size) | ||||||
|       @current_entry.gp_flags |= @encrypter.gp_flags |       @current_entry.gp_flags |= @encrypter.gp_flags | ||||||
|       @current_entry = nil |       @current_entry = nil | ||||||
|       @compressor = ::Zip::NullCompressor.instance |       @compressor = ::Zip::NullCompressor.instance | ||||||
|  |  | ||||||
|  | @ -14,9 +14,7 @@ class NullEncrypterTest < MiniTest::Test | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_header |   def test_header | ||||||
|     [nil, '', 'a' * 10, 0xffffffff].each do |arg| |     assert_empty @encrypter.header(nil) | ||||||
|       assert_empty @encrypter.header(arg) |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_encrypt |   def test_encrypt | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ require 'test_helper' | ||||||
| 
 | 
 | ||||||
| class TraditionalEncrypterTest < MiniTest::Test | class TraditionalEncrypterTest < MiniTest::Test | ||||||
|   def setup |   def setup | ||||||
|  |     @mtime = ::Zip::DOSTime.new(2014, 12, 17, 15, 56, 24) | ||||||
|     @encrypter = ::Zip::TraditionalEncrypter.new('password') |     @encrypter = ::Zip::TraditionalEncrypter.new('password') | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  | @ -10,36 +11,36 @@ class TraditionalEncrypterTest < MiniTest::Test | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_gp_flags |   def test_gp_flags | ||||||
|     assert_equal 1, @encrypter.gp_flags |     assert_equal 9, @encrypter.gp_flags | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_header |   def test_header | ||||||
|     @encrypter.reset! |     @encrypter.reset! | ||||||
|     exepected = [239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 116, 154].pack("C*") |     exepected = [239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 121, 91].pack("C*") | ||||||
|     Random.stub(:rand, 1) do |     Random.stub(:rand, 1) do | ||||||
|       assert_equal exepected, @encrypter.header(0xffffffff) |       assert_equal exepected, @encrypter.header(@mtime) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_encrypt |   def test_encrypt | ||||||
|     @encrypter.reset! |     @encrypter.reset! | ||||||
|     Random.stub(:rand, 1) { @encrypter.header(0xffffffff) } |     Random.stub(:rand, 1) { @encrypter.header(@mtime) } | ||||||
|     assert_raises(NoMethodError) { @encrypter.encrypt(nil) } |     assert_raises(NoMethodError) { @encrypter.encrypt(nil) } | ||||||
|     assert_raises(NoMethodError) { @encrypter.encrypt(1) } |     assert_raises(NoMethodError) { @encrypter.encrypt(1) } | ||||||
|     assert_equal '', @encrypter.encrypt('') |     assert_equal '', @encrypter.encrypt('') | ||||||
|     assert_equal [2, 25, 13, 222, 17, 190, 250, 133, 133, 166].pack("C*"), @encrypter.encrypt('a' * 10) |     assert_equal [100, 218, 7, 114, 226, 82, 62, 93, 224, 62].pack("C*"), @encrypter.encrypt('a' * 10) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_reset! |   def test_reset! | ||||||
|     @encrypter.reset! |     @encrypter.reset! | ||||||
|     Random.stub(:rand, 1) { @encrypter.header(0xffffffff) } |     Random.stub(:rand, 1) { @encrypter.header(@mtime) } | ||||||
|     [2, 25, 13, 222, 17, 190, 250, 133, 133, 166].map(&:chr).each do |c| |     [100, 218, 7, 114, 226, 82, 62, 93, 224, 62].map(&:chr).each do |c| | ||||||
|       assert_equal c, @encrypter.encrypt('a') |       assert_equal c, @encrypter.encrypt('a') | ||||||
|     end |     end | ||||||
|     assert_equal 134.chr, @encrypter.encrypt('a') |     assert_equal 56.chr, @encrypter.encrypt('a') | ||||||
|     @encrypter.reset! |     @encrypter.reset! | ||||||
|     Random.stub(:rand, 1) { @encrypter.header(0xffffffff) } |     Random.stub(:rand, 1) { @encrypter.header(@mtime) } | ||||||
|     [2, 25, 13, 222, 17, 190, 250, 133, 133, 166].map(&:chr).each do |c| |     [100, 218, 7, 114, 226, 82, 62, 93, 224, 62].map(&:chr).each do |c| | ||||||
|       assert_equal c, @encrypter.encrypt('a') |       assert_equal c, @encrypter.encrypt('a') | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  | @ -55,24 +56,24 @@ class TraditionalDecrypterTest < MiniTest::Test | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_gp_flags |   def test_gp_flags | ||||||
|     assert_equal 1, @decrypter.gp_flags |     assert_equal 9, @decrypter.gp_flags | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_decrypt |   def test_decrypt | ||||||
|     @decrypter.reset!([239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 116, 154].pack("C*")) |     @decrypter.reset!([239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 121, 91].pack("C*")) | ||||||
|     [2, 25, 13, 222, 17, 190, 250, 133, 133, 166].map(&:chr).each do |c| |     [100, 218, 7, 114, 226, 82, 62, 93, 224, 62].map(&:chr).each do |c| | ||||||
|       assert_equal 'a', @decrypter.decrypt(c) |       assert_equal 'a', @decrypter.decrypt(c) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_reset! |   def test_reset! | ||||||
|     @decrypter.reset!([239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 116, 154].pack("C*")) |     @decrypter.reset!([239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 121, 91].pack("C*")) | ||||||
|     [2, 25, 13, 222, 17, 190, 250, 133, 133, 166].map(&:chr).each do |c| |     [100, 218, 7, 114, 226, 82, 62, 93, 224, 62].map(&:chr).each do |c| | ||||||
|       assert_equal 'a', @decrypter.decrypt(c) |       assert_equal 'a', @decrypter.decrypt(c) | ||||||
|     end |     end | ||||||
|     assert_equal 229.chr, @decrypter.decrypt(2.chr) |     assert_equal 91.chr, @decrypter.decrypt(2.chr) | ||||||
|     @decrypter.reset!([239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 116, 154].pack("C*")) |     @decrypter.reset!([239, 57, 234, 154, 246, 80, 83, 221, 74, 200, 121, 91].pack("C*")) | ||||||
|     [2, 25, 13, 222, 17, 190, 250, 133, 133, 166].map(&:chr).each do |c| |     [100, 218, 7, 114, 226, 82, 62, 93, 224, 62].map(&:chr).each do |c| | ||||||
|       assert_equal 'a', @decrypter.decrypt(c) |       assert_equal 'a', @decrypter.decrypt(c) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1,33 @@ | ||||||
|  | require 'test_helper' | ||||||
|  | 
 | ||||||
|  | class EncryptionTest < MiniTest::Test | ||||||
|  |   ENCRYPT_ZIP_TEST_FILE = 'test/data/zipWithEncryption.zip' | ||||||
|  |   INPUT_FILE1 = 'test/data/file1.txt' | ||||||
|  | 
 | ||||||
|  |   def test_encrypt | ||||||
|  |     test_file = open(ENCRYPT_ZIP_TEST_FILE, 'rb').read | ||||||
|  | 
 | ||||||
|  |     @rand = [250, 143, 107, 13, 143, 22, 155, 75, 228, 150, 12] | ||||||
|  |     @output = ::Zip::DOSTime.stub(:now, ::Zip::DOSTime.new(2014, 12, 17, 15, 56, 24)) do | ||||||
|  |       Random.stub(:rand, lambda { |range| @rand.shift }) do | ||||||
|  |         Zip::OutputStream.write_buffer(::StringIO.new(''), Zip::TraditionalEncrypter.new('password')) do |zos| | ||||||
|  |           zos.put_next_entry('file1.txt') | ||||||
|  |           zos.write open(INPUT_FILE1).read | ||||||
|  |         end.string | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     @output.unpack("C*").each_with_index do |c, i| | ||||||
|  |       assert_equal test_file[i].ord, c | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def test_decrypt | ||||||
|  |     Zip::InputStream.open(ENCRYPT_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 | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
		Loading…
	
		Reference in New Issue