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