rubyzip 2.4.1 → 3.0.0.alpha
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/Changelog.md +368 -0
- data/README.md +112 -37
- data/Rakefile +11 -7
- data/lib/zip/central_directory.rb +164 -118
- data/lib/zip/compressor.rb +3 -1
- data/lib/zip/constants.rb +25 -21
- data/lib/zip/crypto/decrypted_io.rb +3 -1
- data/lib/zip/crypto/encryption.rb +4 -2
- data/lib/zip/crypto/null_encryption.rb +5 -3
- data/lib/zip/crypto/traditional_encryption.rb +5 -3
- data/lib/zip/decompressor.rb +4 -3
- data/lib/zip/deflater.rb +10 -8
- data/lib/zip/dirtyable.rb +32 -0
- data/lib/zip/dos_time.rb +32 -3
- data/lib/zip/entry.rb +262 -198
- data/lib/zip/entry_set.rb +9 -7
- data/lib/zip/errors.rb +115 -16
- data/lib/zip/extra_field/generic.rb +3 -10
- data/lib/zip/extra_field/ntfs.rb +4 -2
- data/lib/zip/extra_field/old_unix.rb +3 -1
- data/lib/zip/extra_field/universal_time.rb +3 -1
- data/lib/zip/extra_field/unix.rb +5 -3
- data/lib/zip/extra_field/unknown.rb +33 -0
- data/lib/zip/extra_field/zip64.rb +12 -5
- data/lib/zip/extra_field.rb +15 -21
- data/lib/zip/file.rb +144 -265
- data/lib/zip/file_split.rb +97 -0
- data/lib/zip/filesystem/dir.rb +86 -0
- data/lib/zip/filesystem/directory_iterator.rb +48 -0
- data/lib/zip/filesystem/file.rb +262 -0
- data/lib/zip/filesystem/file_stat.rb +110 -0
- data/lib/zip/filesystem/zip_file_name_mapper.rb +81 -0
- data/lib/zip/filesystem.rb +26 -595
- data/lib/zip/inflater.rb +7 -5
- data/lib/zip/input_stream.rb +44 -39
- data/lib/zip/ioextras/abstract_input_stream.rb +14 -9
- data/lib/zip/ioextras/abstract_output_stream.rb +5 -3
- data/lib/zip/ioextras.rb +6 -6
- data/lib/zip/null_compressor.rb +3 -1
- data/lib/zip/null_decompressor.rb +3 -1
- data/lib/zip/null_input_stream.rb +3 -1
- data/lib/zip/output_stream.rb +47 -48
- data/lib/zip/pass_thru_compressor.rb +3 -1
- data/lib/zip/pass_thru_decompressor.rb +4 -2
- data/lib/zip/streamable_directory.rb +3 -1
- data/lib/zip/streamable_stream.rb +3 -0
- data/lib/zip/version.rb +3 -1
- data/lib/zip.rb +15 -20
- data/rubyzip.gemspec +38 -0
- data/samples/example.rb +8 -3
- data/samples/example_filesystem.rb +2 -1
- data/samples/example_recursive.rb +3 -1
- data/samples/gtk_ruby_zip.rb +4 -2
- data/samples/qtzip.rb +6 -5
- data/samples/write_simple.rb +1 -0
- data/samples/zipfind.rb +1 -0
- metadata +84 -50
- data/TODO +0 -15
- data/lib/zip/extra_field/zip64_placeholder.rb +0 -15
data/lib/zip/input_stream.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zip
|
2
4
|
# InputStream is the basic class for reading zip entries in a
|
3
5
|
# zip file. It is possible to create a InputStream object directly,
|
@@ -49,30 +51,30 @@ module Zip
|
|
49
51
|
#
|
50
52
|
# @param context [String||IO||StringIO] file path or IO/StringIO object
|
51
53
|
# @param offset [Integer] offset in the IO/StringIO
|
52
|
-
def initialize(context,
|
54
|
+
def initialize(context, offset: 0, decrypter: nil)
|
53
55
|
super()
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
offset = dep_offset if offset.zero?
|
60
|
-
@archive_io = get_io(context, offset)
|
61
|
-
@decompressor = ::Zip::NullDecompressor
|
62
|
-
@decrypter = decrypter || dep_decrypter || ::Zip::NullDecrypter.new
|
56
|
+
@archive_io = get_io(context, offset)
|
57
|
+
@decompressor = ::Zip::NullDecompressor
|
58
|
+
@decrypter = decrypter || ::Zip::NullDecrypter.new
|
63
59
|
@current_entry = nil
|
60
|
+
@complete_entry = nil
|
64
61
|
end
|
65
62
|
|
66
63
|
def close
|
67
64
|
@archive_io.close
|
68
65
|
end
|
69
66
|
|
70
|
-
# Returns
|
71
|
-
# method on a newly created
|
72
|
-
# the first entry in the archive.
|
73
|
-
# no more entries.
|
67
|
+
# Returns an Entry object and positions the stream at the beginning of
|
68
|
+
# the entry data. It is necessary to call this method on a newly created
|
69
|
+
# InputStream before reading from the first entry in the archive.
|
70
|
+
# Returns nil when there are no more entries.
|
74
71
|
def get_next_entry
|
75
|
-
@
|
72
|
+
unless @current_entry.nil?
|
73
|
+
raise StreamingError, @current_entry if @current_entry.incomplete?
|
74
|
+
|
75
|
+
@archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET)
|
76
|
+
end
|
77
|
+
|
76
78
|
open_entry
|
77
79
|
end
|
78
80
|
|
@@ -91,18 +93,19 @@ module Zip
|
|
91
93
|
@decompressor.read(length, outbuf)
|
92
94
|
end
|
93
95
|
|
96
|
+
# Returns the size of the current entry, or `nil` if there isn't one.
|
97
|
+
def size
|
98
|
+
return if @current_entry.nil?
|
99
|
+
|
100
|
+
@current_entry.size
|
101
|
+
end
|
102
|
+
|
94
103
|
class << self
|
95
104
|
# Same as #initialize but if a block is passed the opened
|
96
105
|
# stream is passed to the block and closed when the block
|
97
106
|
# returns.
|
98
|
-
def open(filename_or_io,
|
99
|
-
|
100
|
-
Zip.warn_about_v3_api('Zip::InputStream.new')
|
101
|
-
end
|
102
|
-
|
103
|
-
offset = dep_offset if offset.zero?
|
104
|
-
|
105
|
-
zio = new(filename_or_io, offset: offset, decrypter: decrypter || dep_decrypter)
|
107
|
+
def open(filename_or_io, offset: 0, decrypter: nil)
|
108
|
+
zio = new(filename_or_io, offset: offset, decrypter: decrypter)
|
106
109
|
return zio unless block_given?
|
107
110
|
|
108
111
|
begin
|
@@ -112,10 +115,9 @@ module Zip
|
|
112
115
|
end
|
113
116
|
end
|
114
117
|
|
115
|
-
def open_buffer(filename_or_io, offset
|
116
|
-
|
117
|
-
|
118
|
-
::Zip::InputStream.open(filename_or_io, offset)
|
118
|
+
def open_buffer(filename_or_io, offset: 0)
|
119
|
+
warn 'open_buffer is deprecated!!! Use open instead!'
|
120
|
+
::Zip::InputStream.open(filename_or_io, offset: offset)
|
119
121
|
end
|
120
122
|
end
|
121
123
|
|
@@ -135,17 +137,18 @@ module Zip
|
|
135
137
|
|
136
138
|
def open_entry
|
137
139
|
@current_entry = ::Zip::Entry.read_local_entry(@archive_io)
|
138
|
-
if @current_entry
|
139
|
-
|
140
|
+
return if @current_entry.nil?
|
141
|
+
|
142
|
+
if @current_entry.encrypted? && @decrypter.kind_of?(NullDecrypter)
|
143
|
+
raise Error,
|
144
|
+
'A password is required to decode this zip file'
|
140
145
|
end
|
141
146
|
|
142
|
-
if @current_entry
|
143
|
-
&&
|
144
|
-
|
145
|
-
raise GPFBit3Error,
|
146
|
-
'General purpose flag Bit 3 is set so not possible to get proper info from local header.' \
|
147
|
-
'Please use ::Zip::File instead of ::Zip::InputStream'
|
147
|
+
if @current_entry.incomplete? && @current_entry.compressed_size == 0 \
|
148
|
+
&& !@complete_entry
|
149
|
+
raise StreamingError, @current_entry
|
148
150
|
end
|
151
|
+
|
149
152
|
@decrypted_io = get_decrypted_io
|
150
153
|
@decompressor = get_decompressor
|
151
154
|
flush
|
@@ -163,16 +166,18 @@ module Zip
|
|
163
166
|
return ::Zip::NullDecompressor if @current_entry.nil?
|
164
167
|
|
165
168
|
decompressed_size =
|
166
|
-
if @current_entry.incomplete? && @current_entry.crc == 0
|
169
|
+
if @current_entry.incomplete? && @current_entry.crc == 0 \
|
170
|
+
&& @current_entry.size == 0 && @complete_entry
|
167
171
|
@complete_entry.size
|
168
172
|
else
|
169
173
|
@current_entry.size
|
170
174
|
end
|
171
175
|
|
172
|
-
decompressor_class = ::Zip::Decompressor.find_by_compression_method(
|
176
|
+
decompressor_class = ::Zip::Decompressor.find_by_compression_method(
|
177
|
+
@current_entry.compression_method
|
178
|
+
)
|
173
179
|
if decompressor_class.nil?
|
174
|
-
raise ::Zip::CompressionMethodError,
|
175
|
-
"Unsupported compression method #{@current_entry.compression_method}"
|
180
|
+
raise ::Zip::CompressionMethodError, @current_entry.compression_method
|
176
181
|
end
|
177
182
|
|
178
183
|
decompressor_class.new(@decrypted_io, decompressed_size)
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zip
|
2
|
-
module IOExtras
|
4
|
+
module IOExtras # :nodoc:
|
3
5
|
# Implements many of the convenience methods of IO
|
4
6
|
# such as gets, getc, readline and readlines
|
5
7
|
# depends on: input_finished?, produce_input and read
|
6
|
-
module AbstractInputStream
|
8
|
+
module AbstractInputStream # :nodoc:
|
7
9
|
include Enumerable
|
8
10
|
include FakeIO
|
9
11
|
|
@@ -11,22 +13,22 @@ module Zip
|
|
11
13
|
super
|
12
14
|
@lineno = 0
|
13
15
|
@pos = 0
|
14
|
-
@output_buffer = ''
|
16
|
+
@output_buffer = +''
|
15
17
|
end
|
16
18
|
|
17
19
|
attr_accessor :lineno
|
18
20
|
attr_reader :pos
|
19
21
|
|
20
|
-
def read(number_of_bytes = nil, buf = ''
|
22
|
+
def read(number_of_bytes = nil, buf = +'')
|
21
23
|
tbuf = if @output_buffer.bytesize > 0
|
22
|
-
if number_of_bytes <= @output_buffer.bytesize
|
24
|
+
if number_of_bytes && number_of_bytes <= @output_buffer.bytesize
|
23
25
|
@output_buffer.slice!(0, number_of_bytes)
|
24
26
|
else
|
25
27
|
number_of_bytes -= @output_buffer.bytesize if number_of_bytes
|
26
28
|
rbuf = sysread(number_of_bytes, buf)
|
27
29
|
out = @output_buffer
|
28
30
|
out << rbuf if rbuf
|
29
|
-
@output_buffer = ''
|
31
|
+
@output_buffer = ''
|
30
32
|
out
|
31
33
|
end
|
32
34
|
else
|
@@ -34,7 +36,7 @@ module Zip
|
|
34
36
|
end
|
35
37
|
|
36
38
|
if tbuf.nil? || tbuf.empty?
|
37
|
-
return nil if number_of_bytes
|
39
|
+
return nil if number_of_bytes&.positive?
|
38
40
|
|
39
41
|
return ''
|
40
42
|
end
|
@@ -82,7 +84,10 @@ module Zip
|
|
82
84
|
@output_buffer << produce_input
|
83
85
|
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
|
84
86
|
end
|
85
|
-
sep_index = [
|
87
|
+
sep_index = [
|
88
|
+
match_index + a_sep_string.bytesize,
|
89
|
+
number_of_bytes || @output_buffer.bytesize
|
90
|
+
].min
|
86
91
|
@pos += sep_index
|
87
92
|
@output_buffer.slice!(0...sep_index)
|
88
93
|
end
|
@@ -93,7 +98,7 @@ module Zip
|
|
93
98
|
|
94
99
|
def flush
|
95
100
|
ret_val = @output_buffer
|
96
|
-
@output_buffer = ''
|
101
|
+
@output_buffer = +''
|
97
102
|
ret_val
|
98
103
|
end
|
99
104
|
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zip
|
2
|
-
module IOExtras
|
4
|
+
module IOExtras # :nodoc:
|
3
5
|
# Implements many of the output convenience methods of IO.
|
4
6
|
# relies on <<
|
5
|
-
module AbstractOutputStream
|
7
|
+
module AbstractOutputStream # :nodoc:
|
6
8
|
include FakeIO
|
7
9
|
|
8
10
|
def write(data)
|
@@ -11,7 +13,7 @@ module Zip
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def print(*params)
|
14
|
-
self << params.join
|
16
|
+
self << params.join << $OUTPUT_RECORD_SEPARATOR.to_s
|
15
17
|
end
|
16
18
|
|
17
19
|
def printf(a_format_string, *params)
|
data/lib/zip/ioextras.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zip
|
2
|
-
module IOExtras
|
4
|
+
module IOExtras # :nodoc:
|
3
5
|
CHUNK_SIZE = 131_072
|
4
6
|
|
5
|
-
RANGE_ALL = 0..-1
|
6
|
-
|
7
7
|
class << self
|
8
8
|
def copy_stream(ostream, istream)
|
9
|
-
ostream.write(istream.read(CHUNK_SIZE, ''
|
9
|
+
ostream.write(istream.read(CHUNK_SIZE, +'')) until istream.eof?
|
10
10
|
end
|
11
11
|
|
12
12
|
def copy_stream_n(ostream, istream, nbytes)
|
13
13
|
toread = nbytes
|
14
14
|
while toread > 0 && !istream.eof?
|
15
15
|
tr = toread > CHUNK_SIZE ? CHUNK_SIZE : toread
|
16
|
-
ostream.write(istream.read(tr, ''
|
16
|
+
ostream.write(istream.read(tr, +''))
|
17
17
|
toread -= tr
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
# Implements kind_of? in order to pretend to be an IO object
|
23
|
-
module FakeIO
|
23
|
+
module FakeIO # :nodoc:
|
24
24
|
def kind_of?(object)
|
25
25
|
object == IO || super
|
26
26
|
end
|
data/lib/zip/null_compressor.rb
CHANGED
data/lib/zip/output_stream.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
1
5
|
module Zip
|
2
6
|
# ZipOutputStream is the basic class for writing zip files. It is
|
3
7
|
# possible to create a ZipOutputStream object directly, passing
|
@@ -18,55 +22,48 @@ module Zip
|
|
18
22
|
# class.
|
19
23
|
|
20
24
|
class OutputStream
|
25
|
+
extend Forwardable
|
21
26
|
include ::Zip::IOExtras::AbstractOutputStream
|
22
27
|
|
23
|
-
|
28
|
+
def_delegators :@cdir, :comment, :comment=
|
24
29
|
|
25
30
|
# Opens the indicated zip file. If a file with that name already
|
26
31
|
# exists it will be overwritten.
|
27
|
-
def initialize(file_name,
|
32
|
+
def initialize(file_name, stream: false, encrypter: nil)
|
28
33
|
super()
|
29
|
-
|
30
|
-
Zip.warn_about_v3_api('Zip::OutputStream.new') if dep_stream || !dep_encrypter.nil?
|
31
|
-
|
32
34
|
@file_name = file_name
|
33
|
-
@output_stream = if stream
|
34
|
-
iostream = @file_name.dup
|
35
|
+
@output_stream = if stream
|
36
|
+
iostream = Zip::RUNNING_ON_WINDOWS ? @file_name : @file_name.dup
|
35
37
|
iostream.reopen(@file_name)
|
36
38
|
iostream.rewind
|
37
39
|
iostream
|
38
40
|
else
|
39
41
|
::File.new(@file_name, 'wb')
|
40
42
|
end
|
41
|
-
@
|
43
|
+
@cdir = ::Zip::CentralDirectory.new
|
42
44
|
@compressor = ::Zip::NullCompressor.instance
|
43
|
-
@encrypter = encrypter ||
|
45
|
+
@encrypter = encrypter || ::Zip::NullEncrypter.new
|
44
46
|
@closed = false
|
45
47
|
@current_entry = nil
|
46
|
-
@comment = nil
|
47
48
|
end
|
48
49
|
|
49
50
|
# Same as #initialize but if a block is passed the opened
|
50
51
|
# stream is passed to the block and closed when the block
|
51
52
|
# returns.
|
52
53
|
class << self
|
53
|
-
def open(file_name,
|
54
|
+
def open(file_name, encrypter: nil)
|
54
55
|
return new(file_name) unless block_given?
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
zos = new(file_name, stream: false, encrypter: (encrypter || dep_encrypter))
|
57
|
+
zos = new(file_name, stream: false, encrypter: encrypter)
|
59
58
|
yield zos
|
60
59
|
ensure
|
61
60
|
zos.close if zos
|
62
61
|
end
|
63
62
|
|
64
63
|
# Same as #open but writes to a filestream instead
|
65
|
-
def write_buffer(io = ::StringIO.new,
|
66
|
-
Zip.warn_about_v3_api('Zip::OutputStream.write_buffer') unless dep_encrypter.nil?
|
67
|
-
|
64
|
+
def write_buffer(io = ::StringIO.new, encrypter: nil)
|
68
65
|
io.binmode if io.respond_to?(:binmode)
|
69
|
-
zos = new(io, stream: true, encrypter:
|
66
|
+
zos = new(io, stream: true, encrypter: encrypter)
|
70
67
|
yield zos
|
71
68
|
zos.close_buffer
|
72
69
|
end
|
@@ -78,7 +75,7 @@ module Zip
|
|
78
75
|
|
79
76
|
finalize_current_entry
|
80
77
|
update_local_headers
|
81
|
-
|
78
|
+
@cdir.write_to_stream(@output_stream)
|
82
79
|
@output_stream.close
|
83
80
|
@closed = true
|
84
81
|
end
|
@@ -89,27 +86,31 @@ module Zip
|
|
89
86
|
|
90
87
|
finalize_current_entry
|
91
88
|
update_local_headers
|
92
|
-
|
89
|
+
@cdir.write_to_stream(@output_stream)
|
93
90
|
@closed = true
|
91
|
+
@output_stream.flush
|
94
92
|
@output_stream
|
95
93
|
end
|
96
94
|
|
97
95
|
# Closes the current entry and opens a new for writing.
|
98
96
|
# +entry+ can be a ZipEntry object or a string.
|
99
|
-
def put_next_entry(
|
97
|
+
def put_next_entry(
|
98
|
+
entry_name, comment = '', extra = ExtraField.new,
|
99
|
+
compression_method = Entry::DEFLATED, level = Zip.default_compression
|
100
|
+
)
|
100
101
|
raise Error, 'zip stream is closed' if @closed
|
101
102
|
|
102
|
-
new_entry =
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
init_next_entry(new_entry
|
103
|
+
new_entry =
|
104
|
+
if entry_name.kind_of?(Entry) || entry_name.kind_of?(StreamableStream)
|
105
|
+
entry_name
|
106
|
+
else
|
107
|
+
Entry.new(
|
108
|
+
@file_name, entry_name.to_s, comment: comment, extra: extra,
|
109
|
+
compression_method: compression_method, compression_level: level
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
init_next_entry(new_entry)
|
113
114
|
@current_entry = new_entry
|
114
115
|
end
|
115
116
|
|
@@ -119,7 +120,7 @@ module Zip
|
|
119
120
|
raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
|
120
121
|
|
121
122
|
finalize_current_entry
|
122
|
-
@
|
123
|
+
@cdir << entry
|
123
124
|
src_pos = entry.local_header_offset
|
124
125
|
entry.write_local_entry(@output_stream)
|
125
126
|
@compressor = NullCompressor.instance
|
@@ -143,47 +144,45 @@ module Zip
|
|
143
144
|
@current_entry.calculate_local_header_size
|
144
145
|
@current_entry.size = @compressor.size
|
145
146
|
@current_entry.crc = @compressor.crc
|
146
|
-
@output_stream << @encrypter.data_descriptor(
|
147
|
+
@output_stream << @encrypter.data_descriptor(
|
148
|
+
@current_entry.crc,
|
149
|
+
@current_entry.compressed_size,
|
150
|
+
@current_entry.size
|
151
|
+
)
|
147
152
|
@current_entry.gp_flags |= @encrypter.gp_flags
|
148
153
|
@current_entry = nil
|
149
154
|
@compressor = ::Zip::NullCompressor.instance
|
150
155
|
end
|
151
156
|
|
152
|
-
def init_next_entry(entry
|
157
|
+
def init_next_entry(entry)
|
153
158
|
finalize_current_entry
|
154
|
-
@
|
159
|
+
@cdir << entry
|
155
160
|
entry.write_local_entry(@output_stream)
|
156
161
|
@encrypter.reset!
|
157
162
|
@output_stream << @encrypter.header(entry.mtime)
|
158
|
-
@compressor = get_compressor(entry
|
163
|
+
@compressor = get_compressor(entry)
|
159
164
|
end
|
160
165
|
|
161
|
-
def get_compressor(entry
|
166
|
+
def get_compressor(entry)
|
162
167
|
case entry.compression_method
|
163
168
|
when Entry::DEFLATED
|
164
|
-
::Zip::Deflater.new(@output_stream,
|
169
|
+
::Zip::Deflater.new(@output_stream, entry.compression_level, @encrypter)
|
165
170
|
when Entry::STORED
|
166
171
|
::Zip::PassThruCompressor.new(@output_stream)
|
167
172
|
else
|
168
|
-
raise ::Zip::CompressionMethodError,
|
169
|
-
"Invalid compression method: '#{entry.compression_method}'"
|
173
|
+
raise ::Zip::CompressionMethodError, entry.compression_method
|
170
174
|
end
|
171
175
|
end
|
172
176
|
|
173
177
|
def update_local_headers
|
174
178
|
pos = @output_stream.pos
|
175
|
-
@
|
179
|
+
@cdir.each do |entry|
|
176
180
|
@output_stream.pos = entry.local_header_offset
|
177
|
-
entry.write_local_entry(@output_stream, true)
|
181
|
+
entry.write_local_entry(@output_stream, rewrite: true)
|
178
182
|
end
|
179
183
|
@output_stream.pos = pos
|
180
184
|
end
|
181
185
|
|
182
|
-
def write_central_directory
|
183
|
-
cdir = CentralDirectory.new(@entry_set, @comment)
|
184
|
-
cdir.write_to_stream(@output_stream)
|
185
|
-
end
|
186
|
-
|
187
186
|
protected
|
188
187
|
|
189
188
|
def finish
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zip
|
2
|
-
class PassThruDecompressor < Decompressor
|
4
|
+
class PassThruDecompressor < Decompressor # :nodoc:all
|
3
5
|
def initialize(*args)
|
4
6
|
super
|
5
7
|
@read_so_far = 0
|
6
8
|
end
|
7
9
|
|
8
|
-
def read(length = nil, outbuf = ''
|
10
|
+
def read(length = nil, outbuf = +'')
|
9
11
|
return (length.nil? || length.zero? ? '' : nil) if eof
|
10
12
|
|
11
13
|
if length.nil? || (@read_so_far + length) > decompressed_size
|
data/lib/zip/version.rb
CHANGED
data/lib/zip.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'English'
|
2
4
|
require 'delegate'
|
3
5
|
require 'singleton'
|
@@ -33,26 +35,12 @@ require 'zip/streamable_stream'
|
|
33
35
|
require 'zip/streamable_directory'
|
34
36
|
require 'zip/errors'
|
35
37
|
|
38
|
+
# Rubyzip is a ruby module for reading and writing zip files.
|
39
|
+
#
|
40
|
+
# The main entry points are File, InputStream and OutputStream. For a
|
41
|
+
# file/directory interface in the style of the standard ruby ::File and
|
42
|
+
# ::Dir APIs then `require 'zip/filesystem'` and see FileSystem.
|
36
43
|
module Zip
|
37
|
-
V3_API_WARNING_MSG = <<~END_MSG
|
38
|
-
You have called '%s' (from %s).
|
39
|
-
This method is changing or deprecated in version 3.0.0. Please see
|
40
|
-
https://github.com/rubyzip/rubyzip/wiki/Updating-to-version-3.x
|
41
|
-
for more information.
|
42
|
-
END_MSG
|
43
|
-
|
44
|
-
def self.warn_about_v3_api(method)
|
45
|
-
return unless ENV['RUBYZIP_V3_API_WARN']
|
46
|
-
|
47
|
-
loc = caller_locations(2, 1)[0]
|
48
|
-
from = "#{loc.path.split('/').last}:#{loc.lineno}"
|
49
|
-
warn format(V3_API_WARNING_MSG, method, from)
|
50
|
-
end
|
51
|
-
|
52
|
-
if ENV['RUBYZIP_V3_API_WARN'] && RUBY_VERSION < '3.0'
|
53
|
-
warn 'RubyZip 3.0 will require Ruby 3.0 or later.'
|
54
|
-
end
|
55
|
-
|
56
44
|
extend self
|
57
45
|
attr_accessor :unicode_names,
|
58
46
|
:on_exists_proc,
|
@@ -65,6 +53,12 @@ module Zip
|
|
65
53
|
:force_entry_names_encoding,
|
66
54
|
:validate_entry_sizes
|
67
55
|
|
56
|
+
DEFAULT_RESTORE_OPTIONS = {
|
57
|
+
restore_ownership: false,
|
58
|
+
restore_permissions: true,
|
59
|
+
restore_times: true
|
60
|
+
}.freeze
|
61
|
+
|
68
62
|
def reset!
|
69
63
|
@_ran_once = false
|
70
64
|
@unicode_names = false
|
@@ -72,9 +66,10 @@ module Zip
|
|
72
66
|
@continue_on_exists_proc = false
|
73
67
|
@sort_entries = false
|
74
68
|
@default_compression = ::Zlib::DEFAULT_COMPRESSION
|
75
|
-
@write_zip64_support =
|
69
|
+
@write_zip64_support = true
|
76
70
|
@warn_invalid_date = true
|
77
71
|
@case_insensitive_match = false
|
72
|
+
@force_entry_names_encoding = nil
|
78
73
|
@validate_entry_sizes = true
|
79
74
|
end
|
80
75
|
|
data/rubyzip.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/zip/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'rubyzip'
|
7
|
+
s.version = ::Zip::VERSION
|
8
|
+
s.authors = ['Robert Haines', 'John Lees-Miller', 'Alexander Simonov']
|
9
|
+
s.email = [
|
10
|
+
'hainesr@gmail.com', 'jdleesmiller@gmail.com', 'alex@simonov.me'
|
11
|
+
]
|
12
|
+
s.homepage = 'http://github.com/rubyzip/rubyzip'
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.summary = 'rubyzip is a ruby module for reading and writing zip files'
|
15
|
+
s.files = Dir.glob('{samples,lib}/**/*.rb') +
|
16
|
+
%w[README.md Changelog.md Rakefile rubyzip.gemspec]
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
s.license = 'BSD-2-Clause'
|
19
|
+
|
20
|
+
s.metadata = {
|
21
|
+
'bug_tracker_uri' => 'https://github.com/rubyzip/rubyzip/issues',
|
22
|
+
'changelog_uri' => "https://github.com/rubyzip/rubyzip/blob/v#{s.version}/Changelog.md",
|
23
|
+
'documentation_uri' => "https://www.rubydoc.info/gems/rubyzip/#{s.version}",
|
24
|
+
'source_code_uri' => "https://github.com/rubyzip/rubyzip/tree/v#{s.version}",
|
25
|
+
'wiki_uri' => 'https://github.com/rubyzip/rubyzip/wiki'
|
26
|
+
}
|
27
|
+
|
28
|
+
s.required_ruby_version = '>= 2.5'
|
29
|
+
|
30
|
+
s.add_development_dependency 'minitest', '~> 5.4'
|
31
|
+
s.add_development_dependency 'rake', '~> 12.3.3'
|
32
|
+
s.add_development_dependency 'rdoc', '~> 6.4.0'
|
33
|
+
s.add_development_dependency 'rubocop', '~> 1.12.0'
|
34
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.10.0'
|
35
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.5.0'
|
36
|
+
s.add_development_dependency 'simplecov', '~> 0.18.0'
|
37
|
+
s.add_development_dependency 'simplecov-lcov', '~> 0.8'
|
38
|
+
end
|