rubyzip 2.1.0 → 2.2.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/lib/zip.rb +2 -1
- data/lib/zip/constants.rb +52 -0
- data/lib/zip/crypto/decrypted_io.rb +39 -0
- data/lib/zip/decompressor.rb +19 -1
- data/lib/zip/entry.rb +8 -0
- data/lib/zip/errors.rb +1 -0
- data/lib/zip/file.rb +1 -1
- data/lib/zip/inflater.rb +22 -36
- data/lib/zip/input_stream.rb +27 -23
- data/lib/zip/ioextras/abstract_input_stream.rb +6 -0
- data/lib/zip/null_decompressor.rb +1 -9
- data/lib/zip/pass_thru_decompressor.rb +13 -22
- data/lib/zip/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cba65b486ec6325e6623957990539a225398a2b9b665b5814a5c06ba70ea1744
|
4
|
+
data.tar.gz: 37dc716e5d98048e1b0c72165c16deb6a6bfef02556890f783cdc62ff5021f4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45de19fa6e2c549c07830243686d622adb937509a942eeb1412a05ea6d1f4a1bde5d60429446ff64f607f3a55400a38c9ccd2d30380825fb4b6e55618702d802
|
7
|
+
data.tar.gz: 8d22f9bc464d950e9ede9cfc1da1056ba664ede954b93ae12d0af68e1d859600d8cd63ba5768553f3d810a693d38ce912c0c2d0f3b3d130da973c8bd833fb3bc
|
data/lib/zip.rb
CHANGED
@@ -4,6 +4,7 @@ require 'tempfile'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'stringio'
|
6
6
|
require 'zlib'
|
7
|
+
require 'zip/constants'
|
7
8
|
require 'zip/dos_time'
|
8
9
|
require 'zip/ioextras'
|
9
10
|
require 'rbconfig'
|
@@ -21,6 +22,7 @@ require 'zip/null_compressor'
|
|
21
22
|
require 'zip/null_input_stream'
|
22
23
|
require 'zip/pass_thru_compressor'
|
23
24
|
require 'zip/pass_thru_decompressor'
|
25
|
+
require 'zip/crypto/decrypted_io'
|
24
26
|
require 'zip/crypto/encryption'
|
25
27
|
require 'zip/crypto/null_encryption'
|
26
28
|
require 'zip/crypto/traditional_encryption'
|
@@ -28,7 +30,6 @@ require 'zip/inflater'
|
|
28
30
|
require 'zip/deflater'
|
29
31
|
require 'zip/streamable_stream'
|
30
32
|
require 'zip/streamable_directory'
|
31
|
-
require 'zip/constants'
|
32
33
|
require 'zip/errors'
|
33
34
|
|
34
35
|
module Zip
|
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,39 @@
|
|
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
|
+
buffer << produce_input
|
16
|
+
end
|
17
|
+
|
18
|
+
outbuf.replace(buffer.slice!(0...(length || output_buffer.bytesize)))
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def eof
|
24
|
+
buffer.empty? && input_finished?
|
25
|
+
end
|
26
|
+
|
27
|
+
def buffer
|
28
|
+
@buffer ||= ''.dup
|
29
|
+
end
|
30
|
+
|
31
|
+
def input_finished?
|
32
|
+
@io.eof
|
33
|
+
end
|
34
|
+
|
35
|
+
def produce_input
|
36
|
+
@decrypter.decrypt(@io.read(CHUNK_SIZE))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/zip/decompressor.rb
CHANGED
@@ -1,9 +1,27 @@
|
|
1
1
|
module Zip
|
2
2
|
class Decompressor #:nodoc:all
|
3
3
|
CHUNK_SIZE = 32_768
|
4
|
-
|
4
|
+
|
5
|
+
def self.decompressor_classes
|
6
|
+
@decompressor_classes ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.register(compression_method, decompressor_class)
|
10
|
+
decompressor_classes[compression_method] = decompressor_class
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find_by_compression_method(compression_method)
|
14
|
+
decompressor_classes[compression_method]
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :input_stream
|
18
|
+
attr_reader :decompressed_size
|
19
|
+
|
20
|
+
def initialize(input_stream, decompressed_size = nil)
|
5
21
|
super()
|
22
|
+
|
6
23
|
@input_stream = input_stream
|
24
|
+
@decompressed_size = decompressed_size
|
7
25
|
end
|
8
26
|
end
|
9
27
|
end
|
data/lib/zip/entry.rb
CHANGED
@@ -72,6 +72,14 @@ module Zip
|
|
72
72
|
@extra = ::Zip::ExtraField.new(@extra.to_s) unless @extra.is_a?(::Zip::ExtraField)
|
73
73
|
end
|
74
74
|
|
75
|
+
def encrypted?
|
76
|
+
gp_flags & 1 == 1
|
77
|
+
end
|
78
|
+
|
79
|
+
def incomplete?
|
80
|
+
gp_flags & 8 == 8
|
81
|
+
end
|
82
|
+
|
75
83
|
def time
|
76
84
|
if @extra['UniversalTime']
|
77
85
|
@extra['UniversalTime'].mtime
|
data/lib/zip/errors.rb
CHANGED
data/lib/zip/file.rb
CHANGED
data/lib/zip/inflater.rb
CHANGED
@@ -1,64 +1,50 @@
|
|
1
1
|
module Zip
|
2
2
|
class Inflater < Decompressor #:nodoc:all
|
3
|
-
def initialize(
|
4
|
-
super
|
5
|
-
@zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
6
|
-
@output_buffer = ''.dup
|
7
|
-
@has_returned_empty_string = false
|
8
|
-
@decrypter = decrypter
|
9
|
-
end
|
3
|
+
def initialize(*args)
|
4
|
+
super
|
10
5
|
|
11
|
-
|
12
|
-
|
13
|
-
while readEverything || @output_buffer.bytesize < number_of_bytes
|
14
|
-
break if internal_input_finished?
|
15
|
-
@output_buffer << internal_produce_input(buf)
|
16
|
-
end
|
17
|
-
return value_when_finished if @output_buffer.bytesize == 0 && input_finished?
|
18
|
-
end_index = number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes
|
19
|
-
@output_buffer.slice!(0...end_index)
|
6
|
+
@buffer = ''.dup
|
7
|
+
@zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
20
8
|
end
|
21
9
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
+
@buffer << produce_input
|
27
16
|
end
|
17
|
+
|
18
|
+
outbuf.replace(@buffer.slice!(0...(length || @buffer.bytesize)))
|
28
19
|
end
|
29
20
|
|
30
|
-
|
31
|
-
|
32
|
-
def input_finished?
|
33
|
-
@output_buffer.empty? && internal_input_finished?
|
21
|
+
def eof
|
22
|
+
@buffer.empty? && input_finished?
|
34
23
|
end
|
35
24
|
|
36
|
-
|
37
|
-
alias :eof? input_finished?
|
25
|
+
alias_method :eof?, :eof
|
38
26
|
|
39
27
|
private
|
40
28
|
|
41
|
-
def
|
29
|
+
def produce_input
|
42
30
|
retried = 0
|
43
31
|
begin
|
44
|
-
@zlib_inflater.inflate(
|
32
|
+
@zlib_inflater.inflate(input_stream.read(Decompressor::CHUNK_SIZE))
|
45
33
|
rescue Zlib::BufError
|
46
34
|
raise if retried >= 5 # how many times should we retry?
|
47
35
|
retried += 1
|
48
36
|
retry
|
49
37
|
end
|
38
|
+
rescue Zlib::Error
|
39
|
+
raise(::Zip::DecompressionError, 'zlib error while inflating')
|
50
40
|
end
|
51
41
|
|
52
|
-
def
|
42
|
+
def input_finished?
|
53
43
|
@zlib_inflater.finished?
|
54
44
|
end
|
55
|
-
|
56
|
-
def value_when_finished # mimic behaviour of ruby File object.
|
57
|
-
return if @has_returned_empty_string
|
58
|
-
@has_returned_empty_string = true
|
59
|
-
''
|
60
|
-
end
|
61
45
|
end
|
46
|
+
|
47
|
+
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_DEFLATE, ::Zip::Inflater)
|
62
48
|
end
|
63
49
|
|
64
50
|
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
data/lib/zip/input_stream.rb
CHANGED
@@ -39,6 +39,8 @@ module Zip
|
|
39
39
|
# class.
|
40
40
|
|
41
41
|
class InputStream
|
42
|
+
CHUNK_SIZE = 32_768
|
43
|
+
|
42
44
|
include ::Zip::IOExtras::AbstractInputStream
|
43
45
|
|
44
46
|
# Opens the indicated zip file. An exception is thrown
|
@@ -78,16 +80,10 @@ module Zip
|
|
78
80
|
end
|
79
81
|
|
80
82
|
# Modeled after IO.sysread
|
81
|
-
def sysread(
|
82
|
-
@decompressor.
|
83
|
-
end
|
84
|
-
|
85
|
-
def eof
|
86
|
-
@output_buffer.empty? && @decompressor.eof
|
83
|
+
def sysread(length = nil, outbuf = '')
|
84
|
+
@decompressor.read(length, outbuf)
|
87
85
|
end
|
88
86
|
|
89
|
-
alias :eof? eof
|
90
|
-
|
91
87
|
class << self
|
92
88
|
# Same as #initialize but if a block is passed the opened
|
93
89
|
# stream is passed to the block and closed when the block
|
@@ -124,46 +120,54 @@ module Zip
|
|
124
120
|
|
125
121
|
def open_entry
|
126
122
|
@current_entry = ::Zip::Entry.read_local_entry(@archive_io)
|
127
|
-
if @current_entry && @current_entry.
|
123
|
+
if @current_entry && @current_entry.encrypted? && @decrypter.is_a?(NullEncrypter)
|
128
124
|
raise Error, 'password required to decode zip file'
|
129
125
|
end
|
130
|
-
if @current_entry && @current_entry.
|
126
|
+
if @current_entry && @current_entry.incomplete? && @current_entry.crc == 0 \
|
131
127
|
&& @current_entry.compressed_size == 0 \
|
132
128
|
&& @current_entry.size == 0 && !@complete_entry
|
133
129
|
raise GPFBit3Error,
|
134
130
|
'General purpose flag Bit 3 is set so not possible to get proper info from local header.' \
|
135
131
|
'Please use ::Zip::File instead of ::Zip::InputStream'
|
136
132
|
end
|
133
|
+
@decrypted_io = get_decrypted_io
|
137
134
|
@decompressor = get_decompressor
|
138
135
|
flush
|
139
136
|
@current_entry
|
140
137
|
end
|
141
138
|
|
139
|
+
def get_decrypted_io
|
140
|
+
header = @archive_io.read(@decrypter.header_bytesize)
|
141
|
+
@decrypter.reset!(header)
|
142
|
+
|
143
|
+
::Zip::DecryptedIo.new(@archive_io, @decrypter)
|
144
|
+
end
|
145
|
+
|
142
146
|
def get_decompressor
|
143
|
-
if @current_entry.nil?
|
144
|
-
|
145
|
-
|
146
|
-
if @current_entry.
|
147
|
-
|
147
|
+
return ::Zip::NullDecompressor if @current_entry.nil?
|
148
|
+
|
149
|
+
decompressed_size =
|
150
|
+
if @current_entry.incomplete? && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry
|
151
|
+
@complete_entry.size
|
148
152
|
else
|
149
|
-
|
153
|
+
@current_entry.size
|
150
154
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
::Zip::Inflater.new(@archive_io, @decrypter)
|
155
|
-
else
|
155
|
+
|
156
|
+
decompressor_class = ::Zip::Decompressor.find_by_compression_method(@current_entry.compression_method)
|
157
|
+
if decompressor_class.nil?
|
156
158
|
raise ::Zip::CompressionMethodError,
|
157
159
|
"Unsupported compression method #{@current_entry.compression_method}"
|
158
160
|
end
|
161
|
+
|
162
|
+
decompressor_class.new(@decrypted_io, decompressed_size)
|
159
163
|
end
|
160
164
|
|
161
165
|
def produce_input
|
162
|
-
@decompressor.
|
166
|
+
@decompressor.read(CHUNK_SIZE)
|
163
167
|
end
|
164
168
|
|
165
169
|
def input_finished?
|
166
|
-
@decompressor.
|
170
|
+
@decompressor.eof
|
167
171
|
end
|
168
172
|
end
|
169
173
|
end
|
@@ -2,18 +2,10 @@ module Zip
|
|
2
2
|
module NullDecompressor #:nodoc:all
|
3
3
|
module_function
|
4
4
|
|
5
|
-
def
|
5
|
+
def read(_length = nil, _outbuf = nil)
|
6
6
|
nil
|
7
7
|
end
|
8
8
|
|
9
|
-
def produce_input
|
10
|
-
nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def input_finished?
|
14
|
-
true
|
15
|
-
end
|
16
|
-
|
17
9
|
def eof
|
18
10
|
true
|
19
11
|
end
|
@@ -1,38 +1,29 @@
|
|
1
1
|
module Zip
|
2
2
|
class PassThruDecompressor < Decompressor #:nodoc:all
|
3
|
-
def initialize(
|
4
|
-
super
|
5
|
-
@chars_to_read = chars_to_read
|
3
|
+
def initialize(*args)
|
4
|
+
super
|
6
5
|
@read_so_far = 0
|
7
|
-
@has_returned_empty_string = false
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
11
|
-
if
|
12
|
-
has_returned_empty_string_val = @has_returned_empty_string
|
13
|
-
@has_returned_empty_string = true
|
14
|
-
return '' unless has_returned_empty_string_val
|
15
|
-
return
|
16
|
-
end
|
8
|
+
def read(length = nil, outbuf = '')
|
9
|
+
return ((length.nil? || length.zero?) ? "" : nil) if eof
|
17
10
|
|
18
|
-
if
|
19
|
-
|
11
|
+
if length.nil? || (@read_so_far + length) > decompressed_size
|
12
|
+
length = decompressed_size - @read_so_far
|
20
13
|
end
|
21
|
-
@read_so_far += number_of_bytes
|
22
|
-
@input_stream.read(number_of_bytes, buf)
|
23
|
-
end
|
24
14
|
|
25
|
-
|
26
|
-
|
15
|
+
@read_so_far += length
|
16
|
+
input_stream.read(length, outbuf)
|
27
17
|
end
|
28
18
|
|
29
|
-
def
|
30
|
-
@read_so_far >=
|
19
|
+
def eof
|
20
|
+
@read_so_far >= decompressed_size
|
31
21
|
end
|
32
22
|
|
33
|
-
|
34
|
-
alias eof? input_finished?
|
23
|
+
alias_method :eof?, :eof
|
35
24
|
end
|
25
|
+
|
26
|
+
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
|
36
27
|
end
|
37
28
|
|
38
29
|
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
data/lib/zip/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyzip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Simonov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-01
|
11
|
+
date: 2020-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- lib/zip/central_directory.rb
|
95
95
|
- lib/zip/compressor.rb
|
96
96
|
- lib/zip/constants.rb
|
97
|
+
- lib/zip/crypto/decrypted_io.rb
|
97
98
|
- lib/zip/crypto/encryption.rb
|
98
99
|
- lib/zip/crypto/null_encryption.rb
|
99
100
|
- lib/zip/crypto/traditional_encryption.rb
|
@@ -139,9 +140,9 @@ licenses:
|
|
139
140
|
- BSD 2-Clause
|
140
141
|
metadata:
|
141
142
|
bug_tracker_uri: https://github.com/rubyzip/rubyzip/issues
|
142
|
-
changelog_uri: https://github.com/rubyzip/rubyzip/blob/v2.
|
143
|
-
documentation_uri: https://www.rubydoc.info/gems/rubyzip/2.
|
144
|
-
source_code_uri: https://github.com/rubyzip/rubyzip/tree/v2.
|
143
|
+
changelog_uri: https://github.com/rubyzip/rubyzip/blob/v2.2.0/Changelog.md
|
144
|
+
documentation_uri: https://www.rubydoc.info/gems/rubyzip/2.2.0
|
145
|
+
source_code_uri: https://github.com/rubyzip/rubyzip/tree/v2.2.0
|
145
146
|
wiki_uri: https://github.com/rubyzip/rubyzip/wiki
|
146
147
|
post_install_message:
|
147
148
|
rdoc_options: []
|