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