zip_tricks 5.2.0 → 5.6.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +96 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +37 -1
- data/CONTRIBUTING.md +4 -4
- data/README.md +28 -17
- data/lib/zip_tricks/block_write.rb +26 -21
- data/lib/zip_tricks/file_reader.rb +8 -6
- data/lib/zip_tricks/null_writer.rb +1 -1
- data/lib/zip_tricks/output_enumerator.rb +48 -27
- data/lib/zip_tricks/path_set.rb +4 -0
- data/lib/zip_tricks/rails_streaming.rb +7 -9
- data/lib/zip_tricks/stream_crc32.rb +2 -2
- data/lib/zip_tricks/streamer.rb +69 -25
- data/lib/zip_tricks/streamer/deflated_writer.rb +9 -28
- data/lib/zip_tricks/streamer/entry.rb +5 -1
- data/lib/zip_tricks/streamer/stored_writer.rb +4 -3
- data/lib/zip_tricks/version.rb +1 -1
- data/lib/zip_tricks/write_and_tell.rb +2 -12
- data/lib/zip_tricks/write_buffer.rb +37 -17
- data/lib/zip_tricks/zip_writer.rb +24 -24
- data/zip_tricks.gemspec +3 -5
- metadata +8 -44
- data/.travis.yml +0 -11
- data/qa/README_QA.md +0 -16
- data/qa/generate_test_files.rb +0 -126
- data/qa/in/VTYL8830.jpg +0 -0
- data/qa/in/war-and-peace.txt +0 -10810
- data/qa/support.rb +0 -88
- data/qa/test-report-2016-07-28.txt +0 -156
- data/qa/test-report-2016-12-12.txt +0 -156
- data/qa/test-report-2017-04-2.txt +0 -168
- data/qa/test-report.txt +0 -28
@@ -4,7 +4,7 @@
|
|
4
4
|
# Normally you will not have to use this class directly
|
5
5
|
class ZipTricks::Streamer::Entry < Struct.new(:filename, :crc32, :compressed_size,
|
6
6
|
:uncompressed_size, :storage_mode, :mtime,
|
7
|
-
:use_data_descriptor)
|
7
|
+
:use_data_descriptor, :local_header_offset, :bytes_used_for_local_header, :bytes_used_for_data_descriptor, :unix_permissions)
|
8
8
|
def initialize(*)
|
9
9
|
super
|
10
10
|
filename.force_encoding(Encoding::UTF_8)
|
@@ -15,6 +15,10 @@ class ZipTricks::Streamer::Entry < Struct.new(:filename, :crc32, :compressed_siz
|
|
15
15
|
end)
|
16
16
|
end
|
17
17
|
|
18
|
+
def total_bytes_used
|
19
|
+
bytes_used_for_local_header + compressed_size + bytes_used_for_data_descriptor
|
20
|
+
end
|
21
|
+
|
18
22
|
# Set the general purpose flags for the entry. We care about is the EFS
|
19
23
|
# bit (bit 11) which should be set if the filename is UTF8. If it is, we need to set the
|
20
24
|
# bit so that the unarchiving application knows that the filename in the archive is UTF-8
|
@@ -12,7 +12,8 @@ class ZipTricks::Streamer::StoredWriter
|
|
12
12
|
|
13
13
|
def initialize(io)
|
14
14
|
@io = ZipTricks::WriteAndTell.new(io)
|
15
|
-
@
|
15
|
+
@crc_compute = ZipTricks::StreamCRC32.new
|
16
|
+
@crc = ZipTricks::WriteBuffer.new(@crc_compute, CRC32_BUFFER_SIZE)
|
16
17
|
end
|
17
18
|
|
18
19
|
# Writes the given data to the contained IO object.
|
@@ -28,9 +29,9 @@ class ZipTricks::Streamer::StoredWriter
|
|
28
29
|
# Returns the amount of data written and the CRC32 checksum. The return value
|
29
30
|
# can be directly used as the argument to {Streamer#update_last_entry_and_write_data_descriptor}
|
30
31
|
#
|
31
|
-
# @param data[String] data to be written
|
32
32
|
# @return [Hash] a hash of `{crc32, compressed_size, uncompressed_size}`
|
33
33
|
def finish
|
34
|
-
|
34
|
+
@crc.flush
|
35
|
+
{crc32: @crc_compute.to_i, compressed_size: @io.tell, uncompressed_size: @io.tell}
|
35
36
|
end
|
36
37
|
end
|
data/lib/zip_tricks/version.rb
CHANGED
@@ -10,9 +10,8 @@ class ZipTricks::WriteAndTell
|
|
10
10
|
|
11
11
|
def <<(bytes)
|
12
12
|
return self if bytes.nil?
|
13
|
-
|
14
|
-
@
|
15
|
-
@pos += binary_bytes.bytesize
|
13
|
+
@io << bytes.b
|
14
|
+
@pos += bytes.bytesize
|
16
15
|
self
|
17
16
|
end
|
18
17
|
|
@@ -23,13 +22,4 @@ class ZipTricks::WriteAndTell
|
|
23
22
|
def tell
|
24
23
|
@pos
|
25
24
|
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def binary(str)
|
30
|
-
return str if str.encoding == Encoding::BINARY
|
31
|
-
str.force_encoding(Encoding::BINARY)
|
32
|
-
rescue RuntimeError # the string is frozen
|
33
|
-
str.dup.force_encoding(Encoding::BINARY)
|
34
|
-
end
|
35
25
|
end
|
@@ -7,13 +7,34 @@
|
|
7
7
|
# CRC32 combine operations - and this adds up. Since the CRC32 value
|
8
8
|
# is usually not needed until the complete output has completed
|
9
9
|
# we can buffer at least some amount of data before computing CRC32 over it.
|
10
|
+
# We also use this buffer for output via Rack, where some amount of buffering
|
11
|
+
# helps reduce the number of syscalls made by the webserver. ZipTricks performs
|
12
|
+
# lots of very small writes, and some degree of speedup (about 20%) can be achieved
|
13
|
+
# with a buffer of a few KB.
|
14
|
+
#
|
15
|
+
# Note that there is no guarantee that the write buffer is going to flush at or above
|
16
|
+
# the given `buffer_size`, because for writes which exceed the buffer size it will
|
17
|
+
# first `flush` and then write through the oversized chunk, without buffering it. This
|
18
|
+
# helps conserve memory. Also note that the buffer will *not* duplicate strings for you
|
19
|
+
# and *will* yield the same buffer String over and over, so if you are storing it in an
|
20
|
+
# Array you might need to duplicate it.
|
21
|
+
#
|
22
|
+
# Note also that the WriteBuffer assumes that the object it `<<`-writes into is going
|
23
|
+
# to **consume** in some way the string that it passes in. After the `<<` method returns,
|
24
|
+
# the WriteBuffer will be cleared, and it passes the same String reference on every call
|
25
|
+
# to `<<`. Therefore, if you need to retain the output of the WriteBuffer in, say, an Array,
|
26
|
+
# you might need to `.dup` the `String` it gives you.
|
10
27
|
class ZipTricks::WriteBuffer
|
11
28
|
# Creates a new WriteBuffer bypassing into a given writable object
|
12
29
|
#
|
13
|
-
# @param writable[#<<] An object that responds to `#<<` with
|
30
|
+
# @param writable[#<<] An object that responds to `#<<` with a String as argument
|
14
31
|
# @param buffer_size[Integer] How many bytes to buffer
|
15
32
|
def initialize(writable, buffer_size)
|
16
|
-
|
33
|
+
# Allocating the buffer using a zero-padded String as a variation
|
34
|
+
# on using capacity:, which JRuby apparently does not like very much. The
|
35
|
+
# desire here is that the buffer doesn't have to be resized during the lifetime
|
36
|
+
# of the object.
|
37
|
+
@buf = ("\0".b * (buffer_size * 2)).clear
|
17
38
|
@buffer_size = buffer_size
|
18
39
|
@writable = writable
|
19
40
|
end
|
@@ -24,28 +45,27 @@ class ZipTricks::WriteBuffer
|
|
24
45
|
# @param data[String] data to be written
|
25
46
|
# @return self
|
26
47
|
def <<(data)
|
27
|
-
|
28
|
-
|
48
|
+
if data.bytesize >= @buffer_size
|
49
|
+
flush unless @buf.empty? # <- this is were we can output less than @buffer_size
|
50
|
+
@writable << data
|
51
|
+
else
|
52
|
+
@buf << data
|
53
|
+
flush if @buf.bytesize >= @buffer_size
|
54
|
+
end
|
29
55
|
self
|
30
56
|
end
|
31
57
|
|
32
58
|
# Explicitly flushes the buffer if it contains anything
|
33
59
|
#
|
34
60
|
# @return self
|
35
|
-
def flush
|
36
|
-
|
37
|
-
|
38
|
-
|
61
|
+
def flush
|
62
|
+
unless @buf.empty?
|
63
|
+
@writable << @buf
|
64
|
+
@buf.clear
|
65
|
+
end
|
39
66
|
self
|
40
67
|
end
|
41
68
|
|
42
|
-
#
|
43
|
-
|
44
|
-
# computation by retrieving the CRC as an integer
|
45
|
-
#
|
46
|
-
# @return [Integer] the return value of `writable#to_i`
|
47
|
-
def to_i
|
48
|
-
flush!
|
49
|
-
@writable.to_i
|
50
|
-
end
|
69
|
+
# `flush!` was renamed to `flush` but we preserve this method for backwards compatibility
|
70
|
+
alias_method :flush!, :flush
|
51
71
|
end
|
@@ -31,22 +31,10 @@ class ZipTricks::ZipWriter
|
|
31
31
|
VERSION_MADE_BY = 52
|
32
32
|
VERSION_NEEDED_TO_EXTRACT = 20
|
33
33
|
VERSION_NEEDED_TO_EXTRACT_ZIP64 = 45
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
# zipinfo.external_attr = 0644 << 16L # permissions -r-wr--r--.
|
39
|
-
# We snatch the incantations from Rubyzip for this.
|
40
|
-
unix_perms = 0o644
|
41
|
-
file_type_file = 0o10
|
42
|
-
(file_type_file << 12 | (unix_perms & 0o7777)) << 16
|
43
|
-
end
|
44
|
-
EMPTY_DIRECTORY_EXTERNAL_ATTRS = begin
|
45
|
-
# Applies permissions to an empty directory.
|
46
|
-
unix_perms = 0o755
|
47
|
-
file_type_dir = 0o04
|
48
|
-
(file_type_dir << 12 | (unix_perms & 0o7777)) << 16
|
49
|
-
end
|
34
|
+
DEFAULT_FILE_UNIX_PERMISSIONS = 0o644
|
35
|
+
DEFAULT_DIRECTORY_UNIX_PERMISSIONS = 0o755
|
36
|
+
FILE_TYPE_FILE = 0o10
|
37
|
+
FILE_TYPE_DIRECTORY = 0o04
|
50
38
|
MADE_BY_SIGNATURE = begin
|
51
39
|
# A combination of the VERSION_MADE_BY low byte and the OS type high byte
|
52
40
|
os_type = 3 # UNIX
|
@@ -57,14 +45,15 @@ class ZipTricks::ZipWriter
|
|
57
45
|
C_UINT2 = 'v' # Encode a 2-byte unsigned little-endian uint
|
58
46
|
C_UINT8 = 'Q<' # Encode an 8-byte unsigned little-endian uint
|
59
47
|
C_CHAR = 'C' # For bit-encoded strings
|
60
|
-
C_INT4 = '
|
48
|
+
C_INT4 = 'l<' # Encode a 4-byte signed little-endian int
|
61
49
|
|
62
50
|
private_constant :FOUR_BYTE_MAX_UINT,
|
63
51
|
:TWO_BYTE_MAX_UINT,
|
64
52
|
:VERSION_MADE_BY,
|
65
53
|
:VERSION_NEEDED_TO_EXTRACT,
|
66
54
|
:VERSION_NEEDED_TO_EXTRACT_ZIP64,
|
67
|
-
:
|
55
|
+
:FILE_TYPE_FILE,
|
56
|
+
:FILE_TYPE_DIRECTORY,
|
68
57
|
:MADE_BY_SIGNATURE,
|
69
58
|
:C_UINT4,
|
70
59
|
:C_UINT2,
|
@@ -136,6 +125,7 @@ class ZipTricks::ZipWriter
|
|
136
125
|
# @param crc32[Fixnum] The CRC32 checksum of the file
|
137
126
|
# @param mtime[Time] the modification time to be recorded in the ZIP
|
138
127
|
# @param gp_flags[Fixnum] bit-packed general purpose flags
|
128
|
+
# @param unix_permissions[Fixnum?] the permissions for the file, or nil for the default to be used
|
139
129
|
# @return [void]
|
140
130
|
def write_central_directory_file_header(io:,
|
141
131
|
local_file_header_location:,
|
@@ -145,7 +135,9 @@ class ZipTricks::ZipWriter
|
|
145
135
|
uncompressed_size:,
|
146
136
|
mtime:,
|
147
137
|
crc32:,
|
148
|
-
filename
|
138
|
+
filename:,
|
139
|
+
unix_permissions: nil
|
140
|
+
)
|
149
141
|
# At this point if the header begins somewhere beyound 0xFFFFFFFF we _have_ to record the offset
|
150
142
|
# of the local file header as a zip64 extra field, so we give up, give in, you loose, love will always win...
|
151
143
|
add_zip64 = (local_file_header_location > FOUR_BYTE_MAX_UINT) ||
|
@@ -195,16 +187,20 @@ class ZipTricks::ZipWriter
|
|
195
187
|
[TWO_BYTE_MAX_UINT].pack(C_UINT2)
|
196
188
|
else
|
197
189
|
[0].pack(C_UINT2)
|
198
|
-
|
190
|
+
end
|
199
191
|
io << [0].pack(C_UINT2) # internal file attributes 2 bytes
|
200
192
|
|
201
193
|
# Because the add_empty_directory method will create a directory with a trailing "/",
|
202
194
|
# this check can be used to assign proper permissions to the created directory.
|
203
|
-
|
204
|
-
|
195
|
+
# external file attributes 4 bytes
|
196
|
+
external_attrs = if filename.end_with?('/')
|
197
|
+
unix_permissions ||= DEFAULT_DIRECTORY_UNIX_PERMISSIONS
|
198
|
+
generate_external_attrs(unix_permissions, FILE_TYPE_DIRECTORY)
|
205
199
|
else
|
206
|
-
|
200
|
+
unix_permissions ||= DEFAULT_FILE_UNIX_PERMISSIONS
|
201
|
+
generate_external_attrs(unix_permissions, FILE_TYPE_FILE)
|
207
202
|
end
|
203
|
+
io << [external_attrs].pack(C_UINT4)
|
208
204
|
|
209
205
|
io << if add_zip64 # relative offset of local header 4 bytes
|
210
206
|
[FOUR_BYTE_MAX_UINT].pack(C_UINT4)
|
@@ -385,7 +381,7 @@ class ZipTricks::ZipWriter
|
|
385
381
|
0x5455, C_UINT2, # tag for this extra block type ("UT")
|
386
382
|
(1 + 4), C_UINT2, # the size of this block (1 byte used for the Flag + 3 longs used for the timestamp)
|
387
383
|
flags, C_CHAR, # encode a single byte
|
388
|
-
mtime.utc.to_i, C_INT4, # Use a signed
|
384
|
+
mtime.utc.to_i, C_INT4, # Use a signed int, not the unsigned one used by the rest of the ZIP spec.
|
389
385
|
]
|
390
386
|
# The atime and ctime can be omitted if not present
|
391
387
|
pack_array(data_and_packspecs)
|
@@ -434,4 +430,8 @@ class ZipTricks::ZipWriter
|
|
434
430
|
values, packspecs = values_to_packspecs.partition.each_with_index { |_, i| i.even? }
|
435
431
|
values.pack(packspecs.join)
|
436
432
|
end
|
433
|
+
|
434
|
+
def generate_external_attrs(unix_permissions_int, file_type_int)
|
435
|
+
(file_type_int << 12 | (unix_permissions_int & 0o7777)) << 16
|
436
|
+
end
|
437
437
|
end
|
data/zip_tricks.gemspec
CHANGED
@@ -5,13 +5,13 @@ require 'zip_tricks/version'
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'zip_tricks'
|
7
7
|
spec.version = ZipTricks::VERSION
|
8
|
-
spec.authors = ['Julik Tarkhanov', 'Noah Berman', 'Dmitry Tymchuk', 'David Bosveld']
|
8
|
+
spec.authors = ['Julik Tarkhanov', 'Noah Berman', 'Dmitry Tymchuk', 'David Bosveld', 'Felix Bünemann']
|
9
9
|
spec.email = ['me@julik.nl']
|
10
10
|
|
11
11
|
spec.licenses = ['MIT (Hippocratic)']
|
12
12
|
spec.summary = 'Stream out ZIP files from Ruby'
|
13
13
|
spec.description = 'Stream out ZIP files from Ruby'
|
14
|
-
spec.homepage = '
|
14
|
+
spec.homepage = 'https://github.com/wetransfer/zip_tricks'
|
15
15
|
|
16
16
|
# Prevent pushing this gem to RubyGems.org.
|
17
17
|
# To allow pushes either set the 'allowed_push_host'
|
@@ -32,10 +32,8 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_development_dependency 'bundler'
|
34
34
|
spec.add_development_dependency 'rubyzip', '~> 1'
|
35
|
-
spec.add_development_dependency 'terminal-table'
|
36
|
-
spec.add_development_dependency 'range_utils'
|
37
35
|
|
38
|
-
spec.add_development_dependency 'rack', '~> 1.6' # For
|
36
|
+
spec.add_development_dependency 'rack', '~> 1.6' # For tests, where we spin up a server
|
39
37
|
spec.add_development_dependency 'rake', '~> 12.2'
|
40
38
|
spec.add_development_dependency 'rspec', '~> 3'
|
41
39
|
spec.add_development_dependency 'complexity_assert'
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zip_tricks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
8
8
|
- Noah Berman
|
9
9
|
- Dmitry Tymchuk
|
10
10
|
- David Bosveld
|
11
|
-
|
11
|
+
- Felix Bünemann
|
12
|
+
autorequire:
|
12
13
|
bindir: exe
|
13
14
|
cert_chain: []
|
14
|
-
date:
|
15
|
+
date: 2021-06-05 00:00:00.000000000 Z
|
15
16
|
dependencies:
|
16
17
|
- !ruby/object:Gem::Dependency
|
17
18
|
name: bundler
|
@@ -41,34 +42,6 @@ dependencies:
|
|
41
42
|
- - "~>"
|
42
43
|
- !ruby/object:Gem::Version
|
43
44
|
version: '1'
|
44
|
-
- !ruby/object:Gem::Dependency
|
45
|
-
name: terminal-table
|
46
|
-
requirement: !ruby/object:Gem::Requirement
|
47
|
-
requirements:
|
48
|
-
- - ">="
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: '0'
|
51
|
-
type: :development
|
52
|
-
prerelease: false
|
53
|
-
version_requirements: !ruby/object:Gem::Requirement
|
54
|
-
requirements:
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: '0'
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: range_utils
|
60
|
-
requirement: !ruby/object:Gem::Requirement
|
61
|
-
requirements:
|
62
|
-
- - ">="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '0'
|
65
|
-
type: :development
|
66
|
-
prerelease: false
|
67
|
-
version_requirements: !ruby/object:Gem::Requirement
|
68
|
-
requirements:
|
69
|
-
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version: '0'
|
72
45
|
- !ruby/object:Gem::Dependency
|
73
46
|
name: rack
|
74
47
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,10 +191,10 @@ extra_rdoc_files: []
|
|
218
191
|
files:
|
219
192
|
- ".codeclimate.yml"
|
220
193
|
- ".document"
|
194
|
+
- ".github/workflows/ci.yml"
|
221
195
|
- ".gitignore"
|
222
196
|
- ".rspec"
|
223
197
|
- ".rubocop.yml"
|
224
|
-
- ".travis.yml"
|
225
198
|
- ".yardopts"
|
226
199
|
- CHANGELOG.md
|
227
200
|
- CODE_OF_CONDUCT.md
|
@@ -262,22 +235,13 @@ files:
|
|
262
235
|
- lib/zip_tricks/write_and_tell.rb
|
263
236
|
- lib/zip_tricks/write_buffer.rb
|
264
237
|
- lib/zip_tricks/zip_writer.rb
|
265
|
-
- qa/README_QA.md
|
266
|
-
- qa/generate_test_files.rb
|
267
|
-
- qa/in/VTYL8830.jpg
|
268
|
-
- qa/in/war-and-peace.txt
|
269
|
-
- qa/support.rb
|
270
|
-
- qa/test-report-2016-07-28.txt
|
271
|
-
- qa/test-report-2016-12-12.txt
|
272
|
-
- qa/test-report-2017-04-2.txt
|
273
|
-
- qa/test-report.txt
|
274
238
|
- zip_tricks.gemspec
|
275
|
-
homepage:
|
239
|
+
homepage: https://github.com/wetransfer/zip_tricks
|
276
240
|
licenses:
|
277
241
|
- MIT (Hippocratic)
|
278
242
|
metadata:
|
279
243
|
allowed_push_host: https://rubygems.org
|
280
|
-
post_install_message:
|
244
|
+
post_install_message:
|
281
245
|
rdoc_options: []
|
282
246
|
require_paths:
|
283
247
|
- lib
|
@@ -293,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
293
257
|
version: '0'
|
294
258
|
requirements: []
|
295
259
|
rubygems_version: 3.0.3
|
296
|
-
signing_key:
|
260
|
+
signing_key:
|
297
261
|
specification_version: 4
|
298
262
|
summary: Stream out ZIP files from Ruby
|
299
263
|
test_files: []
|
data/.travis.yml
DELETED
data/qa/README_QA.md
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
## Manual testing harness for ZipTricks
|
2
|
-
|
3
|
-
These tests will generate **very large** files that test various edge cases of ZIP generation. The idea is to generate
|
4
|
-
these files and to then try to open them with the unarchiver applications we support. The workflow is as follows:
|
5
|
-
|
6
|
-
|
7
|
-
1. Configure your storage to have `zip_tricks` directory linked into your virtual machines and to be on a fast volume (SSD RAID0 is recommended)
|
8
|
-
2. Run `generate_test_files.rb`. This will take some time and produce a number of large ZIP files.
|
9
|
-
3. Open them with the following ZIP unarchivers:
|
10
|
-
* A recent version of `zipinfo` with the `-tlhvz` flags - to see the information about the file
|
11
|
-
* ArchiveUtility on OSX
|
12
|
-
* The Unarchiver on OSX
|
13
|
-
* Built-in Explorer on Windows 7
|
14
|
-
* 7Zip 9.20 on Windows 7
|
15
|
-
* Any other unarchivers you consider necessary
|
16
|
-
* Write down your observations in `test-report.txt` and, when cutting a release, timestamp a copy of that file.
|
data/qa/generate_test_files.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'support'
|
4
|
-
|
5
|
-
build_test 'Two small stored files' do |zip|
|
6
|
-
zip.add_stored_entry(filename: 'text.txt',
|
7
|
-
size: $war_and_peace.bytesize,
|
8
|
-
crc32: $war_and_peace_crc)
|
9
|
-
zip << $war_and_peace
|
10
|
-
|
11
|
-
zip.add_stored_entry(filename: 'image.jpg',
|
12
|
-
size: $image_file.bytesize,
|
13
|
-
crc32: $image_file_crc)
|
14
|
-
zip << $image_file
|
15
|
-
end
|
16
|
-
|
17
|
-
build_test 'Two small stored files and an empty directory' do |zip|
|
18
|
-
zip.add_stored_entry(filename: 'text.txt',
|
19
|
-
size: $war_and_peace.bytesize,
|
20
|
-
crc32: $war_and_peace_crc)
|
21
|
-
zip << $war_and_peace
|
22
|
-
|
23
|
-
zip.add_stored_entry(filename: 'image.jpg',
|
24
|
-
size: $image_file.bytesize,
|
25
|
-
crc32: $image_file_crc)
|
26
|
-
zip << $image_file
|
27
|
-
|
28
|
-
zip.add_empty_directory(dirname: 'Chekov')
|
29
|
-
end
|
30
|
-
|
31
|
-
build_test 'Filename with diacritics' do |zip|
|
32
|
-
zip.add_stored_entry(filename: 'Kungälv.txt',
|
33
|
-
size: $war_and_peace.bytesize,
|
34
|
-
crc32: $war_and_peace_crc)
|
35
|
-
zip << $war_and_peace
|
36
|
-
end
|
37
|
-
|
38
|
-
build_test 'Purely UTF-8 filename' do |zip|
|
39
|
-
zip.add_stored_entry(filename: 'Война и мир.txt',
|
40
|
-
size: $war_and_peace.bytesize,
|
41
|
-
crc32: $war_and_peace_crc)
|
42
|
-
zip << $war_and_peace
|
43
|
-
end
|
44
|
-
|
45
|
-
# The trick of this test is that each file of the 2, on it's own, does _not_ exceed the
|
46
|
-
# size threshold for Zip64. Together, however, they do.
|
47
|
-
build_test 'Two entries larger than the overall Zip64 offset' do |zip|
|
48
|
-
big = generate_big_entry((0xFFFFFFFF / 2) + 1_024)
|
49
|
-
zip.add_stored_entry(filename: 'repeated-A.txt',
|
50
|
-
size: big.size,
|
51
|
-
crc32: big.crc32)
|
52
|
-
big.write_to(zip)
|
53
|
-
|
54
|
-
zip.add_stored_entry(filename: 'repeated-B.txt',
|
55
|
-
size: big.size,
|
56
|
-
crc32: big.crc32)
|
57
|
-
big.write_to(zip)
|
58
|
-
end
|
59
|
-
|
60
|
-
build_test 'One entry that requires Zip64 and a tiny entry following it' do |zip|
|
61
|
-
big = generate_big_entry(0xFFFFFFFF + 2_048)
|
62
|
-
zip.add_stored_entry(filename: 'large-requires-zip64.bin',
|
63
|
-
size: big.size,
|
64
|
-
crc32: big.crc32)
|
65
|
-
big.write_to(zip)
|
66
|
-
|
67
|
-
zip.add_stored_entry(filename: 'tiny-after.txt',
|
68
|
-
size: $war_and_peace.bytesize,
|
69
|
-
crc32: $war_and_peace_crc)
|
70
|
-
zip << $war_and_peace
|
71
|
-
end
|
72
|
-
|
73
|
-
build_test 'One tiny entry followed by second that requires Zip64' do |zip|
|
74
|
-
zip.add_stored_entry(filename: 'tiny-at-start.txt',
|
75
|
-
size: $war_and_peace.bytesize,
|
76
|
-
crc32: $war_and_peace_crc)
|
77
|
-
zip << $war_and_peace
|
78
|
-
|
79
|
-
big = generate_big_entry(0xFFFFFFFF + 2_048)
|
80
|
-
zip.add_stored_entry(filename: 'large-requires-zip64.bin',
|
81
|
-
size: big.size,
|
82
|
-
crc32: big.crc32)
|
83
|
-
big.write_to(zip)
|
84
|
-
end
|
85
|
-
|
86
|
-
build_test 'Two entries both requiring Zip64' do |zip|
|
87
|
-
big = generate_big_entry(0xFFFFFFFF + 2_048)
|
88
|
-
zip.add_stored_entry(filename: 'huge-file-1.bin',
|
89
|
-
size: big.size,
|
90
|
-
crc32: big.crc32)
|
91
|
-
big.write_to(zip)
|
92
|
-
|
93
|
-
zip.add_stored_entry(filename: 'huge-file-2.bin',
|
94
|
-
size: big.size,
|
95
|
-
crc32: big.crc32)
|
96
|
-
big.write_to(zip)
|
97
|
-
end
|
98
|
-
|
99
|
-
build_test 'Two stored entries using data descriptors' do |zip|
|
100
|
-
zip.write_stored_file('stored.1.bin') do |sink|
|
101
|
-
sink << Random.new.bytes(1_024 * 1_024 * 4)
|
102
|
-
end
|
103
|
-
zip.write_stored_file('stored.2.bin') do |sink|
|
104
|
-
sink << Random.new.bytes(1_024 * 1_024 * 3)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
build_test 'One entry deflated using data descriptors' do |zip|
|
109
|
-
big = generate_big_entry(0xFFFFFFFF / 64)
|
110
|
-
zip.write_deflated_file('war-and-peace-repeated-compressed.txt') do |sink|
|
111
|
-
big.write_to(sink)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
build_test 'Two entries larger than the overall Zip64 offset using data descriptors' do |zip|
|
116
|
-
big = generate_big_entry((0xFFFFFFFF / 2) + 1_024)
|
117
|
-
|
118
|
-
zip.write_stored_file('repeated-A.txt') { |sink| big.write_to(sink) }
|
119
|
-
zip.write_stored_file('repeated-B.txt') { |sink| big.write_to(sink) }
|
120
|
-
end
|
121
|
-
|
122
|
-
build_test 'One stored entry larger than Zip64 threshold using data descriptors' do |zip|
|
123
|
-
big = generate_big_entry(0xFFFFFFFF + 64_000)
|
124
|
-
|
125
|
-
zip.write_stored_file('repeated-A.txt') { |sink| big.write_to(sink) }
|
126
|
-
end
|