zip_tricks 4.2.3 → 4.2.4
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.
- checksums.yaml +4 -4
- data/.gitignore +53 -0
- data/Gemfile +3 -13
- data/README.md +36 -0
- data/Rakefile +3 -48
- data/lib/zip_tricks.rb +0 -2
- data/lib/zip_tricks/block_deflate.rb +2 -0
- data/lib/zip_tricks/version.rb +3 -0
- data/lib/zip_tricks/zip_writer.rb +59 -13
- data/testing/README_TESTING.md +12 -0
- data/testing/generate_test_files.rb +86 -0
- data/testing/in/VTYL8830.jpg +0 -0
- data/{spec/zip_tricks → testing/in}/war-and-peace.txt +0 -0
- data/testing/support.rb +83 -0
- data/testing/test-report-2016-07-28.txt +156 -0
- data/testing/test-report-2016-12-12.txt +156 -0
- data/testing/test-report.txt +28 -0
- data/zip_tricks.gemspec +36 -109
- metadata +40 -65
- data/spec/spec_helper.rb +0 -91
- data/spec/zip_tricks/block_deflate_spec.rb +0 -111
- data/spec/zip_tricks/block_write_spec.rb +0 -95
- data/spec/zip_tricks/cdir_entry_with_partial_use_of_zip64_extra_fields.bin +0 -0
- data/spec/zip_tricks/file_reader_spec.rb +0 -287
- data/spec/zip_tricks/rack_body_spec.rb +0 -34
- data/spec/zip_tricks/remote_io_spec.rb +0 -125
- data/spec/zip_tricks/remote_uncap_spec.rb +0 -100
- data/spec/zip_tricks/size_estimator_spec.rb +0 -31
- data/spec/zip_tricks/stream_crc32_spec.rb +0 -38
- data/spec/zip_tricks/streamer/writable_spec.rb +0 -27
- data/spec/zip_tricks/streamer_spec.rb +0 -296
- data/spec/zip_tricks/write_and_tell_spec.rb +0 -43
- data/spec/zip_tricks/zip_writer_spec.rb +0 -419
@@ -1,43 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
|
3
|
-
describe ZipTricks::WriteAndTell do
|
4
|
-
it 'maintains the count of bytes written' do
|
5
|
-
adapter = described_class.new('')
|
6
|
-
expect(adapter.tell).to be_zero
|
7
|
-
|
8
|
-
adapter << 'hello'
|
9
|
-
adapter << ''
|
10
|
-
adapter << '!'
|
11
|
-
expect(adapter.tell).to eq(6)
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'is able to write frozen String objects in different encodings, converting them to binary' do
|
15
|
-
strs = [
|
16
|
-
[12, 123, 0, 3].pack("C*"),
|
17
|
-
"текста кусок",
|
18
|
-
"текста замороженный кусок".freeze,
|
19
|
-
[12, 123, 0, 3].pack("C*"),
|
20
|
-
]
|
21
|
-
|
22
|
-
buf = 'превед'.force_encoding(Encoding::BINARY)
|
23
|
-
writer = described_class.new(buf)
|
24
|
-
strs.each {|s| writer << s }
|
25
|
-
expect(writer.tell).to eq(79)
|
26
|
-
expect(buf.bytesize).to eq(91) # It already contained some bytes
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'advances the internal pointer using advance_position_by' do
|
30
|
-
str = ''
|
31
|
-
|
32
|
-
adapter = described_class.new(str)
|
33
|
-
expect(adapter.tell).to be_zero
|
34
|
-
|
35
|
-
adapter << 'hello'
|
36
|
-
adapter << ''
|
37
|
-
adapter << '!'
|
38
|
-
expect(adapter.tell).to eq(6)
|
39
|
-
adapter.advance_position_by(128981)
|
40
|
-
expect(adapter.tell).to eq(6 + 128981)
|
41
|
-
expect(str).to eq('hello!')
|
42
|
-
end
|
43
|
-
end
|
@@ -1,419 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
require_relative '../../testing/support'
|
3
|
-
|
4
|
-
describe ZipTricks::ZipWriter do
|
5
|
-
class ByteReader < Struct.new(:io)
|
6
|
-
def initialize(io)
|
7
|
-
super(io).tap { io.rewind }
|
8
|
-
end
|
9
|
-
|
10
|
-
def read_2b
|
11
|
-
read_n(2).unpack('v').first
|
12
|
-
end
|
13
|
-
|
14
|
-
def read_2c
|
15
|
-
read_n(2).unpack('CC').first
|
16
|
-
end
|
17
|
-
|
18
|
-
def read_4b
|
19
|
-
read_n(4).unpack('V').first
|
20
|
-
end
|
21
|
-
|
22
|
-
def read_8b
|
23
|
-
read_n(8).unpack('Q<').first
|
24
|
-
end
|
25
|
-
|
26
|
-
def read_n(n)
|
27
|
-
io.read(n).tap {|r|
|
28
|
-
raise "Expected to read #{n} bytes, but read() returned nil" if r.nil?
|
29
|
-
raise "Expected to read #{n} bytes, but read #{r.bytesize} instead" if r.bytesize != n
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
|
-
# For conveniently going to a specific signature
|
34
|
-
def seek_to_start_of_signature(signature)
|
35
|
-
io.rewind
|
36
|
-
signature_encoded = [signature].pack('V')
|
37
|
-
idx = io.read.index(signature_encoded)
|
38
|
-
raise "Could not find the signature #{signature} in the buffer" unless idx
|
39
|
-
io.seek(idx, IO::SEEK_SET)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe '#write_local_file_header' do
|
44
|
-
it 'writes the local file header for an entry that does not require Zip64' do
|
45
|
-
buf = StringIO.new
|
46
|
-
mtime = Time.utc(2016, 7, 17, 13, 48)
|
47
|
-
|
48
|
-
subject = ZipTricks::ZipWriter.new
|
49
|
-
subject.write_local_file_header(io: buf, gp_flags: 12, crc32: 456, compressed_size: 768, uncompressed_size: 901, mtime: mtime, filename: 'foo.bin', storage_mode: 8)
|
50
|
-
|
51
|
-
br = ByteReader.new(buf)
|
52
|
-
expect(br.read_4b).to eq(0x04034b50) # Signature
|
53
|
-
expect(br.read_2b).to eq(20) # Version needed to extract
|
54
|
-
expect(br.read_2b).to eq(12) # gp flags
|
55
|
-
expect(br.read_2b).to eq(8) # storage mode
|
56
|
-
expect(br.read_2b).to eq(28160) # DOS time
|
57
|
-
expect(br.read_2b).to eq(18673) # DOS date
|
58
|
-
expect(br.read_4b).to eq(456) # CRC32
|
59
|
-
expect(br.read_4b).to eq(768) # compressed size
|
60
|
-
expect(br.read_4b).to eq(901) # uncompressed size
|
61
|
-
expect(br.read_2b).to eq(7) # filename size
|
62
|
-
expect(br.read_2b).to eq(0) # extra fields size
|
63
|
-
expect(br.read_n(7)).to eq('foo.bin') # extra fields size
|
64
|
-
expect(buf).to be_eof
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'writes the local file header for an entry that does require Zip64 based on uncompressed size (with the Zip64 extra)' do
|
68
|
-
buf = StringIO.new
|
69
|
-
mtime = Time.utc(2016, 7, 17, 13, 48)
|
70
|
-
|
71
|
-
subject = ZipTricks::ZipWriter.new
|
72
|
-
subject.write_local_file_header(io: buf, gp_flags: 12, crc32: 456, compressed_size: 768, uncompressed_size: 0xFFFFFFFF+1, mtime: mtime, filename: 'foo.bin', storage_mode: 8)
|
73
|
-
|
74
|
-
br = ByteReader.new(buf)
|
75
|
-
expect(br.read_4b).to eq(0x04034b50) # Signature
|
76
|
-
expect(br.read_2b).to eq(45) # Version needed to extract
|
77
|
-
expect(br.read_2b).to eq(12) # gp flags
|
78
|
-
expect(br.read_2b).to eq(8) # storage mode
|
79
|
-
expect(br.read_2b).to eq(28160) # DOS time
|
80
|
-
expect(br.read_2b).to eq(18673) # DOS date
|
81
|
-
expect(br.read_4b).to eq(456) # CRC32
|
82
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # compressed size
|
83
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # uncompressed size
|
84
|
-
expect(br.read_2b).to eq(7) # filename size
|
85
|
-
expect(br.read_2b).to eq(20) # extra fields size
|
86
|
-
expect(br.read_n(7)).to eq('foo.bin') # extra fields size
|
87
|
-
|
88
|
-
expect(buf).not_to be_eof
|
89
|
-
|
90
|
-
expect(br.read_2b).to eq(1) # Zip64 extra tag
|
91
|
-
expect(br.read_2b).to eq(16) # Size of the Zip64 extra payload
|
92
|
-
expect(br.read_8b).to eq(0xFFFFFFFF+1) # uncompressed size
|
93
|
-
expect(br.read_8b).to eq(768) # compressed size
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'writes the local file header for an entry that does require Zip64 based on compressed size (with the Zip64 extra)' do
|
97
|
-
buf = StringIO.new
|
98
|
-
mtime = Time.utc(2016, 7, 17, 13, 48)
|
99
|
-
|
100
|
-
subject = ZipTricks::ZipWriter.new
|
101
|
-
subject.write_local_file_header(io: buf, gp_flags: 12, crc32: 456, compressed_size: 0xFFFFFFFF+1, uncompressed_size: 768, mtime: mtime, filename: 'foo.bin', storage_mode: 8)
|
102
|
-
|
103
|
-
br = ByteReader.new(buf)
|
104
|
-
expect(br.read_4b).to eq(0x04034b50) # Signature
|
105
|
-
expect(br.read_2b).to eq(45) # Version needed to extract
|
106
|
-
expect(br.read_2b).to eq(12) # gp flags
|
107
|
-
expect(br.read_2b).to eq(8) # storage mode
|
108
|
-
expect(br.read_2b).to eq(28160) # DOS time
|
109
|
-
expect(br.read_2b).to eq(18673) # DOS date
|
110
|
-
expect(br.read_4b).to eq(456) # CRC32
|
111
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # compressed size
|
112
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # uncompressed size
|
113
|
-
expect(br.read_2b).to eq(7) # filename size
|
114
|
-
expect(br.read_2b).to eq(20) # extra fields size
|
115
|
-
expect(br.read_n(7)).to eq('foo.bin') # extra fields size
|
116
|
-
|
117
|
-
expect(buf).not_to be_eof
|
118
|
-
|
119
|
-
expect(br.read_2b).to eq(1) # Zip64 extra tag
|
120
|
-
expect(br.read_2b).to eq(16) # Size of the Zip64 extra payload
|
121
|
-
expect(br.read_8b).to eq(768) # uncompressed size
|
122
|
-
expect(br.read_8b).to eq(0xFFFFFFFF+1) # compressed size
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe '#write_data_descriptor' do
|
127
|
-
it 'writes 4-byte sizes into the data descriptor for standard file sizes' do
|
128
|
-
buf = StringIO.new
|
129
|
-
|
130
|
-
subject.write_data_descriptor(io: buf, crc32: 123, compressed_size: 89821, uncompressed_size: 990912)
|
131
|
-
|
132
|
-
br = ByteReader.new(buf)
|
133
|
-
expect(br.read_4b).to eq(0x08074b50) # Signature
|
134
|
-
expect(br.read_4b).to eq(123) # CRC32
|
135
|
-
expect(br.read_4b).to eq(89821) # compressed size
|
136
|
-
expect(br.read_4b).to eq(990912) # uncompressed size
|
137
|
-
expect(buf).to be_eof
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'writes 8-byte sizes into the data descriptor for Zip64 compressed file size' do
|
141
|
-
buf = StringIO.new
|
142
|
-
|
143
|
-
subject.write_data_descriptor(io: buf, crc32: 123, compressed_size: 0xFFFFFFFF + 1, uncompressed_size: 990912)
|
144
|
-
|
145
|
-
br = ByteReader.new(buf)
|
146
|
-
expect(br.read_4b).to eq(0x08074b50) # Signature
|
147
|
-
expect(br.read_4b).to eq(123) # CRC32
|
148
|
-
expect(br.read_8b).to eq(0xFFFFFFFF + 1) # compressed size
|
149
|
-
expect(br.read_8b).to eq(990912) # uncompressed size
|
150
|
-
expect(buf).to be_eof
|
151
|
-
end
|
152
|
-
|
153
|
-
it 'writes 8-byte sizes into the data descriptor for Zip64 uncompressed file size' do
|
154
|
-
buf = StringIO.new
|
155
|
-
|
156
|
-
subject.write_data_descriptor(io: buf, crc32: 123, compressed_size: 123, uncompressed_size: 0xFFFFFFFF + 1)
|
157
|
-
|
158
|
-
br = ByteReader.new(buf)
|
159
|
-
expect(br.read_4b).to eq(0x08074b50) # Signature
|
160
|
-
expect(br.read_4b).to eq(123) # CRC32
|
161
|
-
expect(br.read_8b).to eq(123) # compressed size
|
162
|
-
expect(br.read_8b).to eq(0xFFFFFFFF + 1) # uncompressed size
|
163
|
-
expect(buf).to be_eof
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
describe '#write_central_directory_file_header' do
|
168
|
-
it 'writes the file header for a small-ish entry' do
|
169
|
-
buf = StringIO.new
|
170
|
-
|
171
|
-
subject.write_central_directory_file_header(io: buf, local_file_header_location: 898921,
|
172
|
-
gp_flags: 555, storage_mode: 23,
|
173
|
-
compressed_size: 901, uncompressed_size: 909102,
|
174
|
-
mtime: Time.utc(2016, 2, 2, 14, 00), crc32: 89765,
|
175
|
-
filename: 'a-file.txt', external_attrs: 123)
|
176
|
-
|
177
|
-
br = ByteReader.new(buf)
|
178
|
-
expect(br.read_4b).to eq(0x02014b50) # Central directory entry sig
|
179
|
-
expect(br.read_2b).to eq(820) # version made by
|
180
|
-
expect(br.read_2b).to eq(20) # version need to extract
|
181
|
-
expect(br.read_2b).to eq(555) # general purpose bit flag (explicitly set to bogus value to ensure we pass it through)
|
182
|
-
expect(br.read_2b).to eq(23) # compression method (explicitly set to bogus value)
|
183
|
-
expect(br.read_2b).to eq(28672) # last mod file time
|
184
|
-
expect(br.read_2b).to eq(18498) # last mod file date
|
185
|
-
expect(br.read_4b).to eq(89765) # crc32
|
186
|
-
expect(br.read_4b).to eq(901) # compressed size
|
187
|
-
expect(br.read_4b).to eq(909102) # uncompressed size
|
188
|
-
expect(br.read_2b).to eq(10) # filename length
|
189
|
-
expect(br.read_2b).to eq(0) # extra field length
|
190
|
-
expect(br.read_2b).to eq(0) # file comment
|
191
|
-
expect(br.read_2b).to eq(0) # disk number, must be blanked to the maximum value because of The Unarchiver bug
|
192
|
-
expect(br.read_2b).to eq(0) # internal file attributes
|
193
|
-
expect(br.read_4b).to eq(2175008768) # external file attributes
|
194
|
-
expect(br.read_4b).to eq(898921) # relative offset of local header
|
195
|
-
expect(br.read_n(10)).to eq('a-file.txt') # the filename
|
196
|
-
end
|
197
|
-
|
198
|
-
it 'writes the file header for an entry that requires Zip64 extra because of the uncompressed size' do
|
199
|
-
buf = StringIO.new
|
200
|
-
|
201
|
-
subject.write_central_directory_file_header(io: buf, local_file_header_location: 898921,
|
202
|
-
gp_flags: 555, storage_mode: 23,
|
203
|
-
compressed_size: 901, uncompressed_size: 0xFFFFFFFFF + 3,
|
204
|
-
mtime: Time.utc(2016, 2, 2, 14, 00), crc32: 89765,
|
205
|
-
filename: 'a-file.txt', external_attrs: 123)
|
206
|
-
|
207
|
-
br = ByteReader.new(buf)
|
208
|
-
expect(br.read_4b).to eq(0x02014b50) # Central directory entry sig
|
209
|
-
expect(br.read_2b).to eq(820) # version made by
|
210
|
-
expect(br.read_2b).to eq(45) # version need to extract
|
211
|
-
expect(br.read_2b).to eq(555) # general purpose bit flag (explicitly set to bogus value to ensure we pass it through)
|
212
|
-
expect(br.read_2b).to eq(23) # compression method (explicitly set to bogus value)
|
213
|
-
expect(br.read_2b).to eq(28672) # last mod file time
|
214
|
-
expect(br.read_2b).to eq(18498) # last mod file date
|
215
|
-
expect(br.read_4b).to eq(89765) # crc32
|
216
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # compressed size
|
217
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # uncompressed size
|
218
|
-
expect(br.read_2b).to eq(10) # filename length
|
219
|
-
expect(br.read_2b).to eq(32) # extra field length
|
220
|
-
expect(br.read_2b).to eq(0) # file comment
|
221
|
-
expect(br.read_2b).to eq(0xFFFF) # disk number, must be blanked to the maximum value because of The Unarchiver bug
|
222
|
-
expect(br.read_2b).to eq(0) # internal file attributes
|
223
|
-
expect(br.read_4b).to eq(2175008768) # external file attributes
|
224
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # relative offset of local header
|
225
|
-
expect(br.read_n(10)).to eq('a-file.txt') # the filename
|
226
|
-
|
227
|
-
expect(buf).not_to be_eof
|
228
|
-
expect(br.read_2b).to eq(1) # Zip64 extra tag
|
229
|
-
expect(br.read_2b).to eq(28) # Size of the Zip64 extra payload
|
230
|
-
expect(br.read_8b).to eq(0xFFFFFFFFF + 3) # uncompressed size
|
231
|
-
expect(br.read_8b).to eq(901) # compressed size
|
232
|
-
expect(br.read_8b).to eq(898921) # local file header location
|
233
|
-
end
|
234
|
-
|
235
|
-
it 'writes the file header for an entry that requires Zip64 extra because of the compressed size' do
|
236
|
-
buf = StringIO.new
|
237
|
-
|
238
|
-
subject.write_central_directory_file_header(io: buf, local_file_header_location: 898921,
|
239
|
-
gp_flags: 555, storage_mode: 23,
|
240
|
-
compressed_size: 0xFFFFFFFFF + 3, uncompressed_size: 901, # the worst compression scheme in the universe
|
241
|
-
mtime: Time.utc(2016, 2, 2, 14, 00), crc32: 89765,
|
242
|
-
filename: 'a-file.txt', external_attrs: 123)
|
243
|
-
|
244
|
-
br = ByteReader.new(buf)
|
245
|
-
expect(br.read_4b).to eq(0x02014b50) # Central directory entry sig
|
246
|
-
expect(br.read_2b).to eq(820) # version made by
|
247
|
-
expect(br.read_2b).to eq(45) # version need to extract
|
248
|
-
expect(br.read_2b).to eq(555) # general purpose bit flag (explicitly set to bogus value to ensure we pass it through)
|
249
|
-
expect(br.read_2b).to eq(23) # compression method (explicitly set to bogus value)
|
250
|
-
expect(br.read_2b).to eq(28672) # last mod file time
|
251
|
-
expect(br.read_2b).to eq(18498) # last mod file date
|
252
|
-
expect(br.read_4b).to eq(89765) # crc32
|
253
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # compressed size
|
254
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # uncompressed size
|
255
|
-
expect(br.read_2b).to eq(10) # filename length
|
256
|
-
expect(br.read_2b).to eq(32) # extra field length
|
257
|
-
expect(br.read_2b).to eq(0) # file comment
|
258
|
-
expect(br.read_2b).to eq(0xFFFF) # disk number, must be blanked to the maximum value because of The Unarchiver bug
|
259
|
-
expect(br.read_2b).to eq(0) # internal file attributes
|
260
|
-
expect(br.read_4b).to eq(2175008768) # external file attributes
|
261
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # relative offset of local header
|
262
|
-
expect(br.read_n(10)).to eq('a-file.txt') # the filename
|
263
|
-
|
264
|
-
expect(buf).not_to be_eof
|
265
|
-
expect(br.read_2b).to eq(1) # Zip64 extra tag
|
266
|
-
expect(br.read_2b).to eq(28) # Size of the Zip64 extra payload
|
267
|
-
expect(br.read_8b).to eq(901) # uncompressed size
|
268
|
-
expect(br.read_8b).to eq(0xFFFFFFFFF + 3) # compressed size
|
269
|
-
expect(br.read_8b).to eq(898921) # local file header location
|
270
|
-
end
|
271
|
-
|
272
|
-
it 'writes the file header for an entry that requires Zip64 extra because of the local file header offset being beyound 4GB' do
|
273
|
-
buf = StringIO.new
|
274
|
-
|
275
|
-
subject.write_central_directory_file_header(io: buf, local_file_header_location: 0xFFFFFFFFF + 1,
|
276
|
-
gp_flags: 555, storage_mode: 23,
|
277
|
-
compressed_size: 8981, uncompressed_size: 819891, # the worst compression scheme in the universe
|
278
|
-
mtime: Time.utc(2016, 2, 2, 14, 00), crc32: 89765,
|
279
|
-
filename: 'a-file.txt', external_attrs: 123)
|
280
|
-
|
281
|
-
br = ByteReader.new(buf)
|
282
|
-
expect(br.read_4b).to eq(0x02014b50) # Central directory entry sig
|
283
|
-
expect(br.read_2b).to eq(820) # version made by
|
284
|
-
expect(br.read_2b).to eq(45) # version need to extract
|
285
|
-
expect(br.read_2b).to eq(555) # general purpose bit flag (explicitly set to bogus value to ensure we pass it through)
|
286
|
-
expect(br.read_2b).to eq(23) # compression method (explicitly set to bogus value)
|
287
|
-
expect(br.read_2b).to eq(28672) # last mod file time
|
288
|
-
expect(br.read_2b).to eq(18498) # last mod file date
|
289
|
-
expect(br.read_4b).to eq(89765) # crc32
|
290
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # compressed size
|
291
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # uncompressed size
|
292
|
-
expect(br.read_2b).to eq(10) # filename length
|
293
|
-
expect(br.read_2b).to eq(32) # extra field length
|
294
|
-
expect(br.read_2b).to eq(0) # file comment
|
295
|
-
expect(br.read_2b).to eq(0xFFFF) # disk number, must be blanked to the maximum value because of The Unarchiver bug
|
296
|
-
expect(br.read_2b).to eq(0) # internal file attributes
|
297
|
-
expect(br.read_4b).to eq(2175008768) # external file attributes
|
298
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # relative offset of local header
|
299
|
-
expect(br.read_n(10)).to eq('a-file.txt') # the filename
|
300
|
-
|
301
|
-
expect(buf).not_to be_eof
|
302
|
-
expect(br.read_2b).to eq(1) # Zip64 extra tag
|
303
|
-
expect(br.read_2b).to eq(28) # Size of the Zip64 extra payload
|
304
|
-
expect(br.read_8b).to eq(819891) # uncompressed size
|
305
|
-
expect(br.read_8b).to eq(8981) # compressed size
|
306
|
-
expect(br.read_8b).to eq(0xFFFFFFFFF + 1) # local file header location
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
describe '#write_end_of_central_directory' do
|
311
|
-
it 'writes out the EOCD with all markers for a small ZIP file with just a few entries' do
|
312
|
-
buf = StringIO.new
|
313
|
-
|
314
|
-
num_files = rand(8..190)
|
315
|
-
subject.write_end_of_central_directory(io: buf, start_of_central_directory_location: 9091211,
|
316
|
-
central_directory_size: 9091, num_files_in_archive: num_files)
|
317
|
-
|
318
|
-
br = ByteReader.new(buf)
|
319
|
-
expect(br.read_4b).to eq(0x06054b50) # EOCD signature
|
320
|
-
expect(br.read_2b).to eq(0) # number of this disk
|
321
|
-
expect(br.read_2b).to eq(0) # number of the disk with the EOCD record
|
322
|
-
expect(br.read_2b).to eq(num_files) # number of files on this disk
|
323
|
-
expect(br.read_2b).to eq(num_files) # number of files in central directory total (for all disks)
|
324
|
-
expect(br.read_4b).to eq(9091) # size of the central directory (cdir records for all files)
|
325
|
-
expect(br.read_4b).to eq(9091211) # start of central directory offset from the beginning of file/disk
|
326
|
-
|
327
|
-
comment_length = br.read_2b
|
328
|
-
expect(comment_length).not_to be_zero
|
329
|
-
|
330
|
-
expect(br.read_n(comment_length)).to match(/ZipTricks/)
|
331
|
-
end
|
332
|
-
|
333
|
-
it 'writes out the custom comment' do
|
334
|
-
buf = ''
|
335
|
-
comment = 'Ohai mate'
|
336
|
-
subject.write_end_of_central_directory(io: buf, start_of_central_directory_location: 9091211,
|
337
|
-
central_directory_size: 9091, num_files_in_archive: 4, comment: comment)
|
338
|
-
|
339
|
-
size_and_comment = buf[((comment.bytesize + 2) * -1)..-1]
|
340
|
-
comment_size = size_and_comment.unpack('v')[0]
|
341
|
-
expect(comment_size).to eq(comment.bytesize)
|
342
|
-
end
|
343
|
-
|
344
|
-
it 'writes out the Zip64 EOCD as well if the central directory is located beyound 4GB in the archive' do
|
345
|
-
buf = StringIO.new
|
346
|
-
|
347
|
-
num_files = rand(8..190)
|
348
|
-
subject.write_end_of_central_directory(io: buf, start_of_central_directory_location: 0xFFFFFFFF + 3,
|
349
|
-
central_directory_size: 9091, num_files_in_archive: num_files)
|
350
|
-
|
351
|
-
br = ByteReader.new(buf)
|
352
|
-
|
353
|
-
expect(br.read_4b).to eq(0x06064b50) # Zip64 EOCD signature
|
354
|
-
expect(br.read_8b).to eq(44) # Zip64 EOCD record size
|
355
|
-
expect(br.read_2b).to eq(820) # Version made by
|
356
|
-
expect(br.read_2b).to eq(45) # Version needed to extract
|
357
|
-
expect(br.read_4b).to eq(0) # Number of this disk
|
358
|
-
expect(br.read_4b).to eq(0) # Number of the disk with the Zip64 EOCD record
|
359
|
-
expect(br.read_8b).to eq(num_files) # Number of entries in the central directory of this disk
|
360
|
-
expect(br.read_8b).to eq(num_files) # Number of entries in the central directories of all disks
|
361
|
-
expect(br.read_8b).to eq(9091) # Central directory size
|
362
|
-
expect(br.read_8b).to eq(0xFFFFFFFF + 3) # Start of central directory location
|
363
|
-
|
364
|
-
expect(br.read_4b).to eq(0x07064b50) # Zip64 EOCD locator signature
|
365
|
-
expect(br.read_4b).to eq(0) # Number of the disk with the EOCD locator signature
|
366
|
-
expect(br.read_8b).to eq((0xFFFFFFFF + 3) + 9091) # Where the Zip64 EOCD record starts
|
367
|
-
expect(br.read_4b).to eq(1) # Total number of disks
|
368
|
-
|
369
|
-
# Then the usual EOCD record
|
370
|
-
expect(br.read_4b).to eq(0x06054b50) # EOCD signature
|
371
|
-
expect(br.read_2b).to eq(0) # number of this disk
|
372
|
-
expect(br.read_2b).to eq(0) # number of the disk with the EOCD record
|
373
|
-
expect(br.read_2b).to eq(0xFFFF) # number of files on this disk
|
374
|
-
expect(br.read_2b).to eq(0xFFFF) # number of files in central directory total (for all disks)
|
375
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # size of the central directory (cdir records for all files)
|
376
|
-
expect(br.read_4b).to eq(0xFFFFFFFF) # start of central directory offset from the beginning of file/disk
|
377
|
-
|
378
|
-
comment_length = br.read_2b
|
379
|
-
expect(comment_length).not_to be_zero
|
380
|
-
expect(br.read_n(comment_length)).to match(/ZipTricks/)
|
381
|
-
end
|
382
|
-
|
383
|
-
it 'writes out the Zip64 EOCD if the archive has more than 0xFFFF files' do
|
384
|
-
buf = StringIO.new
|
385
|
-
|
386
|
-
subject.write_end_of_central_directory(io: buf, start_of_central_directory_location: 123,
|
387
|
-
central_directory_size: 9091, num_files_in_archive: 0xFFFF + 1)
|
388
|
-
|
389
|
-
br = ByteReader.new(buf)
|
390
|
-
|
391
|
-
expect(br.read_4b).to eq(0x06064b50) # Zip64 EOCD signature
|
392
|
-
br.read_8b
|
393
|
-
br.read_2b
|
394
|
-
br.read_2b
|
395
|
-
br.read_4b
|
396
|
-
br.read_4b
|
397
|
-
expect(br.read_8b).to eq(0xFFFF + 1) # Number of entries in the central directory of this disk
|
398
|
-
expect(br.read_8b).to eq(0xFFFF + 1) # Number of entries in the central directories of all disks
|
399
|
-
end
|
400
|
-
|
401
|
-
it 'writes out the Zip64 EOCD if the central directory size exceeds 0xFFFFFFFF' do
|
402
|
-
buf = StringIO.new
|
403
|
-
|
404
|
-
subject.write_end_of_central_directory(io: buf, start_of_central_directory_location: 123,
|
405
|
-
central_directory_size: 0xFFFFFFFF + 2, num_files_in_archive: 5)
|
406
|
-
|
407
|
-
br = ByteReader.new(buf)
|
408
|
-
|
409
|
-
expect(br.read_4b).to eq(0x06064b50) # Zip64 EOCD signature
|
410
|
-
br.read_8b
|
411
|
-
br.read_2b
|
412
|
-
br.read_2b
|
413
|
-
br.read_4b
|
414
|
-
br.read_4b
|
415
|
-
expect(br.read_8b).to eq(5) # Number of entries in the central directory of this disk
|
416
|
-
expect(br.read_8b).to eq(5) # Number of entries in the central directories of all disks
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|