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,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