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.
Files changed (132) hide show
  1. data/HACKING +25 -42
  2. data/NEWS +25 -0
  3. data/README +2 -2
  4. data/Rakefile +202 -0
  5. data/TODO +5 -0
  6. data/default.mspec +8 -0
  7. data/lib/archive/support/binary_stringio.rb +23 -0
  8. data/lib/archive/support/integer.rb +13 -0
  9. data/lib/archive/support/io-like.rb +3 -1
  10. data/lib/archive/support/ioextensions.rb +16 -0
  11. data/lib/archive/support/iowindow.rb +10 -18
  12. data/lib/archive/support/time.rb +2 -0
  13. data/lib/archive/support/zlib.rb +298 -71
  14. data/lib/archive/zip.rb +161 -139
  15. data/lib/archive/zip/codec.rb +2 -0
  16. data/lib/archive/zip/codec/deflate.rb +59 -11
  17. data/lib/archive/zip/codec/null_encryption.rb +75 -14
  18. data/lib/archive/zip/codec/store.rb +75 -26
  19. data/lib/archive/zip/codec/traditional_encryption.rb +146 -35
  20. data/lib/archive/zip/data_descriptor.rb +6 -4
  21. data/lib/archive/zip/entry.rb +184 -132
  22. data/lib/archive/zip/error.rb +2 -0
  23. data/lib/archive/zip/extra_field.rb +20 -6
  24. data/lib/archive/zip/extra_field/extended_timestamp.rb +141 -60
  25. data/lib/archive/zip/extra_field/raw.rb +70 -12
  26. data/lib/archive/zip/extra_field/unix.rb +58 -16
  27. data/lib/archive/zip/version.rb +6 -0
  28. data/spec/archive/zip/codec/deflate/compress/checksum_spec.rb +42 -0
  29. data/spec/archive/zip/codec/deflate/compress/close_spec.rb +44 -0
  30. data/spec/archive/zip/codec/deflate/compress/crc32_spec.rb +21 -0
  31. data/spec/archive/zip/codec/deflate/compress/data_descriptor_spec.rb +67 -0
  32. data/spec/archive/zip/codec/deflate/compress/new_spec.rb +37 -0
  33. data/spec/archive/zip/codec/deflate/compress/open_spec.rb +46 -0
  34. data/spec/archive/zip/codec/deflate/compress/write_spec.rb +109 -0
  35. data/spec/archive/zip/codec/deflate/decompress/checksum_spec.rb +18 -0
  36. data/spec/archive/zip/codec/deflate/decompress/close_spec.rb +33 -0
  37. data/spec/archive/zip/codec/deflate/decompress/crc32_spec.rb +18 -0
  38. data/spec/archive/zip/codec/deflate/decompress/data_descriptor_spec.rb +67 -0
  39. data/spec/archive/zip/codec/deflate/decompress/new_spec.rb +14 -0
  40. data/spec/archive/zip/codec/deflate/decompress/open_spec.rb +27 -0
  41. data/spec/archive/zip/codec/deflate/fixtures/classes.rb +25 -0
  42. data/spec/archive/zip/codec/deflate/fixtures/compressed_file.bin +1 -0
  43. data/spec/archive/zip/codec/deflate/fixtures/compressed_file_nocomp.bin +0 -0
  44. data/spec/archive/zip/codec/deflate/fixtures/raw_file.txt +10 -0
  45. data/spec/archive/zip/codec/null_encryption/decrypt/close_spec.rb +33 -0
  46. data/spec/archive/zip/codec/null_encryption/decrypt/new_spec.rb +14 -0
  47. data/spec/archive/zip/codec/null_encryption/decrypt/open_spec.rb +27 -0
  48. data/spec/archive/zip/codec/null_encryption/decrypt/read_spec.rb +24 -0
  49. data/spec/archive/zip/codec/null_encryption/decrypt/rewind_spec.rb +25 -0
  50. data/spec/archive/zip/codec/null_encryption/decrypt/seek_spec.rb +57 -0
  51. data/spec/archive/zip/codec/null_encryption/decrypt/tell_spec.rb +21 -0
  52. data/spec/archive/zip/codec/null_encryption/encrypt/close_spec.rb +33 -0
  53. data/spec/archive/zip/codec/null_encryption/encrypt/new_spec.rb +14 -0
  54. data/spec/archive/zip/codec/null_encryption/encrypt/open_spec.rb +27 -0
  55. data/spec/archive/zip/codec/null_encryption/encrypt/rewind_spec.rb +26 -0
  56. data/spec/archive/zip/codec/null_encryption/encrypt/seek_spec.rb +50 -0
  57. data/spec/archive/zip/codec/null_encryption/encrypt/tell_spec.rb +29 -0
  58. data/spec/archive/zip/codec/null_encryption/encrypt/write_spec.rb +29 -0
  59. data/spec/archive/zip/codec/null_encryption/fixtures/classes.rb +12 -0
  60. data/spec/archive/zip/codec/null_encryption/fixtures/raw_file.txt +10 -0
  61. data/spec/archive/zip/codec/store/compress/close_spec.rb +33 -0
  62. data/spec/archive/zip/codec/store/compress/data_descriptor_spec.rb +68 -0
  63. data/spec/archive/zip/codec/store/compress/new_spec.rb +14 -0
  64. data/spec/archive/zip/codec/store/compress/open_spec.rb +27 -0
  65. data/spec/archive/zip/codec/store/compress/rewind_spec.rb +26 -0
  66. data/spec/archive/zip/codec/store/compress/seek_spec.rb +50 -0
  67. data/spec/archive/zip/codec/store/compress/tell_spec.rb +29 -0
  68. data/spec/archive/zip/codec/store/compress/write_spec.rb +29 -0
  69. data/spec/archive/zip/codec/store/decompress/close_spec.rb +33 -0
  70. data/spec/archive/zip/codec/store/decompress/data_descriptor_spec.rb +68 -0
  71. data/spec/archive/zip/codec/store/decompress/new_spec.rb +14 -0
  72. data/spec/archive/zip/codec/store/decompress/open_spec.rb +27 -0
  73. data/spec/archive/zip/codec/store/decompress/read_spec.rb +24 -0
  74. data/spec/archive/zip/codec/store/decompress/rewind_spec.rb +25 -0
  75. data/spec/archive/zip/codec/store/decompress/seek_spec.rb +57 -0
  76. data/spec/archive/zip/codec/store/decompress/tell_spec.rb +21 -0
  77. data/spec/archive/zip/codec/store/fixtures/classes.rb +12 -0
  78. data/spec/archive/zip/codec/store/fixtures/raw_file.txt +10 -0
  79. data/spec/archive/zip/codec/traditional_encryption/decrypt/close_spec.rb +64 -0
  80. data/spec/archive/zip/codec/traditional_encryption/decrypt/new_spec.rb +18 -0
  81. data/spec/archive/zip/codec/traditional_encryption/decrypt/open_spec.rb +39 -0
  82. data/spec/archive/zip/codec/traditional_encryption/decrypt/read_spec.rb +126 -0
  83. data/spec/archive/zip/codec/traditional_encryption/decrypt/rewind_spec.rb +38 -0
  84. data/spec/archive/zip/codec/traditional_encryption/decrypt/seek_spec.rb +82 -0
  85. data/spec/archive/zip/codec/traditional_encryption/decrypt/tell_spec.rb +25 -0
  86. data/spec/archive/zip/codec/traditional_encryption/encrypt/close_spec.rb +64 -0
  87. data/spec/archive/zip/codec/traditional_encryption/encrypt/new_spec.rb +18 -0
  88. data/spec/archive/zip/codec/traditional_encryption/encrypt/open_spec.rb +39 -0
  89. data/spec/archive/zip/codec/traditional_encryption/encrypt/rewind_spec.rb +41 -0
  90. data/spec/archive/zip/codec/traditional_encryption/encrypt/seek_spec.rb +75 -0
  91. data/spec/archive/zip/codec/traditional_encryption/encrypt/tell_spec.rb +42 -0
  92. data/spec/archive/zip/codec/traditional_encryption/encrypt/write_spec.rb +127 -0
  93. data/spec/archive/zip/codec/traditional_encryption/fixtures/classes.rb +27 -0
  94. data/spec/archive/zip/codec/traditional_encryption/fixtures/encrypted_file.bin +0 -0
  95. data/spec/archive/zip/codec/traditional_encryption/fixtures/raw_file.txt +10 -0
  96. data/spec/binary_stringio/new_spec.rb +34 -0
  97. data/spec/binary_stringio/set_encoding_spec.rb +14 -0
  98. data/spec/ioextensions/read_exactly_spec.rb +50 -0
  99. data/spec/zlib/fixtures/classes.rb +65 -0
  100. data/spec/zlib/fixtures/compressed_file.bin +1 -0
  101. data/spec/zlib/fixtures/compressed_file_gzip.bin +0 -0
  102. data/spec/zlib/fixtures/compressed_file_huffman.bin +2 -0
  103. data/spec/zlib/fixtures/compressed_file_minmem.bin +0 -0
  104. data/spec/zlib/fixtures/compressed_file_minwin.bin +1 -0
  105. data/spec/zlib/fixtures/compressed_file_nocomp.bin +0 -0
  106. data/spec/zlib/fixtures/compressed_file_raw.bin +1 -0
  107. data/spec/zlib/fixtures/raw_file.txt +10 -0
  108. data/spec/zlib/zreader/checksum_spec.rb +40 -0
  109. data/spec/zlib/zreader/close_spec.rb +14 -0
  110. data/spec/zlib/zreader/compressed_size_spec.rb +18 -0
  111. data/spec/zlib/zreader/new_spec.rb +41 -0
  112. data/spec/zlib/zreader/open_spec.rb +49 -0
  113. data/spec/zlib/zreader/read_spec.rb +47 -0
  114. data/spec/zlib/zreader/rewind_spec.rb +23 -0
  115. data/spec/zlib/zreader/seek_spec.rb +55 -0
  116. data/spec/zlib/zreader/tell_spec.rb +21 -0
  117. data/spec/zlib/zreader/uncompressed_size_spec.rb +18 -0
  118. data/spec/zlib/zwriter/checksum_spec.rb +41 -0
  119. data/spec/zlib/zwriter/close_spec.rb +14 -0
  120. data/spec/zlib/zwriter/compressed_size_spec.rb +19 -0
  121. data/spec/zlib/zwriter/new_spec.rb +64 -0
  122. data/spec/zlib/zwriter/open_spec.rb +68 -0
  123. data/spec/zlib/zwriter/rewind_spec.rb +26 -0
  124. data/spec/zlib/zwriter/seek_spec.rb +54 -0
  125. data/spec/zlib/zwriter/tell_spec.rb +29 -0
  126. data/spec/zlib/zwriter/uncompressed_size_spec.rb +19 -0
  127. data/spec/zlib/zwriter/write_spec.rb +28 -0
  128. data/spec_helper.rb +49 -0
  129. metadata +296 -74
  130. data/MANIFEST +0 -27
  131. data/lib/archive/support/io.rb +0 -14
  132. data/lib/archive/support/stringio.rb +0 -22
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.dirname(__FILE__) + '/../../../../../../spec_helper'
4
+ require File.dirname(__FILE__) + '/../fixtures/classes'
5
+ require 'archive/zip/codec/store'
6
+ require 'archive/support/binary_stringio'
7
+
8
+ describe "Archive::Zip::Codec::Store::Decompress#close" do
9
+ it "closes the stream" do
10
+ c = Archive::Zip::Codec::Store::Decompress.new(BinaryStringIO.new)
11
+ c.close
12
+ c.closed?.should be_true
13
+ end
14
+
15
+ it "closes the delegate stream by default" do
16
+ delegate = mock('delegate')
17
+ delegate.should_receive(:close).and_return(nil)
18
+ c = Archive::Zip::Codec::Store::Decompress.new(delegate)
19
+ c.close
20
+ end
21
+
22
+ it "optionally leaves the delegate stream open" do
23
+ delegate = mock('delegate')
24
+ delegate.should_receive(:close).and_return(nil)
25
+ c = Archive::Zip::Codec::Store::Decompress.new(delegate)
26
+ c.close(true)
27
+
28
+ delegate = mock('delegate')
29
+ delegate.should_not_receive(:close)
30
+ c = Archive::Zip::Codec::Store::Decompress.new(delegate)
31
+ c.close(false)
32
+ end
33
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.dirname(__FILE__) + '/../../../../../../spec_helper'
4
+ require File.dirname(__FILE__) + '/../fixtures/classes'
5
+ require 'archive/support/zlib'
6
+ require 'archive/zip/codec/store'
7
+
8
+ describe "Archive::Zip::Codec::Store::Decompress#data_descriptor" do
9
+ it "is an instance of Archive::Zip::DataDescriptor" do
10
+ StoreSpecs.compressed_data do |cd|
11
+ closed_decompressor = Archive::Zip::Codec::Store::Decompress.open(
12
+ cd
13
+ ) do |decompressor|
14
+ decompressor.read
15
+ decompressor.data_descriptor.class.should ==
16
+ Archive::Zip::DataDescriptor
17
+ decompressor
18
+ end
19
+ closed_decompressor.data_descriptor.class.should ==
20
+ Archive::Zip::DataDescriptor
21
+ end
22
+ end
23
+
24
+ it "has a crc32 attribute containing the CRC32 checksum" do
25
+ crc32 = Zlib.crc32(StoreSpecs.test_data)
26
+ StoreSpecs.compressed_data do |cd|
27
+ closed_decompressor = Archive::Zip::Codec::Store::Decompress.open(
28
+ cd
29
+ ) do |decompressor|
30
+ decompressor.read
31
+ decompressor.data_descriptor.crc32.should == crc32
32
+ decompressor
33
+ end
34
+ closed_decompressor.data_descriptor.crc32.should == crc32
35
+ end
36
+ end
37
+
38
+ it "has a compressed_size attribute containing the size of the compressed data" do
39
+ compressed_size = StoreSpecs.compressed_data.size
40
+ StoreSpecs.compressed_data do |cd|
41
+ closed_decompressor = Archive::Zip::Codec::Store::Decompress.open(
42
+ cd
43
+ ) do |decompressor|
44
+ decompressor.read
45
+ decompressor.data_descriptor.compressed_size.should == compressed_size
46
+ decompressor
47
+ end
48
+ closed_decompressor.data_descriptor.compressed_size.should ==
49
+ compressed_size
50
+ end
51
+ end
52
+
53
+ it "has an uncompressed_size attribute containing the size of the input data" do
54
+ uncompressed_size = StoreSpecs.test_data.size
55
+ StoreSpecs.compressed_data do |cd|
56
+ closed_decompressor = Archive::Zip::Codec::Store::Decompress.open(
57
+ cd
58
+ ) do |decompressor|
59
+ decompressor.read
60
+ decompressor.data_descriptor.uncompressed_size.should ==
61
+ uncompressed_size
62
+ decompressor
63
+ end
64
+ closed_decompressor.data_descriptor.uncompressed_size.should ==
65
+ uncompressed_size
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.dirname(__FILE__) + '/../../../../../../spec_helper'
4
+ require File.dirname(__FILE__) + '/../fixtures/classes'
5
+ require 'archive/zip/codec/store'
6
+ require 'archive/support/binary_stringio'
7
+
8
+ describe "Archive::Zip::Codec::Store::Decompress.new" do
9
+ it "returns a new instance" do
10
+ d = Archive::Zip::Codec::Store::Decompress.new(BinaryStringIO.new)
11
+ d.class.should == Archive::Zip::Codec::Store::Decompress
12
+ d.close
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.dirname(__FILE__) + '/../../../../../../spec_helper'
4
+ require File.dirname(__FILE__) + '/../fixtures/classes'
5
+ require 'archive/zip/codec/store'
6
+ require 'archive/support/binary_stringio'
7
+
8
+ describe "Archive::Zip::Codec::Store::Decompress.open" do
9
+ it "returns a new instance when run without a block" do
10
+ d = Archive::Zip::Codec::Store::Decompress.open(BinaryStringIO.new)
11
+ d.class.should == Archive::Zip::Codec::Store::Decompress
12
+ d.close
13
+ end
14
+
15
+ it "executes a block with a new instance as an argument" do
16
+ Archive::Zip::Codec::Store::Decompress.open(BinaryStringIO.new) do |decompressor|
17
+ decompressor.class.should == Archive::Zip::Codec::Store::Decompress
18
+ end
19
+ end
20
+
21
+ it "closes the object after executing a block" do
22
+ d = Archive::Zip::Codec::Store::Decompress.open(BinaryStringIO.new) do |decompressor|
23
+ decompressor
24
+ end
25
+ d.closed?.should.be_true
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.dirname(__FILE__) + '/../../../../../../spec_helper'
4
+ require File.dirname(__FILE__) + '/../fixtures/classes'
5
+ require 'archive/zip/codec/store'
6
+
7
+ describe "Archive::Zip::Codec::Store::Decompress#read" do
8
+ it "calls the read method of the delegate" do
9
+ delegate = mock('delegate')
10
+ delegate.should_receive(:read).and_return(nil)
11
+ delegate.should_receive(:close).and_return(nil)
12
+ Archive::Zip::Codec::Store::Decompress.open(delegate) do |d|
13
+ d.read
14
+ end
15
+ end
16
+
17
+ it "passes data through unmodified" do
18
+ StoreSpecs.compressed_data do |cd|
19
+ Archive::Zip::Codec::Store::Decompress.open(cd) do |d|
20
+ d.read.should == StoreSpecs.test_data
21
+ end
22
+ end
23
+ end
24
+ 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/store'
6
+
7
+ describe "Archive::Zip::Codec::Store::Decompress#rewind" do
8
+ it "can rewind the stream when the delegate responds to rewind" do
9
+ StoreSpecs.compressed_data do |cd|
10
+ Archive::Zip::Codec::Store::Decompress.open(cd) do |d|
11
+ d.read(4)
12
+ lambda { d.rewind }.should_not raise_error
13
+ d.read.should == StoreSpecs.test_data
14
+ end
15
+ end
16
+ end
17
+
18
+ it "raises Errno::EINVAL when attempting to rewind the stream when the delegate does not respond to rewind" do
19
+ delegate = mock('delegate')
20
+ delegate.should_receive(:close).and_return(nil)
21
+ Archive::Zip::Codec::Store::Decompress.open(delegate) do |d|
22
+ lambda { d.rewind }.should raise_error(Errno::EINVAL)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.dirname(__FILE__) + '/../../../../../../spec_helper'
4
+ require File.dirname(__FILE__) + '/../fixtures/classes'
5
+ require 'archive/zip/codec/store'
6
+
7
+ describe "Archive::Zip::Codec::Store::Decompress#seek" do
8
+ it "can seek to the beginning of the stream when the delegate responds to rewind" do
9
+ StoreSpecs.compressed_data do |cd|
10
+ Archive::Zip::Codec::Store::Decompress.open(cd) do |d|
11
+ d.read(4)
12
+ lambda { d.seek(0) }.should_not raise_error
13
+ end
14
+ end
15
+ end
16
+
17
+ it "raises Errno::EINVAL when attempting to seek to the beginning of the stream when the delegate does not respond to rewind" do
18
+ delegate = mock('delegate')
19
+ delegate.should_receive(:close).and_return(nil)
20
+ Archive::Zip::Codec::Store::Decompress.open(delegate) do |d|
21
+ lambda { d.seek(0) }.should raise_error(Errno::EINVAL)
22
+ end
23
+ end
24
+
25
+ it "raises Errno::EINVAL when seeking forward or backward from the current position of the stream" do
26
+ StoreSpecs.compressed_data do |cd|
27
+ Archive::Zip::Codec::Store::Decompress.open(cd) do |d|
28
+ # Disable read buffering to avoid some seeking optimizations implemented
29
+ # by IO::Like which allow seeking forward within the buffer.
30
+ d.fill_size = 0
31
+
32
+ d.read(4)
33
+ lambda { d.seek(1, IO::SEEK_CUR) }.should raise_error(Errno::EINVAL)
34
+ lambda { d.seek(-1, IO::SEEK_CUR) }.should raise_error(Errno::EINVAL)
35
+ end
36
+ end
37
+ end
38
+
39
+ it "raises Errno::EINVAL when seeking a non-zero offset relative to the beginning of the stream" do
40
+ StoreSpecs.compressed_data do |cd|
41
+ Archive::Zip::Codec::Store::Decompress.open(cd) do |d|
42
+ lambda { d.seek(-1, IO::SEEK_SET) }.should raise_error(Errno::EINVAL)
43
+ lambda { d.seek(1, IO::SEEK_SET) }.should raise_error(Errno::EINVAL)
44
+ end
45
+ end
46
+ end
47
+
48
+ it "raises Errno::EINVAL when seeking relative to the end of the stream" do
49
+ StoreSpecs.compressed_data do |cd|
50
+ Archive::Zip::Codec::Store::Decompress.open(cd) do |d|
51
+ lambda { d.seek(0, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
52
+ lambda { d.seek(-1, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
53
+ lambda { d.seek(1, IO::SEEK_END) }.should raise_error(Errno::EINVAL)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.dirname(__FILE__) + '/../../../../../../spec_helper'
4
+ require File.dirname(__FILE__) + '/../fixtures/classes'
5
+ require 'archive/zip/codec/store'
6
+
7
+ describe "Archive::Zip::Codec::Store::Decompress#tell" do
8
+ it "returns the current position of the stream" do
9
+ StoreSpecs.compressed_data do |cd|
10
+ Archive::Zip::Codec::Store::Decompress.open(cd) do |d|
11
+ d.tell.should == 0
12
+ d.read(4)
13
+ d.tell.should == 4
14
+ d.read
15
+ d.tell.should == 235
16
+ d.rewind
17
+ d.tell.should == 0
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: UTF-8
2
+
3
+ class StoreSpecs
4
+ class << self
5
+ def test_data
6
+ File.open(File.join(File.dirname(__FILE__), 'raw_file.txt'), 'rb') do |f|
7
+ block_given? ? yield(f) : f.read
8
+ end
9
+ end
10
+ alias :compressed_data :test_data
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ test
2
+ This is a file with test data.
3
+ The quick brown fox jumps over the lazy dog.
4
+
5
+ Mary had a little lamb
6
+ Whose fleece was white as snow
7
+ And everywhere that Mary went
8
+ The lamb was sure to go
9
+
10
+ She sells sea shells down by the sea shore.
@@ -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::Decrypt#close" do
9
+ it "closes the stream" do
10
+ d = Archive::Zip::Codec::TraditionalEncryption::Decrypt.new(
11
+ BinaryStringIO.new("\000" * 12),
12
+ TraditionalEncryptionSpecs.password,
13
+ TraditionalEncryptionSpecs.mtime
14
+ )
15
+ d.close
16
+ d.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(:read).with(an_instance_of(Fixnum)).at_least(:once).and_return { |n| "\000" * n }
24
+ # Use the following instead for now.
25
+ delegate.should_receive(:read).once.and_return("\000" * 12)
26
+ delegate.should_receive(:close).and_return(nil)
27
+ d = Archive::Zip::Codec::TraditionalEncryption::Decrypt.new(
28
+ delegate,
29
+ TraditionalEncryptionSpecs.password,
30
+ TraditionalEncryptionSpecs.mtime
31
+ )
32
+ d.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(:read).with(an_instance_of(Fixnum)).at_least(:once).and_return { |n| "\000" * n }
40
+ # Use the following instead for now.
41
+ delegate.should_receive(:read).once.and_return("\000" * 12)
42
+ delegate.should_receive(:close).and_return(nil)
43
+ d = Archive::Zip::Codec::TraditionalEncryption::Decrypt.new(
44
+ delegate,
45
+ TraditionalEncryptionSpecs.password,
46
+ TraditionalEncryptionSpecs.mtime
47
+ )
48
+ d.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(:read).with(an_instance_of(Fixnum)).at_least(:once).and_return { |n| "\000" * n }
54
+ # Use the following instead for now.
55
+ delegate.should_receive(:read).once.and_return("\000" * 12)
56
+ delegate.should_not_receive(:close)
57
+ d = Archive::Zip::Codec::TraditionalEncryption::Decrypt.new(
58
+ delegate,
59
+ TraditionalEncryptionSpecs.password,
60
+ TraditionalEncryptionSpecs.mtime
61
+ )
62
+ d.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/store'
6
+ require 'archive/support/binary_stringio'
7
+
8
+ describe "Archive::Zip::Codec::TraditionalEncryption::Decrypt.new" do
9
+ it "returns a new instance" do
10
+ d = Archive::Zip::Codec::TraditionalEncryption::Decrypt.new(
11
+ BinaryStringIO.new("\000" * 12),
12
+ TraditionalEncryptionSpecs.password,
13
+ TraditionalEncryptionSpecs.mtime
14
+ )
15
+ d.class.should == Archive::Zip::Codec::TraditionalEncryption::Decrypt
16
+ d.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/store'
6
+ require 'archive/support/binary_stringio'
7
+
8
+ describe "Archive::Zip::Codec::TraditionalEncryption::Decrypt.open" do
9
+ it "returns a new instance when run without a block" do
10
+ d = Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
11
+ BinaryStringIO.new("\000" * 12),
12
+ TraditionalEncryptionSpecs.password,
13
+ TraditionalEncryptionSpecs.mtime
14
+ )
15
+ d.class.should == Archive::Zip::Codec::TraditionalEncryption::Decrypt
16
+ d.close
17
+ end
18
+
19
+ it "executes a block with a new instance as an argument" do
20
+ Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
21
+ BinaryStringIO.new("\000" * 12),
22
+ TraditionalEncryptionSpecs.password,
23
+ TraditionalEncryptionSpecs.mtime
24
+ ) do |decryptor|
25
+ decryptor.class.should == Archive::Zip::Codec::TraditionalEncryption::Decrypt
26
+ end
27
+ end
28
+
29
+ it "closes the object after executing a block" do
30
+ d = Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
31
+ BinaryStringIO.new("\000" * 12),
32
+ TraditionalEncryptionSpecs.password,
33
+ TraditionalEncryptionSpecs.mtime
34
+ ) do |decryptor|
35
+ decryptor
36
+ end
37
+ d.closed?.should.be_true
38
+ end
39
+ end
@@ -0,0 +1,126 @@
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#read" do
8
+ it "calls the read method of the delegate" do
9
+ delegate = mock('delegate')
10
+ # RSpec's mocking facility supposedly supports this, but MSpec's does not as
11
+ # of version 1.5.10.
12
+ #delegate.should_receive(:read).with(an_instance_of(Fixnum)).at_least(:once).and_return { |n| "\000" * n }
13
+ # Use the following instead for now.
14
+ delegate.should_receive(:read).twice.and_return("\000" * 12, nil)
15
+ delegate.should_receive(:close).and_return(nil)
16
+ Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
17
+ delegate,
18
+ TraditionalEncryptionSpecs.password,
19
+ TraditionalEncryptionSpecs.mtime
20
+ ) do |d|
21
+ d.read
22
+ end
23
+ end
24
+
25
+ it "decrypts data read from the delegate" do
26
+ TraditionalEncryptionSpecs.encrypted_data do |ed|
27
+ Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
28
+ ed,
29
+ TraditionalEncryptionSpecs.password,
30
+ TraditionalEncryptionSpecs.mtime
31
+ ) do |d|
32
+ d.read.should == TraditionalEncryptionSpecs.test_data
33
+ end
34
+ end
35
+ end
36
+
37
+ it "decrypts data read from a delegate that only returns 1 byte at a time" do
38
+ TraditionalEncryptionSpecs.encrypted_data do |ed|
39
+ # Override ed.read to raise Errno::EAGAIN every other time it's called.
40
+ class << ed
41
+ alias :read_orig :read
42
+ def read(length = nil, buffer = nil)
43
+ read_orig(1, buffer)
44
+ end
45
+ end
46
+
47
+ Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
48
+ ed,
49
+ TraditionalEncryptionSpecs.password,
50
+ TraditionalEncryptionSpecs.mtime
51
+ ) do |d|
52
+ buffer = ''
53
+ begin
54
+ buffer << d.read
55
+ rescue Errno::EAGAIN
56
+ retry
57
+ end
58
+ buffer.should == TraditionalEncryptionSpecs.test_data
59
+ end
60
+ end
61
+ end
62
+
63
+ it "decrypts data read from a delegate that raises Errno::EAGAIN" do
64
+ TraditionalEncryptionSpecs.encrypted_data do |ed|
65
+ # Override ed.read to raise Errno::EAGAIN every other time it's called.
66
+ class << ed
67
+ alias :read_orig :read
68
+ def read(length = nil, buffer = nil)
69
+ if @error_raised then
70
+ @error_raised = false
71
+ read_orig(length, buffer)
72
+ else
73
+ @error_raised = true
74
+ raise Errno::EAGAIN
75
+ end
76
+ end
77
+ end
78
+
79
+ Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
80
+ ed,
81
+ TraditionalEncryptionSpecs.password,
82
+ TraditionalEncryptionSpecs.mtime
83
+ ) do |d|
84
+ buffer = ''
85
+ begin
86
+ buffer << d.read
87
+ rescue Errno::EAGAIN
88
+ retry
89
+ end
90
+ buffer.should == TraditionalEncryptionSpecs.test_data
91
+ end
92
+ end
93
+ end
94
+
95
+ it "decrypts data read from a delegate that raises Errno::EINTR" do
96
+ TraditionalEncryptionSpecs.encrypted_data do |ed|
97
+ # Override ed.read to raise Errno::EINTR every other time it's called.
98
+ class << ed
99
+ alias :read_orig :read
100
+ def read(length = nil, buffer = nil)
101
+ if @error_raised then
102
+ @error_raised = false
103
+ read_orig(length, buffer)
104
+ else
105
+ @error_raised = true
106
+ raise Errno::EINTR
107
+ end
108
+ end
109
+ end
110
+
111
+ Archive::Zip::Codec::TraditionalEncryption::Decrypt.open(
112
+ ed,
113
+ TraditionalEncryptionSpecs.password,
114
+ TraditionalEncryptionSpecs.mtime
115
+ ) do |d|
116
+ buffer = ''
117
+ begin
118
+ buffer << d.read
119
+ rescue Errno::EINTR
120
+ retry
121
+ end
122
+ buffer.should == TraditionalEncryptionSpecs.test_data
123
+ end
124
+ end
125
+ end
126
+ end