rubyzip 1.2.2 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +64 -23
- data/Rakefile +3 -0
- data/lib/zip.rb +6 -3
- data/lib/zip/central_directory.rb +9 -5
- data/lib/zip/constants.rb +52 -0
- data/lib/zip/crypto/decrypted_io.rb +40 -0
- data/lib/zip/crypto/traditional_encryption.rb +9 -9
- data/lib/zip/decompressor.rb +19 -1
- data/lib/zip/dos_time.rb +12 -7
- data/lib/zip/entry.rb +69 -37
- data/lib/zip/entry_set.rb +2 -0
- data/lib/zip/errors.rb +2 -0
- data/lib/zip/extra_field.rb +11 -9
- data/lib/zip/extra_field/generic.rb +10 -9
- data/lib/zip/extra_field/ntfs.rb +4 -0
- data/lib/zip/extra_field/old_unix.rb +3 -1
- data/lib/zip/extra_field/universal_time.rb +42 -12
- data/lib/zip/extra_field/unix.rb +3 -1
- data/lib/zip/extra_field/zip64.rb +4 -2
- data/lib/zip/file.rb +115 -70
- data/lib/zip/filesystem.rb +193 -177
- data/lib/zip/inflater.rb +24 -36
- data/lib/zip/input_stream.rb +33 -26
- data/lib/zip/ioextras.rb +1 -1
- data/lib/zip/ioextras/abstract_input_stream.rb +19 -8
- data/lib/zip/ioextras/abstract_output_stream.rb +1 -1
- data/lib/zip/null_decompressor.rb +1 -9
- data/lib/zip/output_stream.rb +14 -5
- data/lib/zip/pass_thru_compressor.rb +2 -2
- data/lib/zip/pass_thru_decompressor.rb +13 -22
- data/lib/zip/streamable_directory.rb +3 -3
- data/lib/zip/streamable_stream.rb +6 -10
- data/lib/zip/version.rb +1 -1
- data/samples/example.rb +2 -2
- data/samples/example_filesystem.rb +1 -1
- data/samples/gtk_ruby_zip.rb +19 -19
- data/samples/qtzip.rb +6 -6
- data/samples/write_simple.rb +2 -4
- data/samples/zipfind.rb +23 -22
- metadata +32 -167
- data/test/basic_zip_file_test.rb +0 -60
- data/test/case_sensitivity_test.rb +0 -69
- data/test/central_directory_entry_test.rb +0 -69
- data/test/central_directory_test.rb +0 -100
- data/test/crypto/null_encryption_test.rb +0 -57
- data/test/crypto/traditional_encryption_test.rb +0 -80
- data/test/data/WarnInvalidDate.zip +0 -0
- data/test/data/file1.txt +0 -46
- data/test/data/file1.txt.deflatedData +0 -0
- data/test/data/file2.txt +0 -1504
- data/test/data/globTest.zip +0 -0
- data/test/data/globTest/foo.txt +0 -0
- data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
- data/test/data/globTest/food.txt +0 -0
- data/test/data/gpbit3stored.zip +0 -0
- data/test/data/mimetype +0 -1
- data/test/data/notzippedruby.rb +0 -7
- data/test/data/ntfs.zip +0 -0
- data/test/data/oddExtraField.zip +0 -0
- data/test/data/path_traversal/Makefile +0 -10
- data/test/data/path_traversal/jwilk/README.md +0 -5
- data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
- data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
- data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
- data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
- data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
- data/test/data/path_traversal/jwilk/relative0.zip +0 -0
- data/test/data/path_traversal/jwilk/relative2.zip +0 -0
- data/test/data/path_traversal/jwilk/symlink.zip +0 -0
- data/test/data/path_traversal/relative1.zip +0 -0
- data/test/data/path_traversal/tuzovakaoff/README.md +0 -3
- data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
- data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
- data/test/data/rubycode.zip +0 -0
- data/test/data/rubycode2.zip +0 -0
- data/test/data/test.xls +0 -0
- data/test/data/testDirectory.bin +0 -0
- data/test/data/zip64-sample.zip +0 -0
- data/test/data/zipWithDirs.zip +0 -0
- data/test/data/zipWithEncryption.zip +0 -0
- data/test/deflater_test.rb +0 -65
- data/test/encryption_test.rb +0 -42
- data/test/entry_set_test.rb +0 -163
- data/test/entry_test.rb +0 -154
- data/test/errors_test.rb +0 -35
- data/test/extra_field_test.rb +0 -76
- data/test/file_extract_directory_test.rb +0 -54
- data/test/file_extract_test.rb +0 -83
- data/test/file_permissions_test.rb +0 -65
- data/test/file_split_test.rb +0 -57
- data/test/file_test.rb +0 -601
- data/test/filesystem/dir_iterator_test.rb +0 -58
- data/test/filesystem/directory_test.rb +0 -139
- data/test/filesystem/file_mutating_test.rb +0 -87
- data/test/filesystem/file_nonmutating_test.rb +0 -508
- data/test/filesystem/file_stat_test.rb +0 -64
- data/test/gentestfiles.rb +0 -126
- data/test/inflater_test.rb +0 -14
- data/test/input_stream_test.rb +0 -182
- data/test/ioextras/abstract_input_stream_test.rb +0 -102
- data/test/ioextras/abstract_output_stream_test.rb +0 -106
- data/test/ioextras/fake_io_test.rb +0 -18
- data/test/local_entry_test.rb +0 -154
- data/test/output_stream_test.rb +0 -128
- data/test/pass_thru_compressor_test.rb +0 -30
- data/test/pass_thru_decompressor_test.rb +0 -14
- data/test/path_traversal_test.rb +0 -134
- data/test/samples/example_recursive_test.rb +0 -37
- data/test/settings_test.rb +0 -95
- data/test/test_helper.rb +0 -234
- data/test/unicode_file_names_and_comments_test.rb +0 -62
- data/test/zip64_full_test.rb +0 -51
- data/test/zip64_support_test.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ffab0e42187d7bbd5b732ff0b9395a6215587a18ce5dd9d64da46d1c628a69c
|
4
|
+
data.tar.gz: 3032ae5d4f62644c1a19d5de25d515844ecb8da0f59c774fcaa6b16904f496b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 218f77b0c4ae423f2baed702bf56bb598e2c3d22a01fc9af8c2fa33432580e2706a820474fa1222480370517a9f28bda692a2f296d89620459d9c6239fcfff37
|
7
|
+
data.tar.gz: a4ffa820bb2272b07bd918827d03751261f87d694966ef6c88f74f4ec569c94b0420c9288a92e5370653d00790478bdd85d3e89a9ef42ccd94834facb622c336
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# rubyzip
|
2
|
+
|
2
3
|
[![Gem Version](https://badge.fury.io/rb/rubyzip.svg)](http://badge.fury.io/rb/rubyzip)
|
3
4
|
[![Build Status](https://secure.travis-ci.org/rubyzip/rubyzip.svg)](http://travis-ci.org/rubyzip/rubyzip)
|
4
5
|
[![Code Climate](https://codeclimate.com/github/rubyzip/rubyzip.svg)](https://codeclimate.com/github/rubyzip/rubyzip)
|
@@ -19,9 +20,10 @@ gem 'zip-zip' # will load compatibility for old rubyzip API.
|
|
19
20
|
|
20
21
|
## Requirements
|
21
22
|
|
22
|
-
|
23
|
+
- Ruby 2.4 or greater (for rubyzip 2.0; use 1.x for older rubies)
|
23
24
|
|
24
25
|
## Installation
|
26
|
+
|
25
27
|
Rubyzip is available on RubyGems:
|
26
28
|
|
27
29
|
```
|
@@ -59,7 +61,8 @@ end
|
|
59
61
|
```
|
60
62
|
|
61
63
|
### Zipping a directory recursively
|
62
|
-
|
64
|
+
|
65
|
+
Copy from [here](https://github.com/rubyzip/rubyzip/blob/9d891f7353e66052283562d3e252fe380bb4b199/samples/example_recursive.rb)
|
63
66
|
|
64
67
|
```ruby
|
65
68
|
require 'zip'
|
@@ -83,7 +86,7 @@ class ZipFileGenerator
|
|
83
86
|
|
84
87
|
# Zip the input directory.
|
85
88
|
def write
|
86
|
-
entries = Dir.entries(@input_dir) - %w
|
89
|
+
entries = Dir.entries(@input_dir) - %w[. ..]
|
87
90
|
|
88
91
|
::Zip::File.open(@output_file, ::Zip::File::CREATE) do |zipfile|
|
89
92
|
write_entries entries, '', zipfile
|
@@ -97,7 +100,6 @@ class ZipFileGenerator
|
|
97
100
|
entries.each do |e|
|
98
101
|
zipfile_path = path == '' ? e : File.join(path, e)
|
99
102
|
disk_file_path = File.join(@input_dir, zipfile_path)
|
100
|
-
puts "Deflating #{disk_file_path}"
|
101
103
|
|
102
104
|
if File.directory? disk_file_path
|
103
105
|
recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
|
@@ -109,14 +111,12 @@ class ZipFileGenerator
|
|
109
111
|
|
110
112
|
def recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
|
111
113
|
zipfile.mkdir zipfile_path
|
112
|
-
subdir = Dir.entries(disk_file_path) - %w
|
114
|
+
subdir = Dir.entries(disk_file_path) - %w[. ..]
|
113
115
|
write_entries subdir, zipfile_path, zipfile
|
114
116
|
end
|
115
117
|
|
116
118
|
def put_into_archive(disk_file_path, zipfile, zipfile_path)
|
117
|
-
zipfile.
|
118
|
-
f.write(File.open(disk_file_path, 'rb').read)
|
119
|
-
end
|
119
|
+
zipfile.add(zipfile_path, disk_file_path)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
```
|
@@ -152,12 +152,15 @@ When modifying a zip archive the file permissions of the archive are preserved.
|
|
152
152
|
### Reading a Zip file
|
153
153
|
|
154
154
|
```ruby
|
155
|
+
MAX_SIZE = 1024**2 # 1MiB (but of course you can increase this)
|
155
156
|
Zip::File.open('foo.zip') do |zip_file|
|
156
157
|
# Handle entries one by one
|
157
158
|
zip_file.each do |entry|
|
158
|
-
# Extract to file/directory/symlink
|
159
159
|
puts "Extracting #{entry.name}"
|
160
|
-
entry.
|
160
|
+
raise 'File too large when extracted' if entry.size > MAX_SIZE
|
161
|
+
|
162
|
+
# Extract to file or directory based on name in the archive
|
163
|
+
entry.extract
|
161
164
|
|
162
165
|
# Read into memory
|
163
166
|
content = entry.get_input_stream.read
|
@@ -165,6 +168,7 @@ Zip::File.open('foo.zip') do |zip_file|
|
|
165
168
|
|
166
169
|
# Find specific entry
|
167
170
|
entry = zip_file.glob('*.csv').first
|
171
|
+
raise 'File too large when extracted' if entry.size > MAX_SIZE
|
168
172
|
puts entry.get_input_stream.read
|
169
173
|
end
|
170
174
|
```
|
@@ -177,7 +181,6 @@ But there is one exception when it is not working - General Purpose Flag Bit 3.
|
|
177
181
|
|
178
182
|
> If bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written. The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure (optionally preceded by a 4-byte signature) immediately after the compressed data
|
179
183
|
|
180
|
-
|
181
184
|
If `::Zip::InputStream` finds such entry in the zip archive it will raise an exception.
|
182
185
|
|
183
186
|
### Password Protection (Experimental)
|
@@ -220,7 +223,9 @@ File.open(new_path, "wb") {|f| f.write(buffer.string) }
|
|
220
223
|
|
221
224
|
## Configuration
|
222
225
|
|
223
|
-
|
226
|
+
### Existing Files
|
227
|
+
|
228
|
+
By default, rubyzip will not overwrite files if they already exist inside of the extracted path. To change this behavior, you may specify a configuration option like so:
|
224
229
|
|
225
230
|
```ruby
|
226
231
|
Zip.on_exists_proc = true
|
@@ -234,32 +239,76 @@ Additionally, if you want to configure rubyzip to overwrite existing files while
|
|
234
239
|
Zip.continue_on_exists_proc = true
|
235
240
|
```
|
236
241
|
|
242
|
+
### Non-ASCII Names
|
243
|
+
|
237
244
|
If you want to store non-english names and want to open them on Windows(pre 7) you need to set this option:
|
238
245
|
|
239
246
|
```ruby
|
240
247
|
Zip.unicode_names = true
|
241
248
|
```
|
242
249
|
|
250
|
+
Sometimes file names inside zip contain non-ASCII characters. If you can assume which encoding was used for such names and want to be able to find such entries using `find_entry` then you can force assumed encoding like so:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
Zip.force_entry_names_encoding = 'UTF-8'
|
254
|
+
```
|
255
|
+
|
256
|
+
Allowed encoding names are the same as accepted by `String#force_encoding`
|
257
|
+
|
258
|
+
### Date Validation
|
259
|
+
|
243
260
|
Some zip files might have an invalid date format, which will raise a warning. You can hide this warning with the following setting:
|
244
261
|
|
245
262
|
```ruby
|
246
263
|
Zip.warn_invalid_date = false
|
247
264
|
```
|
248
265
|
|
266
|
+
### Size Validation
|
267
|
+
|
268
|
+
By default (in rubyzip >= 2.0), rubyzip's `extract` method checks that an entry's reported uncompressed size is not (significantly) smaller than its actual size. This is to help you protect your application against [zip bombs](https://en.wikipedia.org/wiki/Zip_bomb). Before `extract`ing an entry, you should check that its size is in the range you expect. For example, if your application supports processing up to 100 files at once, each up to 10MiB, your zip extraction code might look like:
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
MAX_FILE_SIZE = 10 * 1024**2 # 10MiB
|
272
|
+
MAX_FILES = 100
|
273
|
+
Zip::File.open('foo.zip') do |zip_file|
|
274
|
+
num_files = 0
|
275
|
+
zip_file.each do |entry|
|
276
|
+
num_files += 1 if entry.file?
|
277
|
+
raise 'Too many extracted files' if num_files > MAX_FILES
|
278
|
+
raise 'File too large when extracted' if entry.size > MAX_FILE_SIZE
|
279
|
+
entry.extract
|
280
|
+
end
|
281
|
+
end
|
282
|
+
```
|
283
|
+
|
284
|
+
If you need to extract zip files that report incorrect uncompressed sizes and you really trust them not too be too large, you can disable this setting with
|
285
|
+
```ruby
|
286
|
+
Zip.validate_entry_sizes = false
|
287
|
+
```
|
288
|
+
|
289
|
+
Note that if you use the lower level `Zip::InputStream` interface, `rubyzip` does *not* check the entry `size`s. In this case, the caller is responsible for making sure it does not read more data than expected from the input stream.
|
290
|
+
|
291
|
+
### Default Compression
|
292
|
+
|
249
293
|
You can set the default compression level like so:
|
250
294
|
|
251
295
|
```ruby
|
252
296
|
Zip.default_compression = Zlib::DEFAULT_COMPRESSION
|
253
297
|
```
|
298
|
+
|
254
299
|
It defaults to `Zlib::DEFAULT_COMPRESSION`. Possible values are `Zlib::BEST_COMPRESSION`, `Zlib::DEFAULT_COMPRESSION` and `Zlib::NO_COMPRESSION`
|
255
300
|
|
256
|
-
|
301
|
+
### Zip64 Support
|
302
|
+
|
303
|
+
By default, Zip64 support is disabled for writing. To enable it do this:
|
257
304
|
|
258
305
|
```ruby
|
259
|
-
Zip.
|
306
|
+
Zip.write_zip64_support = true
|
260
307
|
```
|
261
308
|
|
262
|
-
|
309
|
+
_NOTE_: If you will enable Zip64 writing then you will need zip extractor with Zip64 support to extract archive.
|
310
|
+
|
311
|
+
### Block Form
|
263
312
|
|
264
313
|
You can set multiple settings at the same time by using a block:
|
265
314
|
|
@@ -272,14 +321,6 @@ You can set multiple settings at the same time by using a block:
|
|
272
321
|
end
|
273
322
|
```
|
274
323
|
|
275
|
-
By default, Zip64 support is disabled for writing. To enable it do this:
|
276
|
-
|
277
|
-
```ruby
|
278
|
-
Zip.write_zip64_support = true
|
279
|
-
```
|
280
|
-
|
281
|
-
_NOTE_: If you will enable Zip64 writing then you will need zip extractor with Zip64 support to extract archive.
|
282
|
-
|
283
324
|
## Developing
|
284
325
|
|
285
326
|
To run the test you need to do this:
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rake/testtask'
|
3
|
+
require 'rubocop/rake_task'
|
3
4
|
|
4
5
|
task default: :test
|
5
6
|
|
@@ -10,6 +11,8 @@ Rake::TestTask.new(:test) do |test|
|
|
10
11
|
test.verbose = true
|
11
12
|
end
|
12
13
|
|
14
|
+
RuboCop::RakeTask.new
|
15
|
+
|
13
16
|
# Rake::TestTask.new(:zip64_full_test) do |test|
|
14
17
|
# test.libs << File.join(File.dirname(__FILE__), 'lib')
|
15
18
|
# test.libs << File.join(File.dirname(__FILE__), 'test')
|
data/lib/zip.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
require 'English'
|
1
2
|
require 'delegate'
|
2
3
|
require 'singleton'
|
3
4
|
require 'tempfile'
|
4
|
-
require 'tmpdir'
|
5
5
|
require 'fileutils'
|
6
6
|
require 'stringio'
|
7
7
|
require 'zlib'
|
8
|
+
require 'zip/constants'
|
8
9
|
require 'zip/dos_time'
|
9
10
|
require 'zip/ioextras'
|
10
11
|
require 'rbconfig'
|
@@ -22,6 +23,7 @@ require 'zip/null_compressor'
|
|
22
23
|
require 'zip/null_input_stream'
|
23
24
|
require 'zip/pass_thru_compressor'
|
24
25
|
require 'zip/pass_thru_decompressor'
|
26
|
+
require 'zip/crypto/decrypted_io'
|
25
27
|
require 'zip/crypto/encryption'
|
26
28
|
require 'zip/crypto/null_encryption'
|
27
29
|
require 'zip/crypto/traditional_encryption'
|
@@ -29,7 +31,6 @@ require 'zip/inflater'
|
|
29
31
|
require 'zip/deflater'
|
30
32
|
require 'zip/streamable_stream'
|
31
33
|
require 'zip/streamable_directory'
|
32
|
-
require 'zip/constants'
|
33
34
|
require 'zip/errors'
|
34
35
|
|
35
36
|
module Zip
|
@@ -42,7 +43,8 @@ module Zip
|
|
42
43
|
:write_zip64_support,
|
43
44
|
:warn_invalid_date,
|
44
45
|
:case_insensitive_match,
|
45
|
-
:force_entry_names_encoding
|
46
|
+
:force_entry_names_encoding,
|
47
|
+
:validate_entry_sizes
|
46
48
|
|
47
49
|
def reset!
|
48
50
|
@_ran_once = false
|
@@ -54,6 +56,7 @@ module Zip
|
|
54
56
|
@write_zip64_support = false
|
55
57
|
@warn_invalid_date = true
|
56
58
|
@case_insensitive_match = false
|
59
|
+
@validate_entry_sizes = true
|
57
60
|
end
|
58
61
|
|
59
62
|
def setup
|
@@ -65,7 +65,7 @@ module Zip
|
|
65
65
|
@entry_set ? @entry_set.size : 0, # number of entries on this disk
|
66
66
|
@entry_set ? @entry_set.size : 0, # number of entries total
|
67
67
|
cdir_size, # size of central directory
|
68
|
-
offset
|
68
|
+
offset # offset of start of central directory in its disk
|
69
69
|
]
|
70
70
|
io << tmp.pack('VQ<vvVVQ<Q<Q<Q<')
|
71
71
|
end
|
@@ -141,6 +141,7 @@ module Zip
|
|
141
141
|
def get_e_o_c_d(buf) #:nodoc:
|
142
142
|
sig_index = buf.rindex([END_OF_CDS].pack('V'))
|
143
143
|
raise Error, 'Zip end of central directory signature not found' unless sig_index
|
144
|
+
|
144
145
|
buf = buf.slice!((sig_index + 4)..(buf.bytesize))
|
145
146
|
|
146
147
|
def buf.read(count)
|
@@ -166,8 +167,10 @@ module Zip
|
|
166
167
|
def get_64_e_o_c_d(buf) #:nodoc:
|
167
168
|
zip_64_start = buf.rindex([ZIP64_END_OF_CDS].pack('V'))
|
168
169
|
raise Error, 'Zip64 end of central directory signature not found' unless zip_64_start
|
170
|
+
|
169
171
|
zip_64_locator = buf.rindex([ZIP64_EOCD_LOCATOR].pack('V'))
|
170
172
|
raise Error, 'Zip64 end of central directory signature locator not found' unless zip_64_locator
|
173
|
+
|
171
174
|
buf = buf.slice!((zip_64_start + 4)..zip_64_locator)
|
172
175
|
|
173
176
|
def buf.read(count)
|
@@ -178,8 +181,8 @@ module Zip
|
|
178
181
|
end
|
179
182
|
|
180
183
|
# For iterating over the entries.
|
181
|
-
def each(&
|
182
|
-
@entry_set.each(&
|
184
|
+
def each(&a_proc)
|
185
|
+
@entry_set.each(&a_proc)
|
183
186
|
end
|
184
187
|
|
185
188
|
# Returns the number of entries in the central directory (and
|
@@ -191,13 +194,14 @@ module Zip
|
|
191
194
|
def self.read_from_stream(io) #:nodoc:
|
192
195
|
cdir = new
|
193
196
|
cdir.read_from_stream(io)
|
194
|
-
|
197
|
+
cdir
|
195
198
|
rescue Error
|
196
|
-
|
199
|
+
nil
|
197
200
|
end
|
198
201
|
|
199
202
|
def ==(other) #:nodoc:
|
200
203
|
return false unless other.kind_of?(CentralDirectory)
|
204
|
+
|
201
205
|
@entry_set.entries.sort == other.entries.sort && comment == other.comment
|
202
206
|
end
|
203
207
|
end
|
data/lib/zip/constants.rb
CHANGED
@@ -60,4 +60,56 @@ module Zip
|
|
60
60
|
FSTYPE_MAC_OSX => 'Mac OS/X (Darwin)'.freeze,
|
61
61
|
FSTYPE_ATHEOS => 'AtheOS'.freeze
|
62
62
|
}.freeze
|
63
|
+
|
64
|
+
COMPRESSION_METHOD_STORE = 0
|
65
|
+
COMPRESSION_METHOD_SHRINK = 1
|
66
|
+
COMPRESSION_METHOD_REDUCE_1 = 2
|
67
|
+
COMPRESSION_METHOD_REDUCE_2 = 3
|
68
|
+
COMPRESSION_METHOD_REDUCE_3 = 4
|
69
|
+
COMPRESSION_METHOD_REDUCE_4 = 5
|
70
|
+
COMPRESSION_METHOD_IMPLODE = 6
|
71
|
+
# RESERVED = 7
|
72
|
+
COMPRESSION_METHOD_DEFLATE = 8
|
73
|
+
COMPRESSION_METHOD_DEFLATE_64 = 9
|
74
|
+
COMPRESSION_METHOD_PKWARE_DCLI = 10
|
75
|
+
# RESERVED = 11
|
76
|
+
COMPRESSION_METHOD_BZIP2 = 12
|
77
|
+
# RESERVED = 13
|
78
|
+
COMPRESSION_METHOD_LZMA = 14
|
79
|
+
# RESERVED = 15
|
80
|
+
COMPRESSION_METHOD_IBM_CMPSC = 16
|
81
|
+
# RESERVED = 17
|
82
|
+
COMPRESSION_METHOD_IBM_TERSE = 18
|
83
|
+
COMPRESSION_METHOD_IBM_LZ77 = 19
|
84
|
+
COMPRESSION_METHOD_JPEG = 96
|
85
|
+
COMPRESSION_METHOD_WAVPACK = 97
|
86
|
+
COMPRESSION_METHOD_PPMD = 98
|
87
|
+
COMPRESSION_METHOD_AES = 99
|
88
|
+
|
89
|
+
COMPRESSION_METHODS = {
|
90
|
+
COMPRESSION_METHOD_STORE => 'Store (no compression)',
|
91
|
+
COMPRESSION_METHOD_SHRINK => 'Shrink',
|
92
|
+
COMPRESSION_METHOD_REDUCE_1 => 'Reduce with compression factor 1',
|
93
|
+
COMPRESSION_METHOD_REDUCE_2 => 'Reduce with compression factor 2',
|
94
|
+
COMPRESSION_METHOD_REDUCE_3 => 'Reduce with compression factor 3',
|
95
|
+
COMPRESSION_METHOD_REDUCE_4 => 'Reduce with compression factor 4',
|
96
|
+
COMPRESSION_METHOD_IMPLODE => 'Implode',
|
97
|
+
# RESERVED = 7
|
98
|
+
COMPRESSION_METHOD_DEFLATE => 'Deflate',
|
99
|
+
COMPRESSION_METHOD_DEFLATE_64 => 'Deflate64(tm)',
|
100
|
+
COMPRESSION_METHOD_PKWARE_DCLI => 'PKWARE Data Compression Library Imploding (old IBM TERSE)',
|
101
|
+
# RESERVED = 11
|
102
|
+
COMPRESSION_METHOD_BZIP2 => 'BZIP2',
|
103
|
+
# RESERVED = 13
|
104
|
+
COMPRESSION_METHOD_LZMA => 'LZMA',
|
105
|
+
# RESERVED = 15
|
106
|
+
COMPRESSION_METHOD_IBM_CMPSC => 'IBM z/OS CMPSC Compression',
|
107
|
+
# RESERVED = 17
|
108
|
+
COMPRESSION_METHOD_IBM_TERSE => 'IBM TERSE (new)',
|
109
|
+
COMPRESSION_METHOD_IBM_LZ77 => 'IBM LZ77 z Architecture (PFS)',
|
110
|
+
COMPRESSION_METHOD_JPEG => 'JPEG variant',
|
111
|
+
COMPRESSION_METHOD_WAVPACK => 'WavPack compressed data',
|
112
|
+
COMPRESSION_METHOD_PPMD => 'PPMd version I, Rev 1',
|
113
|
+
COMPRESSION_METHOD_AES => 'AES encryption'
|
114
|
+
}.freeze
|
63
115
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Zip
|
2
|
+
class DecryptedIo #:nodoc:all
|
3
|
+
CHUNK_SIZE = 32_768
|
4
|
+
|
5
|
+
def initialize(io, decrypter)
|
6
|
+
@io = io
|
7
|
+
@decrypter = decrypter
|
8
|
+
end
|
9
|
+
|
10
|
+
def read(length = nil, outbuf = +'')
|
11
|
+
return (length.nil? || length.zero? ? '' : nil) if eof
|
12
|
+
|
13
|
+
while length.nil? || (buffer.bytesize < length)
|
14
|
+
break if input_finished?
|
15
|
+
|
16
|
+
buffer << produce_input
|
17
|
+
end
|
18
|
+
|
19
|
+
outbuf.replace(buffer.slice!(0...(length || output_buffer.bytesize)))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def eof
|
25
|
+
buffer.empty? && input_finished?
|
26
|
+
end
|
27
|
+
|
28
|
+
def buffer
|
29
|
+
@buffer ||= +''
|
30
|
+
end
|
31
|
+
|
32
|
+
def input_finished?
|
33
|
+
@io.eof
|
34
|
+
end
|
35
|
+
|
36
|
+
def produce_input
|
37
|
+
@decrypter.decrypt(@io.read(CHUNK_SIZE))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -24,8 +24,8 @@ module Zip
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def update_keys(
|
28
|
-
@key0 = ~Zlib.crc32(
|
27
|
+
def update_keys(num)
|
28
|
+
@key0 = ~Zlib.crc32(num, ~@key0)
|
29
29
|
@key1 = ((@key1 + (@key0 & 0xff)) * 134_775_813 + 1) & 0xffffffff
|
30
30
|
@key2 = ~Zlib.crc32((@key1 >> 24).chr, ~@key2)
|
31
31
|
end
|
@@ -63,10 +63,10 @@ module Zip
|
|
63
63
|
|
64
64
|
private
|
65
65
|
|
66
|
-
def encode(
|
66
|
+
def encode(num)
|
67
67
|
t = decrypt_byte
|
68
|
-
update_keys(
|
69
|
-
t ^
|
68
|
+
update_keys(num.chr)
|
69
|
+
t ^ num
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -86,10 +86,10 @@ module Zip
|
|
86
86
|
|
87
87
|
private
|
88
88
|
|
89
|
-
def decode(
|
90
|
-
|
91
|
-
update_keys(
|
92
|
-
|
89
|
+
def decode(num)
|
90
|
+
num ^= decrypt_byte
|
91
|
+
update_keys(num.chr)
|
92
|
+
num
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|