archive-zip 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HACKING +25 -42
- data/NEWS +25 -0
- data/README +2 -2
- data/Rakefile +202 -0
- data/TODO +5 -0
- data/default.mspec +8 -0
- data/lib/archive/support/binary_stringio.rb +23 -0
- data/lib/archive/support/integer.rb +13 -0
- data/lib/archive/support/io-like.rb +3 -1
- data/lib/archive/support/ioextensions.rb +16 -0
- data/lib/archive/support/iowindow.rb +10 -18
- data/lib/archive/support/time.rb +2 -0
- data/lib/archive/support/zlib.rb +298 -71
- data/lib/archive/zip.rb +161 -139
- data/lib/archive/zip/codec.rb +2 -0
- data/lib/archive/zip/codec/deflate.rb +59 -11
- data/lib/archive/zip/codec/null_encryption.rb +75 -14
- data/lib/archive/zip/codec/store.rb +75 -26
- data/lib/archive/zip/codec/traditional_encryption.rb +146 -35
- data/lib/archive/zip/data_descriptor.rb +6 -4
- data/lib/archive/zip/entry.rb +184 -132
- data/lib/archive/zip/error.rb +2 -0
- data/lib/archive/zip/extra_field.rb +20 -6
- data/lib/archive/zip/extra_field/extended_timestamp.rb +141 -60
- data/lib/archive/zip/extra_field/raw.rb +70 -12
- data/lib/archive/zip/extra_field/unix.rb +58 -16
- data/lib/archive/zip/version.rb +6 -0
- data/spec/archive/zip/codec/deflate/compress/checksum_spec.rb +42 -0
- data/spec/archive/zip/codec/deflate/compress/close_spec.rb +44 -0
- data/spec/archive/zip/codec/deflate/compress/crc32_spec.rb +21 -0
- data/spec/archive/zip/codec/deflate/compress/data_descriptor_spec.rb +67 -0
- data/spec/archive/zip/codec/deflate/compress/new_spec.rb +37 -0
- data/spec/archive/zip/codec/deflate/compress/open_spec.rb +46 -0
- data/spec/archive/zip/codec/deflate/compress/write_spec.rb +109 -0
- data/spec/archive/zip/codec/deflate/decompress/checksum_spec.rb +18 -0
- data/spec/archive/zip/codec/deflate/decompress/close_spec.rb +33 -0
- data/spec/archive/zip/codec/deflate/decompress/crc32_spec.rb +18 -0
- data/spec/archive/zip/codec/deflate/decompress/data_descriptor_spec.rb +67 -0
- data/spec/archive/zip/codec/deflate/decompress/new_spec.rb +14 -0
- data/spec/archive/zip/codec/deflate/decompress/open_spec.rb +27 -0
- data/spec/archive/zip/codec/deflate/fixtures/classes.rb +25 -0
- data/spec/archive/zip/codec/deflate/fixtures/compressed_file.bin +1 -0
- data/spec/archive/zip/codec/deflate/fixtures/compressed_file_nocomp.bin +0 -0
- data/spec/archive/zip/codec/deflate/fixtures/raw_file.txt +10 -0
- data/spec/archive/zip/codec/null_encryption/decrypt/close_spec.rb +33 -0
- data/spec/archive/zip/codec/null_encryption/decrypt/new_spec.rb +14 -0
- data/spec/archive/zip/codec/null_encryption/decrypt/open_spec.rb +27 -0
- data/spec/archive/zip/codec/null_encryption/decrypt/read_spec.rb +24 -0
- data/spec/archive/zip/codec/null_encryption/decrypt/rewind_spec.rb +25 -0
- data/spec/archive/zip/codec/null_encryption/decrypt/seek_spec.rb +57 -0
- data/spec/archive/zip/codec/null_encryption/decrypt/tell_spec.rb +21 -0
- data/spec/archive/zip/codec/null_encryption/encrypt/close_spec.rb +33 -0
- data/spec/archive/zip/codec/null_encryption/encrypt/new_spec.rb +14 -0
- data/spec/archive/zip/codec/null_encryption/encrypt/open_spec.rb +27 -0
- data/spec/archive/zip/codec/null_encryption/encrypt/rewind_spec.rb +26 -0
- data/spec/archive/zip/codec/null_encryption/encrypt/seek_spec.rb +50 -0
- data/spec/archive/zip/codec/null_encryption/encrypt/tell_spec.rb +29 -0
- data/spec/archive/zip/codec/null_encryption/encrypt/write_spec.rb +29 -0
- data/spec/archive/zip/codec/null_encryption/fixtures/classes.rb +12 -0
- data/spec/archive/zip/codec/null_encryption/fixtures/raw_file.txt +10 -0
- data/spec/archive/zip/codec/store/compress/close_spec.rb +33 -0
- data/spec/archive/zip/codec/store/compress/data_descriptor_spec.rb +68 -0
- data/spec/archive/zip/codec/store/compress/new_spec.rb +14 -0
- data/spec/archive/zip/codec/store/compress/open_spec.rb +27 -0
- data/spec/archive/zip/codec/store/compress/rewind_spec.rb +26 -0
- data/spec/archive/zip/codec/store/compress/seek_spec.rb +50 -0
- data/spec/archive/zip/codec/store/compress/tell_spec.rb +29 -0
- data/spec/archive/zip/codec/store/compress/write_spec.rb +29 -0
- data/spec/archive/zip/codec/store/decompress/close_spec.rb +33 -0
- data/spec/archive/zip/codec/store/decompress/data_descriptor_spec.rb +68 -0
- data/spec/archive/zip/codec/store/decompress/new_spec.rb +14 -0
- data/spec/archive/zip/codec/store/decompress/open_spec.rb +27 -0
- data/spec/archive/zip/codec/store/decompress/read_spec.rb +24 -0
- data/spec/archive/zip/codec/store/decompress/rewind_spec.rb +25 -0
- data/spec/archive/zip/codec/store/decompress/seek_spec.rb +57 -0
- data/spec/archive/zip/codec/store/decompress/tell_spec.rb +21 -0
- data/spec/archive/zip/codec/store/fixtures/classes.rb +12 -0
- data/spec/archive/zip/codec/store/fixtures/raw_file.txt +10 -0
- data/spec/archive/zip/codec/traditional_encryption/decrypt/close_spec.rb +64 -0
- data/spec/archive/zip/codec/traditional_encryption/decrypt/new_spec.rb +18 -0
- data/spec/archive/zip/codec/traditional_encryption/decrypt/open_spec.rb +39 -0
- data/spec/archive/zip/codec/traditional_encryption/decrypt/read_spec.rb +126 -0
- data/spec/archive/zip/codec/traditional_encryption/decrypt/rewind_spec.rb +38 -0
- data/spec/archive/zip/codec/traditional_encryption/decrypt/seek_spec.rb +82 -0
- data/spec/archive/zip/codec/traditional_encryption/decrypt/tell_spec.rb +25 -0
- data/spec/archive/zip/codec/traditional_encryption/encrypt/close_spec.rb +64 -0
- data/spec/archive/zip/codec/traditional_encryption/encrypt/new_spec.rb +18 -0
- data/spec/archive/zip/codec/traditional_encryption/encrypt/open_spec.rb +39 -0
- data/spec/archive/zip/codec/traditional_encryption/encrypt/rewind_spec.rb +41 -0
- data/spec/archive/zip/codec/traditional_encryption/encrypt/seek_spec.rb +75 -0
- data/spec/archive/zip/codec/traditional_encryption/encrypt/tell_spec.rb +42 -0
- data/spec/archive/zip/codec/traditional_encryption/encrypt/write_spec.rb +127 -0
- data/spec/archive/zip/codec/traditional_encryption/fixtures/classes.rb +27 -0
- data/spec/archive/zip/codec/traditional_encryption/fixtures/encrypted_file.bin +0 -0
- data/spec/archive/zip/codec/traditional_encryption/fixtures/raw_file.txt +10 -0
- data/spec/binary_stringio/new_spec.rb +34 -0
- data/spec/binary_stringio/set_encoding_spec.rb +14 -0
- data/spec/ioextensions/read_exactly_spec.rb +50 -0
- data/spec/zlib/fixtures/classes.rb +65 -0
- data/spec/zlib/fixtures/compressed_file.bin +1 -0
- data/spec/zlib/fixtures/compressed_file_gzip.bin +0 -0
- data/spec/zlib/fixtures/compressed_file_huffman.bin +2 -0
- data/spec/zlib/fixtures/compressed_file_minmem.bin +0 -0
- data/spec/zlib/fixtures/compressed_file_minwin.bin +1 -0
- data/spec/zlib/fixtures/compressed_file_nocomp.bin +0 -0
- data/spec/zlib/fixtures/compressed_file_raw.bin +1 -0
- data/spec/zlib/fixtures/raw_file.txt +10 -0
- data/spec/zlib/zreader/checksum_spec.rb +40 -0
- data/spec/zlib/zreader/close_spec.rb +14 -0
- data/spec/zlib/zreader/compressed_size_spec.rb +18 -0
- data/spec/zlib/zreader/new_spec.rb +41 -0
- data/spec/zlib/zreader/open_spec.rb +49 -0
- data/spec/zlib/zreader/read_spec.rb +47 -0
- data/spec/zlib/zreader/rewind_spec.rb +23 -0
- data/spec/zlib/zreader/seek_spec.rb +55 -0
- data/spec/zlib/zreader/tell_spec.rb +21 -0
- data/spec/zlib/zreader/uncompressed_size_spec.rb +18 -0
- data/spec/zlib/zwriter/checksum_spec.rb +41 -0
- data/spec/zlib/zwriter/close_spec.rb +14 -0
- data/spec/zlib/zwriter/compressed_size_spec.rb +19 -0
- data/spec/zlib/zwriter/new_spec.rb +64 -0
- data/spec/zlib/zwriter/open_spec.rb +68 -0
- data/spec/zlib/zwriter/rewind_spec.rb +26 -0
- data/spec/zlib/zwriter/seek_spec.rb +54 -0
- data/spec/zlib/zwriter/tell_spec.rb +29 -0
- data/spec/zlib/zwriter/uncompressed_size_spec.rb +19 -0
- data/spec/zlib/zwriter/write_spec.rb +28 -0
- data/spec_helper.rb +49 -0
- metadata +296 -74
- data/MANIFEST +0 -27
- data/lib/archive/support/io.rb +0 -14
- data/lib/archive/support/stringio.rb +0 -22
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
|
|
7
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Decrypt#rewind" do
|
|
8
|
+
it "can rewind the stream when the delegate responds to rewind" do
|
|
9
|
+
TraditionalEncryptionSpecs.encrypted_data do |ed|
|
|
10
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
11
|
+
ed,
|
|
12
|
+
TraditionalEncryptionSpecs.password,
|
|
13
|
+
TraditionalEncryptionSpecs.mtime
|
|
14
|
+
) do |d|
|
|
15
|
+
d.read(4)
|
|
16
|
+
lambda { d.rewind }.should_not raise_error
|
|
17
|
+
d.read.should == TraditionalEncryptionSpecs.test_data
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "raises Errno::EINVAL when attempting to rewind the stream when the delegate does not respond to rewind" do
|
|
23
|
+
delegate = mock('delegate')
|
|
24
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
25
|
+
# of version 1.5.10.
|
|
26
|
+
#delegate.should_receive(:read).with(an_instance_of(Fixnum)).at_least(:once).and_return { |n| "\000" * n }
|
|
27
|
+
# Use the following instead for now.
|
|
28
|
+
delegate.should_receive(:read).once.and_return("\000" * 12)
|
|
29
|
+
delegate.should_receive(:close).and_return(nil)
|
|
30
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
31
|
+
delegate,
|
|
32
|
+
TraditionalEncryptionSpecs.password,
|
|
33
|
+
TraditionalEncryptionSpecs.mtime
|
|
34
|
+
) do |d|
|
|
35
|
+
lambda { d.rewind }.should raise_error(Errno::EINVAL)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
|
|
7
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Decrypt#seek" do
|
|
8
|
+
it "can seek to the beginning of the stream when the delegate responds to rewind" do
|
|
9
|
+
TraditionalEncryptionSpecs.encrypted_data do |ed|
|
|
10
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
11
|
+
ed,
|
|
12
|
+
TraditionalEncryptionSpecs.password,
|
|
13
|
+
TraditionalEncryptionSpecs.mtime
|
|
14
|
+
) do |d|
|
|
15
|
+
d.read(4)
|
|
16
|
+
lambda { d.seek(0) }.should_not raise_error
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "raises Errno::EINVAL when attempting to seek to the beginning of the stream when the delegate does not respond to rewind" do
|
|
22
|
+
delegate = mock('delegate')
|
|
23
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
24
|
+
# of version 1.5.10.
|
|
25
|
+
#delegate.should_receive(:read).with(an_instance_of(Fixnum)).at_least(:once).and_return { |n| "\000" * n }
|
|
26
|
+
# Use the following instead for now.
|
|
27
|
+
delegate.should_receive(:read).once.and_return("\000" * 12)
|
|
28
|
+
delegate.should_receive(:close).and_return(nil)
|
|
29
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
30
|
+
delegate,
|
|
31
|
+
TraditionalEncryptionSpecs.password,
|
|
32
|
+
TraditionalEncryptionSpecs.mtime
|
|
33
|
+
) do |d|
|
|
34
|
+
lambda { d.seek(0) }.should raise_error(Errno::EINVAL)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "raises Errno::EINVAL when seeking forward or backward from the current position of the stream" do
|
|
39
|
+
TraditionalEncryptionSpecs.encrypted_data do |ed|
|
|
40
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
41
|
+
ed,
|
|
42
|
+
TraditionalEncryptionSpecs.password,
|
|
43
|
+
TraditionalEncryptionSpecs.mtime
|
|
44
|
+
) do |d|
|
|
45
|
+
# Disable read buffering to avoid some seeking optimizations implemented
|
|
46
|
+
# by IO::Like which allow seeking forward within the buffer.
|
|
47
|
+
d.fill_size = 0
|
|
48
|
+
|
|
49
|
+
d.read(4)
|
|
50
|
+
lambda { d.seek(1, IO::SEEK_CUR) }.should raise_error(Errno::EINVAL)
|
|
51
|
+
lambda { d.seek(-1, IO::SEEK_CUR) }.should raise_error(Errno::EINVAL)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "raises Errno::EINVAL when seeking a non-zero offset relative to the beginning of the stream" do
|
|
57
|
+
TraditionalEncryptionSpecs.encrypted_data do |ed|
|
|
58
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
59
|
+
ed,
|
|
60
|
+
TraditionalEncryptionSpecs.password,
|
|
61
|
+
TraditionalEncryptionSpecs.mtime
|
|
62
|
+
) do |d|
|
|
63
|
+
lambda { d.seek(-1, IO::SEEK_SET) }.should raise_error(Errno::EINVAL)
|
|
64
|
+
lambda { d.seek(1, IO::SEEK_SET) }.should raise_error(Errno::EINVAL)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "raises Errno::EINVAL when seeking relative to the end of the stream" do
|
|
70
|
+
TraditionalEncryptionSpecs.encrypted_data do |ed|
|
|
71
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
72
|
+
ed,
|
|
73
|
+
TraditionalEncryptionSpecs.password,
|
|
74
|
+
TraditionalEncryptionSpecs.mtime
|
|
75
|
+
) do |d|
|
|
76
|
+
lambda { d.seek(0, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
|
|
77
|
+
lambda { d.seek(-1, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
|
|
78
|
+
lambda { d.seek(1, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
|
|
7
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Decrypt#tell" do
|
|
8
|
+
it "returns the current position of the stream" do
|
|
9
|
+
TraditionalEncryptionSpecs.encrypted_data do |ed|
|
|
10
|
+
Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
|
|
11
|
+
ed,
|
|
12
|
+
TraditionalEncryptionSpecs.password,
|
|
13
|
+
TraditionalEncryptionSpecs.mtime
|
|
14
|
+
) do |d|
|
|
15
|
+
d.tell.should == 0
|
|
16
|
+
d.read(4)
|
|
17
|
+
d.tell.should == 4
|
|
18
|
+
d.read
|
|
19
|
+
d.tell.should == 235
|
|
20
|
+
d.rewind
|
|
21
|
+
d.tell.should == 0
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
require 'archive/support/binary_stringio'
|
|
7
|
+
|
|
8
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Encrypt#close" do
|
|
9
|
+
it "closes the stream" do
|
|
10
|
+
e = Archive::Zip::Codec::TraditionalEncryption::Encrypt.new(
|
|
11
|
+
BinaryStringIO.new,
|
|
12
|
+
TraditionalEncryptionSpecs.password,
|
|
13
|
+
TraditionalEncryptionSpecs.mtime
|
|
14
|
+
)
|
|
15
|
+
e.close
|
|
16
|
+
e.closed?.should be_true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "closes the delegate stream by default" do
|
|
20
|
+
delegate = mock('delegate')
|
|
21
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
22
|
+
# of version 1.5.10.
|
|
23
|
+
#delegate.should_receive(:write).with(an_instance_of(String)).at_least(:once).and_return { |s| s.length }
|
|
24
|
+
# Use the following instead for now.
|
|
25
|
+
delegate.should_receive(:write).at_least(:once).and_return(1)
|
|
26
|
+
delegate.should_receive(:close).and_return(nil)
|
|
27
|
+
e = Archive::Zip::Codec::TraditionalEncryption::Encrypt.new(
|
|
28
|
+
delegate,
|
|
29
|
+
TraditionalEncryptionSpecs.password,
|
|
30
|
+
TraditionalEncryptionSpecs.mtime
|
|
31
|
+
)
|
|
32
|
+
e.close
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "optionally leaves the delegate stream open" do
|
|
36
|
+
delegate = mock('delegate')
|
|
37
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
38
|
+
# of version 1.5.10.
|
|
39
|
+
#delegate.should_receive(:write).with(an_instance_of(String)).at_least(:once).and_return { |s| s.length }
|
|
40
|
+
# Use the following instead for now.
|
|
41
|
+
delegate.should_receive(:write).at_least(:once).and_return(1)
|
|
42
|
+
delegate.should_receive(:close).and_return(nil)
|
|
43
|
+
e = Archive::Zip::Codec::TraditionalEncryption::Encrypt.new(
|
|
44
|
+
delegate,
|
|
45
|
+
TraditionalEncryptionSpecs.password,
|
|
46
|
+
TraditionalEncryptionSpecs.mtime
|
|
47
|
+
)
|
|
48
|
+
e.close(true)
|
|
49
|
+
|
|
50
|
+
delegate = mock('delegate')
|
|
51
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
52
|
+
# of version 1.5.10.
|
|
53
|
+
#delegate.should_receive(:write).with(an_instance_of(String)).at_least(:once).and_return { |s| s.length }
|
|
54
|
+
# Use the following instead for now.
|
|
55
|
+
delegate.should_receive(:write).at_least(:once).and_return(1)
|
|
56
|
+
delegate.should_not_receive(:close)
|
|
57
|
+
e = Archive::Zip::Codec::TraditionalEncryption::Encrypt.new(
|
|
58
|
+
delegate,
|
|
59
|
+
TraditionalEncryptionSpecs.password,
|
|
60
|
+
TraditionalEncryptionSpecs.mtime
|
|
61
|
+
)
|
|
62
|
+
e.close(false)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
require 'archive/support/binary_stringio'
|
|
7
|
+
|
|
8
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Encrypt.new" do
|
|
9
|
+
it "returns a new instance" do
|
|
10
|
+
e = Archive::Zip::Codec::TraditionalEncryption::Encrypt.new(
|
|
11
|
+
BinaryStringIO.new,
|
|
12
|
+
TraditionalEncryptionSpecs.password,
|
|
13
|
+
TraditionalEncryptionSpecs.mtime
|
|
14
|
+
)
|
|
15
|
+
e.class.should == Archive::Zip::Codec::TraditionalEncryption::Encrypt
|
|
16
|
+
e.close
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
require 'archive/support/binary_stringio'
|
|
7
|
+
|
|
8
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Encrypt.open" do
|
|
9
|
+
it "returns a new instance when run without a block" do
|
|
10
|
+
e = Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
11
|
+
BinaryStringIO.new,
|
|
12
|
+
TraditionalEncryptionSpecs.password,
|
|
13
|
+
TraditionalEncryptionSpecs.mtime
|
|
14
|
+
)
|
|
15
|
+
e.class.should == Archive::Zip::Codec::TraditionalEncryption::Encrypt
|
|
16
|
+
e.close
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "executes a block with a new instance as an argument" do
|
|
20
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
21
|
+
BinaryStringIO.new,
|
|
22
|
+
TraditionalEncryptionSpecs.password,
|
|
23
|
+
TraditionalEncryptionSpecs.mtime
|
|
24
|
+
) do |encryptor|
|
|
25
|
+
encryptor.class.should == Archive::Zip::Codec::TraditionalEncryption::Encrypt
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "closes the object after executing a block" do
|
|
30
|
+
e = Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
31
|
+
BinaryStringIO.new,
|
|
32
|
+
TraditionalEncryptionSpecs.password,
|
|
33
|
+
TraditionalEncryptionSpecs.mtime
|
|
34
|
+
) do |encryptor|
|
|
35
|
+
encryptor
|
|
36
|
+
end
|
|
37
|
+
e.closed?.should.be_true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
require 'archive/support/binary_stringio'
|
|
7
|
+
|
|
8
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Encrypt#rewind" do
|
|
9
|
+
it "can rewind the stream when the delegate responds to rewind" do
|
|
10
|
+
encrypted_data = BinaryStringIO.new
|
|
11
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
12
|
+
encrypted_data,
|
|
13
|
+
TraditionalEncryptionSpecs.password,
|
|
14
|
+
TraditionalEncryptionSpecs.mtime
|
|
15
|
+
) do |e|
|
|
16
|
+
e.write('test')
|
|
17
|
+
# Ensure repeatable test data is used for encryption header.
|
|
18
|
+
srand(0)
|
|
19
|
+
lambda { e.rewind }.should_not raise_error
|
|
20
|
+
e.write(TraditionalEncryptionSpecs.test_data)
|
|
21
|
+
end
|
|
22
|
+
encrypted_data.string.should == TraditionalEncryptionSpecs.encrypted_data
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "raises Errno::EINVAL when attempting to rewind the stream when the delegate does not respond to rewind" do
|
|
26
|
+
delegate = mock('delegate')
|
|
27
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
28
|
+
# of version 1.5.10.
|
|
29
|
+
#delegate.should_receive(:write).with(an_instance_of(String)).at_least(:once).and_return { |s| s.length }
|
|
30
|
+
# Use the following instead for now.
|
|
31
|
+
delegate.should_receive(:write).at_least(:once).and_return(1)
|
|
32
|
+
delegate.should_receive(:close).once.and_return(nil)
|
|
33
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
34
|
+
delegate,
|
|
35
|
+
TraditionalEncryptionSpecs.password,
|
|
36
|
+
TraditionalEncryptionSpecs.mtime
|
|
37
|
+
) do |e|
|
|
38
|
+
lambda { e.rewind }.should raise_error(Errno::EINVAL)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
require 'archive/support/binary_stringio'
|
|
7
|
+
|
|
8
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Encrypt#seek" do
|
|
9
|
+
it "can seek to the beginning of the stream when the delegate responds to rewind" do
|
|
10
|
+
encrypted_data = BinaryStringIO.new
|
|
11
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
12
|
+
encrypted_data,
|
|
13
|
+
TraditionalEncryptionSpecs.password,
|
|
14
|
+
TraditionalEncryptionSpecs.mtime
|
|
15
|
+
) do |e|
|
|
16
|
+
e.write('test')
|
|
17
|
+
lambda { e.seek(0) }.should_not raise_error
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "raises Errno::EINVAL when attempting to seek to the beginning of the stream when the delegate does not respond to rewind" do
|
|
22
|
+
delegate = mock('delegate')
|
|
23
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
24
|
+
# of version 1.5.10.
|
|
25
|
+
#delegate.should_receive(:write).with(an_instance_of(String)).at_least(:once).and_return { |s| s.length }
|
|
26
|
+
# Use the following instead for now.
|
|
27
|
+
delegate.should_receive(:write).at_least(:once).and_return(1)
|
|
28
|
+
delegate.should_receive(:close).and_return(nil)
|
|
29
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
30
|
+
delegate,
|
|
31
|
+
TraditionalEncryptionSpecs.password,
|
|
32
|
+
TraditionalEncryptionSpecs.mtime
|
|
33
|
+
) do |e|
|
|
34
|
+
lambda { e.seek(0) }.should raise_error(Errno::EINVAL)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "raises Errno::EINVAL when seeking forward or backward from the current position of the stream" do
|
|
39
|
+
encrypted_data = BinaryStringIO.new
|
|
40
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
41
|
+
encrypted_data,
|
|
42
|
+
TraditionalEncryptionSpecs.password,
|
|
43
|
+
TraditionalEncryptionSpecs.mtime
|
|
44
|
+
) do |e|
|
|
45
|
+
e.write('test')
|
|
46
|
+
lambda { e.seek(1, IO::SEEK_CUR) }.should raise_error(Errno::EINVAL)
|
|
47
|
+
lambda { e.seek(-1, IO::SEEK_CUR) }.should raise_error(Errno::EINVAL)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "raises Errno::EINVAL when seeking a non-zero offset relative to the beginning of the stream" do
|
|
52
|
+
encrypted_data = BinaryStringIO.new
|
|
53
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
54
|
+
encrypted_data,
|
|
55
|
+
TraditionalEncryptionSpecs.password,
|
|
56
|
+
TraditionalEncryptionSpecs.mtime
|
|
57
|
+
) do |e|
|
|
58
|
+
lambda { e.seek(-1, IO::SEEK_SET) }.should raise_error(Errno::EINVAL)
|
|
59
|
+
lambda { e.seek(1, IO::SEEK_SET) }.should raise_error(Errno::EINVAL)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "raises Errno::EINVAL when seeking relative to the end of the stream" do
|
|
64
|
+
encrypted_data = BinaryStringIO.new
|
|
65
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
66
|
+
encrypted_data,
|
|
67
|
+
TraditionalEncryptionSpecs.password,
|
|
68
|
+
TraditionalEncryptionSpecs.mtime
|
|
69
|
+
) do |e|
|
|
70
|
+
lambda { e.seek(0, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
|
|
71
|
+
lambda { e.seek(-1, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
|
|
72
|
+
lambda { e.seek(1, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
require 'archive/support/binary_stringio'
|
|
7
|
+
|
|
8
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Encrypt#tell" do
|
|
9
|
+
it "returns the current position of the stream" do
|
|
10
|
+
encrypted_data = BinaryStringIO.new
|
|
11
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
12
|
+
encrypted_data,
|
|
13
|
+
TraditionalEncryptionSpecs.password,
|
|
14
|
+
TraditionalEncryptionSpecs.mtime
|
|
15
|
+
) do |e|
|
|
16
|
+
e.tell.should == 0
|
|
17
|
+
e.write('test1')
|
|
18
|
+
e.tell.should == 5
|
|
19
|
+
e.write('test2')
|
|
20
|
+
e.tell.should == 10
|
|
21
|
+
e.rewind
|
|
22
|
+
e.tell.should == 0
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "raises IOError on closed stream" do
|
|
27
|
+
delegate = mock('delegate')
|
|
28
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
29
|
+
# of version 1.5.10.
|
|
30
|
+
#delegate.should_receive(:write).with(an_instance_of(String)).at_least(:once).and_return { |s| s.length }
|
|
31
|
+
# Use the following instead for now.
|
|
32
|
+
delegate.should_receive(:write).at_least(:once).and_return(1)
|
|
33
|
+
delegate.should_receive(:close).once.and_return(nil)
|
|
34
|
+
lambda do
|
|
35
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
36
|
+
delegate,
|
|
37
|
+
TraditionalEncryptionSpecs.password,
|
|
38
|
+
TraditionalEncryptionSpecs.mtime
|
|
39
|
+
) { |e| e }.tell
|
|
40
|
+
end.should raise_error(IOError)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../../../../spec_helper'
|
|
4
|
+
require File.dirname(__FILE__) + '/../fixtures/classes'
|
|
5
|
+
require 'archive/zip/codec/traditional_encryption'
|
|
6
|
+
require 'archive/support/binary_stringio'
|
|
7
|
+
|
|
8
|
+
describe "Archive::Zip::Codec::TraditionalEncryption::Encrypt#write" do
|
|
9
|
+
it "calls the write method of the delegate" do
|
|
10
|
+
delegate = mock('delegate')
|
|
11
|
+
# RSpec's mocking facility supposedly supports this, but MSpec's does not as
|
|
12
|
+
# of version 1.5.10.
|
|
13
|
+
#delegate.should_receive(:write).with(an_instance_of(String)).at_least(:once).and_return { |s| s.length }
|
|
14
|
+
# Use the following instead for now.
|
|
15
|
+
delegate.should_receive(:write).at_least(:once).and_return(1)
|
|
16
|
+
delegate.should_receive(:close).once.and_return(nil)
|
|
17
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
18
|
+
delegate,
|
|
19
|
+
TraditionalEncryptionSpecs.password,
|
|
20
|
+
TraditionalEncryptionSpecs.mtime
|
|
21
|
+
) do |e|
|
|
22
|
+
e.write(TraditionalEncryptionSpecs.test_data)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "writes encrypted data to the delegate" do
|
|
27
|
+
# Ensure repeatable test data is used for encryption header.
|
|
28
|
+
srand(0)
|
|
29
|
+
encrypted_data = BinaryStringIO.new
|
|
30
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
31
|
+
encrypted_data,
|
|
32
|
+
TraditionalEncryptionSpecs.password,
|
|
33
|
+
TraditionalEncryptionSpecs.mtime
|
|
34
|
+
) do |e|
|
|
35
|
+
e.write(TraditionalEncryptionSpecs.test_data)
|
|
36
|
+
end
|
|
37
|
+
encrypted_data.string.should == TraditionalEncryptionSpecs.encrypted_data
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "writes encrypted data to a delegate that only performs partial writes" do
|
|
41
|
+
# Ensure repeatable test data is used for encryption header.
|
|
42
|
+
srand(0)
|
|
43
|
+
encrypted_data = BinaryStringIO.new
|
|
44
|
+
# Override encrypted_data.write to perform writes 1 byte at a time.
|
|
45
|
+
class << encrypted_data
|
|
46
|
+
alias :write_orig :write
|
|
47
|
+
def write(buffer)
|
|
48
|
+
write_orig(buffer.slice(0, 1))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
53
|
+
encrypted_data,
|
|
54
|
+
TraditionalEncryptionSpecs.password,
|
|
55
|
+
TraditionalEncryptionSpecs.mtime
|
|
56
|
+
) do |e|
|
|
57
|
+
e.write(TraditionalEncryptionSpecs.test_data)
|
|
58
|
+
end
|
|
59
|
+
encrypted_data.string.should == TraditionalEncryptionSpecs.encrypted_data
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "writes encrypted data to a delegate that raises Errno::EAGAIN" do
|
|
63
|
+
# Ensure repeatable test data is used for encryption header.
|
|
64
|
+
srand(0)
|
|
65
|
+
encrypted_data = BinaryStringIO.new
|
|
66
|
+
# Override encrypted_data.write to raise Errno::EAGAIN every other time it's
|
|
67
|
+
# called.
|
|
68
|
+
class << encrypted_data
|
|
69
|
+
alias :write_orig :write
|
|
70
|
+
def write(buffer)
|
|
71
|
+
if @error_raised then
|
|
72
|
+
@error_raised = false
|
|
73
|
+
write_orig(buffer)
|
|
74
|
+
else
|
|
75
|
+
@error_raised = true
|
|
76
|
+
raise Errno::EAGAIN
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
82
|
+
encrypted_data,
|
|
83
|
+
TraditionalEncryptionSpecs.password,
|
|
84
|
+
TraditionalEncryptionSpecs.mtime
|
|
85
|
+
) do |e|
|
|
86
|
+
begin
|
|
87
|
+
e.write(TraditionalEncryptionSpecs.test_data)
|
|
88
|
+
rescue Errno::EAGAIN
|
|
89
|
+
retry
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
encrypted_data.string.should == TraditionalEncryptionSpecs.encrypted_data
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "writes encrypted data to a delegate that raises Errno::EINTR" do
|
|
96
|
+
# Ensure repeatable test data is used for encryption header.
|
|
97
|
+
srand(0)
|
|
98
|
+
encrypted_data = BinaryStringIO.new
|
|
99
|
+
# Override encrypted_data.write to raise Errno::EINTR every other time it's
|
|
100
|
+
# called.
|
|
101
|
+
class << encrypted_data
|
|
102
|
+
alias :write_orig :write
|
|
103
|
+
def write(buffer)
|
|
104
|
+
if @error_raised then
|
|
105
|
+
@error_raised = false
|
|
106
|
+
write_orig(buffer)
|
|
107
|
+
else
|
|
108
|
+
@error_raised = true
|
|
109
|
+
raise Errno::EINTR
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
Archive::Zip::Codec::TraditionalEncryption::Encrypt.open(
|
|
115
|
+
encrypted_data,
|
|
116
|
+
TraditionalEncryptionSpecs.password,
|
|
117
|
+
TraditionalEncryptionSpecs.mtime
|
|
118
|
+
) do |e|
|
|
119
|
+
begin
|
|
120
|
+
e.write(TraditionalEncryptionSpecs.test_data)
|
|
121
|
+
rescue Errno::EINTR
|
|
122
|
+
retry
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
encrypted_data.string.should == TraditionalEncryptionSpecs.encrypted_data
|
|
126
|
+
end
|
|
127
|
+
end
|