rubyzip 3.2.1 → 3.3.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/Changelog.md +19 -0
- data/LICENSE.md +1 -1
- data/lib/zip/central_directory.rb +39 -33
- data/lib/zip/crypto/decrypted_io.rb +5 -5
- data/lib/zip/entry.rb +4 -5
- data/lib/zip/inflater.rb +5 -5
- data/lib/zip/input_stream.rb +24 -5
- data/lib/zip/ioextras/abstract_input_stream.rb +142 -60
- data/lib/zip/pass_thru_decompressor.rb +6 -6
- data/lib/zip/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 301afd00cf28573bc4e6b12cd9a7f6dca91dcd260244423ac8dab1c97e4dcbec
|
|
4
|
+
data.tar.gz: 8c6d46366f1fe3064632b0de1a00a82f44184438ae7febdc3db82407092965f2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 44a3a3e3176ea832db64716d81ae5dcf2919d975e395012a27ca849f3d6d22a2b9e199f73bae152f2ae2acb62f4ccbce3de33b4ffd26f21935d2ab997f2abb19
|
|
7
|
+
data.tar.gz: beeec7382ef911feeb9e4403dc6025a02904f74cc31cb9948f180c060b8706aa9b080d0e2bbbcfaae9c89465e0922799169713bba5563d275db3d677dc0962d4
|
data/Changelog.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# 3.3.0 (2026-05-02)
|
|
2
|
+
|
|
3
|
+
- Refactor `InputStream` and `AbstractInputStream`.
|
|
4
|
+
[#661](https://github.com/rubyzip/rubyzip/pull/661)
|
|
5
|
+
|
|
6
|
+
Tooling/internal:
|
|
7
|
+
|
|
8
|
+
- Update Actions to use checkout@v5.
|
|
9
|
+
- Add Ruby4.0 to the CI matrix. [#659](https://github.com/rubyzip/rubyzip/pull/659)
|
|
10
|
+
|
|
11
|
+
# 3.2.2 (2025-11-02)
|
|
12
|
+
|
|
13
|
+
- Fix reading EOCDs when header signatures are in an Entry payload. [#656](https://github.com/rubyzip/rubyzip/issues/656)
|
|
14
|
+
|
|
15
|
+
Tooling/internal:
|
|
16
|
+
|
|
17
|
+
- Stop using macos-13 runners in GitHub Actions.
|
|
18
|
+
- Update YJIT GitHub Actions runners.
|
|
19
|
+
|
|
1
20
|
# 3.2.1 (2025-10-24)
|
|
2
21
|
|
|
3
22
|
- Fix `Entry#gather_fileinfo_from_srcpath` error messages. [#654](https://github.com/rubyzip/rubyzip/issues/654)
|
data/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
BSD 2-Clause License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2002-
|
|
3
|
+
Copyright (c) 2002-2026, The Rubyzip Developers
|
|
4
4
|
|
|
5
5
|
Redistribution and use in source and binary forms, with or without
|
|
6
6
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -143,28 +143,27 @@ module Zip
|
|
|
143
143
|
zip64_eocd_offset
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
# Unpack the EOCD and return a boolean indicating whether this header is
|
|
147
|
+
# complete without needing Zip64 extensions.
|
|
148
|
+
def unpack_e_o_c_d(buffer) # :nodoc: # rubocop:disable Naming/PredicateMethod
|
|
147
149
|
_, # END_OF_CD_SIG. We know we have this at this point.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
size_in_bytes,
|
|
153
|
-
cdir_offset,
|
|
150
|
+
@number_of_this_disk,
|
|
151
|
+
@number_of_disk_with_start_of_cdir,
|
|
152
|
+
@total_number_of_entries_in_cdir_on_this_disk,
|
|
153
|
+
@size,
|
|
154
|
+
@size_in_bytes,
|
|
155
|
+
@cdir_offset,
|
|
154
156
|
comment_length = buffer.unpack('VvvvvVVv')
|
|
155
157
|
|
|
156
|
-
@number_of_this_disk = num_disk unless num_disk == 0xFFFF
|
|
157
|
-
@number_of_disk_with_start_of_cdir = num_disk_cdir unless num_disk_cdir == 0xFFFF
|
|
158
|
-
@total_number_of_entries_in_cdir_on_this_disk = num_cdir_disk unless num_cdir_disk == 0xFFFF
|
|
159
|
-
@size = num_entries unless num_entries == 0xFFFF
|
|
160
|
-
@size_in_bytes = size_in_bytes unless size_in_bytes == 0xFFFFFFFF
|
|
161
|
-
@cdir_offset = cdir_offset unless cdir_offset == 0xFFFFFFFF
|
|
162
|
-
|
|
163
158
|
@comment = if comment_length.positive?
|
|
164
159
|
buffer.slice(STATIC_EOCD_SIZE, comment_length)
|
|
165
160
|
else
|
|
166
161
|
''
|
|
167
162
|
end
|
|
163
|
+
|
|
164
|
+
!([@number_of_this_disk, @number_of_disk_with_start_of_cdir,
|
|
165
|
+
@total_number_of_entries_in_cdir_on_this_disk, @size].any?(0xFFFF) ||
|
|
166
|
+
@size_in_bytes == 0xFFFFFFFF || @cdir_offset == 0xFFFFFFFF)
|
|
168
167
|
end
|
|
169
168
|
|
|
170
169
|
def read_central_directory_entries(io) # :nodoc:
|
|
@@ -217,30 +216,37 @@ module Zip
|
|
|
217
216
|
eocd_location = data.rindex([END_OF_CD_SIG].pack('V'))
|
|
218
217
|
raise Error, 'Zip end of central directory signature not found' unless eocd_location
|
|
219
218
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if zip64_eocd_locator
|
|
223
|
-
zip64_eocd_location = data.rindex([ZIP64_END_OF_CD_SIG].pack('V'))
|
|
219
|
+
# Parse the EOCD and return if it is complete without Zip64 extensions.
|
|
220
|
+
return if unpack_e_o_c_d(data.slice(eocd_location..-1))
|
|
224
221
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
data.slice(zip64_eocd_locator..eocd_location)
|
|
231
|
-
)
|
|
232
|
-
unless zip64_eocd_location
|
|
233
|
-
raise Error, 'Zip64 end of central directory signature not found'
|
|
234
|
-
end
|
|
222
|
+
# Need to read in the Zip64 EOCD locator and then the Zip64 EOCD.
|
|
223
|
+
zip64_eocd_locator = data.rindex([ZIP64_EOCD_LOCATOR_SIG].pack('V'), eocd_location)
|
|
224
|
+
unless zip64_eocd_locator
|
|
225
|
+
raise Error, 'Zip64 end of central directory locator signature expected but not found'
|
|
226
|
+
end
|
|
235
227
|
|
|
236
|
-
|
|
237
|
-
|
|
228
|
+
# Do we already have the Zip64 EOCD in the data we've read?
|
|
229
|
+
zip64_eocd_location = data.rindex([ZIP64_END_OF_CD_SIG].pack('V'), zip64_eocd_locator)
|
|
230
|
+
|
|
231
|
+
zip64_eocd_data =
|
|
232
|
+
if zip64_eocd_location
|
|
233
|
+
# Yes.
|
|
234
|
+
data.slice(zip64_eocd_location..zip64_eocd_locator)
|
|
235
|
+
else
|
|
236
|
+
# No. Read its location from the locator and then read it in.
|
|
237
|
+
zip64_eocd_location = unpack_64_eocd_locator(
|
|
238
|
+
data.slice(zip64_eocd_locator..eocd_location)
|
|
239
|
+
)
|
|
240
|
+
unless zip64_eocd_location
|
|
241
|
+
raise Error, 'Zip64 end of central directory signature not found'
|
|
238
242
|
end
|
|
239
243
|
|
|
240
|
-
|
|
241
|
-
|
|
244
|
+
io.seek(zip64_eocd_location, IO::SEEK_SET)
|
|
245
|
+
io.read(base_location + zip64_eocd_locator - zip64_eocd_location)
|
|
246
|
+
end
|
|
242
247
|
|
|
243
|
-
|
|
248
|
+
# Finally, unpack the Zip64 EOCD.
|
|
249
|
+
unpack_64_e_o_c_d(zip64_eocd_data)
|
|
244
250
|
end
|
|
245
251
|
|
|
246
252
|
def eocd_data(io)
|
|
@@ -8,13 +8,13 @@ module Zip
|
|
|
8
8
|
@io = io
|
|
9
9
|
@decrypter = decrypter
|
|
10
10
|
@bytes_remaining = compressed_size
|
|
11
|
-
@buffer = +''
|
|
11
|
+
@buffer = +''.b
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def read(
|
|
15
|
-
return (
|
|
14
|
+
def read(maxlen = nil)
|
|
15
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
16
16
|
|
|
17
|
-
while
|
|
17
|
+
while maxlen.nil? || (@buffer.bytesize < maxlen)
|
|
18
18
|
break if input_finished?
|
|
19
19
|
|
|
20
20
|
@buffer << produce_input
|
|
@@ -22,7 +22,7 @@ module Zip
|
|
|
22
22
|
|
|
23
23
|
@decrypter.check_integrity!(@io) if input_finished?
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
@buffer.slice!(0...(maxlen || @buffer.bytesize))
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
private
|
data/lib/zip/entry.rb
CHANGED
|
@@ -751,21 +751,20 @@ module Zip
|
|
|
751
751
|
|
|
752
752
|
def create_file(dest_path, _continue_on_exists_proc = proc { Zip.continue_on_exists_proc })
|
|
753
753
|
if ::File.exist?(dest_path) && !yield(self, dest_path)
|
|
754
|
-
raise
|
|
754
|
+
raise DestinationExistsError, dest_path
|
|
755
755
|
end
|
|
756
756
|
|
|
757
757
|
::File.open(dest_path, 'wb') do |os|
|
|
758
758
|
get_input_stream do |is|
|
|
759
759
|
bytes_written = 0
|
|
760
760
|
warned = false
|
|
761
|
-
buf =
|
|
762
|
-
while (buf = is.sysread(::Zip::Decompressor::CHUNK_SIZE, buf))
|
|
761
|
+
while (buf = is.sysread(Decompressor::CHUNK_SIZE))
|
|
763
762
|
os << buf
|
|
764
763
|
bytes_written += buf.bytesize
|
|
765
764
|
next unless bytes_written > size && !warned
|
|
766
765
|
|
|
767
|
-
error =
|
|
768
|
-
raise error if
|
|
766
|
+
error = EntrySizeError.new(self)
|
|
767
|
+
raise error if Zip.validate_entry_sizes
|
|
769
768
|
|
|
770
769
|
warn "WARNING: #{error.message}"
|
|
771
770
|
warned = true
|
data/lib/zip/inflater.rb
CHANGED
|
@@ -5,20 +5,20 @@ module Zip
|
|
|
5
5
|
def initialize(*args)
|
|
6
6
|
super
|
|
7
7
|
|
|
8
|
-
@buffer = +''
|
|
8
|
+
@buffer = +''.b
|
|
9
9
|
@zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def read(
|
|
13
|
-
return (
|
|
12
|
+
def read(maxlen = nil)
|
|
13
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
14
14
|
|
|
15
|
-
while
|
|
15
|
+
while maxlen.nil? || (@buffer.bytesize < maxlen)
|
|
16
16
|
break if input_finished?
|
|
17
17
|
|
|
18
18
|
@buffer << produce_input
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
@buffer.slice!(0...(maxlen || @buffer.bytesize))
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def eof?
|
data/lib/zip/input_stream.rb
CHANGED
|
@@ -89,9 +89,28 @@ module Zip
|
|
|
89
89
|
open_entry
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
#
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
# Modelled after IO#sysread.
|
|
93
|
+
#
|
|
94
|
+
# Reads up to maxlen bytes from the stream; returns a string
|
|
95
|
+
# (either a new string or the given out_string).
|
|
96
|
+
# Its encoding is the unchanged encoding of out_string, if out_string is
|
|
97
|
+
# given; ASCII-8BIT, otherwise. Output contains maxlen bytes from the
|
|
98
|
+
# stream, if available; otherwise contains all available bytes, if any
|
|
99
|
+
# available; otherwise is an empty string.
|
|
100
|
+
#
|
|
101
|
+
# This method should not be used with buffered input stream-reader methods,
|
|
102
|
+
# such as #read, #readline, #gets.
|
|
103
|
+
def sysread(maxlen, out_string = nil)
|
|
104
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
105
|
+
|
|
106
|
+
output = produce_input(maxlen)
|
|
107
|
+
|
|
108
|
+
if out_string.nil?
|
|
109
|
+
output.force_encoding(Encoding::ASCII_8BIT)
|
|
110
|
+
else
|
|
111
|
+
encoding = out_string.encoding
|
|
112
|
+
out_string.replace(output).force_encoding(encoding)
|
|
113
|
+
end
|
|
95
114
|
end
|
|
96
115
|
|
|
97
116
|
# Returns the size of the current entry, or `nil` if there isn't one.
|
|
@@ -197,8 +216,8 @@ module Zip
|
|
|
197
216
|
decompressor_class.new(io, decompressed_size)
|
|
198
217
|
end
|
|
199
218
|
|
|
200
|
-
def produce_input # :nodoc:
|
|
201
|
-
@decompressor.read(
|
|
219
|
+
def produce_input(maxlen = CHUNK_SIZE) # :nodoc:
|
|
220
|
+
@decompressor.read(maxlen)
|
|
202
221
|
end
|
|
203
222
|
|
|
204
223
|
def input_finished? # :nodoc:
|
|
@@ -3,126 +3,208 @@
|
|
|
3
3
|
module Zip
|
|
4
4
|
module IOExtras # :nodoc:
|
|
5
5
|
# Implements many of the convenience methods of IO
|
|
6
|
-
# such as gets, getc, readline and readlines
|
|
6
|
+
# such as gets, getc, read, readline and readlines
|
|
7
7
|
# depends on: input_finished?, produce_input and read
|
|
8
|
-
module AbstractInputStream
|
|
8
|
+
module AbstractInputStream
|
|
9
9
|
include Enumerable
|
|
10
10
|
include FakeIO
|
|
11
11
|
|
|
12
|
-
def initialize
|
|
12
|
+
def initialize # :nodoc:
|
|
13
13
|
super
|
|
14
14
|
@lineno = 0
|
|
15
15
|
@pos = 0
|
|
16
|
-
@output_buffer = +''
|
|
16
|
+
@output_buffer = +''.b
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
# Returns (or sets) the current line number in the decompressed
|
|
20
|
+
# (possibly decrypted) data stream. See the Line Number documentation
|
|
21
|
+
# for the IO class for more information.
|
|
19
22
|
attr_accessor :lineno
|
|
23
|
+
|
|
24
|
+
# Returns the current position (in bytes) in the decompressed (possibly
|
|
25
|
+
# decrypted) data stream.
|
|
20
26
|
attr_reader :pos
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
# Reads bytes from the stream decompressed (possibly decrypted) data
|
|
29
|
+
# stream. If `maxlen` is `nil`, reads all bytes; otherwise, reads up to
|
|
30
|
+
# `maxlen` bytes. If `maxlen` is zero, returns an empty string.
|
|
31
|
+
#
|
|
32
|
+
# Returns a string (either a new string or the given `out_string`)
|
|
33
|
+
# containing the bytes read. The string's encoding is the unchanged
|
|
34
|
+
# encoding of `out_string`, if `out_string` is given; `ASCII-8BIT`,
|
|
35
|
+
# otherwise.
|
|
36
|
+
def read(maxlen = nil, out_string = nil) # rubocop:disable Metrics/PerceivedComplexity
|
|
37
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
38
|
+
|
|
23
39
|
tbuf = if @output_buffer.bytesize > 0
|
|
24
|
-
if
|
|
25
|
-
@output_buffer.slice!(0,
|
|
40
|
+
if maxlen && maxlen <= @output_buffer.bytesize
|
|
41
|
+
@output_buffer.slice!(0, maxlen)
|
|
26
42
|
else
|
|
27
|
-
|
|
28
|
-
rbuf =
|
|
43
|
+
maxlen -= @output_buffer.bytesize if maxlen
|
|
44
|
+
rbuf = produce_input(maxlen)
|
|
29
45
|
out = @output_buffer
|
|
30
46
|
out << rbuf if rbuf
|
|
31
|
-
@output_buffer = ''
|
|
47
|
+
@output_buffer = +''.b
|
|
32
48
|
out
|
|
33
49
|
end
|
|
34
50
|
else
|
|
35
|
-
|
|
51
|
+
produce_input(maxlen)
|
|
36
52
|
end
|
|
37
53
|
|
|
38
54
|
if tbuf.nil? || tbuf.empty?
|
|
39
|
-
return nil if
|
|
55
|
+
return nil if maxlen&.positive?
|
|
40
56
|
|
|
41
57
|
return ''
|
|
42
58
|
end
|
|
43
59
|
|
|
44
60
|
@pos += tbuf.length
|
|
45
61
|
|
|
46
|
-
if
|
|
47
|
-
|
|
62
|
+
if out_string.nil?
|
|
63
|
+
tbuf.force_encoding(Encoding::ASCII_8BIT)
|
|
48
64
|
else
|
|
49
|
-
|
|
65
|
+
encoding = out_string.encoding
|
|
66
|
+
out_string.replace(tbuf).force_encoding(encoding)
|
|
50
67
|
end
|
|
51
|
-
buf
|
|
52
68
|
end
|
|
53
69
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
# Reads and returns all remaining lines from the stream. See the Line IO
|
|
71
|
+
# documentation in the IO class for more information.
|
|
72
|
+
#
|
|
73
|
+
# With no arguments given, returns lines as determined by line
|
|
74
|
+
# separator `$/`, or `nil` if none.
|
|
75
|
+
#
|
|
76
|
+
# With only string argument `sep` given, returns lines as
|
|
77
|
+
# determined by line separator `sep`, or `nil` if none. See the
|
|
78
|
+
# Line Separator documentation in the IO class for more information.
|
|
79
|
+
# The two special values for `sep` (`nil` and `""`) are honoured.
|
|
80
|
+
#
|
|
81
|
+
# With only integer argument `limit` given, limits the number of bytes
|
|
82
|
+
# in each line; see the Line Limit documentation in the IO class for more
|
|
83
|
+
# information.
|
|
84
|
+
#
|
|
85
|
+
# With arguments `sep` and `limit` given, combines the two behaviors.
|
|
86
|
+
#
|
|
87
|
+
# Optional keyword argument `chomp` specifies whether line separators
|
|
88
|
+
# are to be omitted.
|
|
89
|
+
def readlines(sep = $INPUT_RECORD_SEPARATOR, limit = nil, chomp: false)
|
|
90
|
+
each(sep, limit, chomp: chomp).to_a
|
|
58
91
|
end
|
|
59
92
|
|
|
60
|
-
|
|
61
|
-
|
|
93
|
+
# Reads and returns a line from the stream. See the Line IO
|
|
94
|
+
# documentation in the IO class for more information.
|
|
95
|
+
#
|
|
96
|
+
# With no arguments given, returns the next line as determined by line
|
|
97
|
+
# separator `$/`, or `nil` if none.
|
|
98
|
+
#
|
|
99
|
+
# With only string argument `sep` given, returns the next line as
|
|
100
|
+
# determined by line separator `sep`, or `nil` if none. See the
|
|
101
|
+
# Line Separator documentation in the IO class for more information.
|
|
102
|
+
# The two special values for `sep` (`nil` and `""`) are honoured.
|
|
103
|
+
#
|
|
104
|
+
# With only integer argument `limit` given, limits the number of bytes
|
|
105
|
+
# in the line; see the Line Limit documentation in the IO class for more
|
|
106
|
+
# information.
|
|
107
|
+
#
|
|
108
|
+
# With arguments `sep` and `limit` given, combines the two behaviors.
|
|
109
|
+
#
|
|
110
|
+
# Optional keyword argument `chomp` specifies whether line separators
|
|
111
|
+
# are to be omitted.
|
|
112
|
+
def gets(sep = $INPUT_RECORD_SEPARATOR, limit = nil, chomp: false)
|
|
113
|
+
if sep.nil?
|
|
114
|
+
return nil if eof?
|
|
115
|
+
|
|
116
|
+
@lineno = @lineno.next
|
|
117
|
+
return read(limit)
|
|
118
|
+
end
|
|
62
119
|
|
|
63
|
-
if
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
elsif
|
|
67
|
-
|
|
68
|
-
a_sep_string = $INPUT_RECORD_SEPARATOR
|
|
69
|
-
else
|
|
70
|
-
number_of_bytes = nil
|
|
71
|
-
a_sep_string = a_sep_string.to_str if a_sep_string
|
|
120
|
+
if sep.respond_to?(:to_int)
|
|
121
|
+
limit = sep.to_int
|
|
122
|
+
sep = $INPUT_RECORD_SEPARATOR
|
|
123
|
+
elsif sep&.empty?
|
|
124
|
+
sep = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}"
|
|
72
125
|
end
|
|
73
126
|
|
|
74
|
-
|
|
127
|
+
buffer_index = 0
|
|
128
|
+
while (sep_index = @output_buffer.index(sep, buffer_index)).nil?
|
|
129
|
+
break if limit && @output_buffer.bytesize >= limit
|
|
75
130
|
|
|
76
|
-
|
|
131
|
+
if input_finished?
|
|
132
|
+
return nil if @output_buffer.empty?
|
|
77
133
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return @output_buffer.empty? ? nil : flush if input_finished?
|
|
134
|
+
@lineno = @lineno.next
|
|
135
|
+
@pos += @output_buffer.bytesize
|
|
136
|
+
return @output_buffer.slice!(0..)
|
|
137
|
+
end
|
|
83
138
|
|
|
139
|
+
buffer_index = [buffer_index, @output_buffer.bytesize - sep.bytesize].max
|
|
84
140
|
@output_buffer << produce_input
|
|
85
|
-
over_limit = number_of_bytes && @output_buffer.bytesize >= number_of_bytes
|
|
86
141
|
end
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
@pos +=
|
|
92
|
-
@output_buffer.slice!(0
|
|
142
|
+
|
|
143
|
+
limit ||= @output_buffer.bytesize
|
|
144
|
+
cut_index = sep_index ? [sep_index + sep.bytesize, limit].min : limit
|
|
145
|
+
@lineno = @lineno.next
|
|
146
|
+
@pos += cut_index
|
|
147
|
+
chomp ? @output_buffer.slice!(0, cut_index).chomp(sep) : @output_buffer.slice!(0, cut_index)
|
|
93
148
|
end
|
|
94
149
|
|
|
95
|
-
def ungetc(byte)
|
|
150
|
+
def ungetc(byte) # :nodoc:
|
|
96
151
|
@output_buffer = byte.chr + @output_buffer
|
|
97
152
|
end
|
|
98
153
|
|
|
99
|
-
def flush
|
|
100
|
-
|
|
101
|
-
@output_buffer = +''
|
|
102
|
-
ret_val
|
|
154
|
+
def flush # :nodoc:
|
|
155
|
+
@output_buffer.slice!(0..)
|
|
103
156
|
end
|
|
104
157
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
158
|
+
# Reads a line as with #gets, but raises `EOFError` if already at
|
|
159
|
+
# end-of-stream.
|
|
160
|
+
#
|
|
161
|
+
# Optional keyword argument `chomp` specifies whether line separators
|
|
162
|
+
# are to be omitted.
|
|
163
|
+
def readline(sep = $INPUT_RECORD_SEPARATOR, limit = nil, chomp: false)
|
|
164
|
+
raise EOFError if eof?
|
|
108
165
|
|
|
109
|
-
|
|
166
|
+
gets(sep, limit, chomp: chomp)
|
|
110
167
|
end
|
|
111
168
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
169
|
+
# Calls the block with each remaining line read from the stream.
|
|
170
|
+
# Does nothing if already at end-of-stream. See the Line IO
|
|
171
|
+
# documentation in the IO class for more information.
|
|
172
|
+
#
|
|
173
|
+
# With no arguments given, reads lines as determined by line separator
|
|
174
|
+
# `$/`. With only string argument `sep` given, reads lines as determined
|
|
175
|
+
# by line separator `sep`. See the Line Separator documentation in the
|
|
176
|
+
# IO class for more information. The two special values for `sep`
|
|
177
|
+
# (`nil` and `""`) are honoured.
|
|
178
|
+
#
|
|
179
|
+
# With only integer argument `limit` given, limits the number of bytes
|
|
180
|
+
# in each line; see the Line Limit documentation in the IO class for
|
|
181
|
+
# more information.
|
|
182
|
+
#
|
|
183
|
+
# With arguments `sep` and `limit` given, combines the two behaviors.
|
|
184
|
+
#
|
|
185
|
+
# Optional keyword argument `chomp` specifies whether line separators
|
|
186
|
+
# are to be omitted.
|
|
187
|
+
#
|
|
188
|
+
# Returns an `Enumerator` if no block is given.
|
|
189
|
+
def each(sep = $INPUT_RECORD_SEPARATOR, limit = nil, chomp: false)
|
|
190
|
+
return to_enum(:each, sep, limit, chomp: chomp) unless block_given?
|
|
191
|
+
|
|
192
|
+
while (line = gets(sep, limit, chomp: chomp))
|
|
193
|
+
yield line
|
|
194
|
+
end
|
|
116
195
|
end
|
|
117
196
|
|
|
118
|
-
alias each
|
|
197
|
+
alias each_line each
|
|
119
198
|
|
|
199
|
+
# Returns `true` if the stream is positioned at its end, `false`
|
|
200
|
+
# otherwise. See Position documentation in the IO class for more
|
|
201
|
+
# information.
|
|
120
202
|
def eof?
|
|
121
203
|
@output_buffer.empty? && input_finished?
|
|
122
204
|
end
|
|
123
205
|
|
|
124
206
|
# Alias for compatibility. Remove for version 4.
|
|
125
|
-
alias eof eof?
|
|
207
|
+
alias eof eof? # :nodoc:
|
|
126
208
|
end
|
|
127
209
|
end
|
|
128
210
|
end
|
|
@@ -7,15 +7,15 @@ module Zip
|
|
|
7
7
|
@read_so_far = 0
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def read(
|
|
11
|
-
return (
|
|
10
|
+
def read(maxlen = nil)
|
|
11
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
12
12
|
|
|
13
|
-
if
|
|
14
|
-
|
|
13
|
+
if maxlen.nil? || (@read_so_far + maxlen) > decompressed_size
|
|
14
|
+
maxlen = decompressed_size - @read_so_far
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
@read_so_far +=
|
|
18
|
-
input_stream.read(
|
|
17
|
+
@read_so_far += maxlen
|
|
18
|
+
input_stream.read(maxlen)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def eof?
|
data/lib/zip/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubyzip
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robert Haines
|
|
@@ -195,9 +195,9 @@ licenses:
|
|
|
195
195
|
- BSD-2-Clause
|
|
196
196
|
metadata:
|
|
197
197
|
bug_tracker_uri: https://github.com/rubyzip/rubyzip/issues
|
|
198
|
-
changelog_uri: https://github.com/rubyzip/rubyzip/blob/v3.
|
|
199
|
-
documentation_uri: https://www.rubydoc.info/gems/rubyzip/3.
|
|
200
|
-
source_code_uri: https://github.com/rubyzip/rubyzip/tree/v3.
|
|
198
|
+
changelog_uri: https://github.com/rubyzip/rubyzip/blob/v3.3.0/Changelog.md
|
|
199
|
+
documentation_uri: https://www.rubydoc.info/gems/rubyzip/3.3.0
|
|
200
|
+
source_code_uri: https://github.com/rubyzip/rubyzip/tree/v3.3.0
|
|
201
201
|
wiki_uri: https://github.com/rubyzip/rubyzip/wiki
|
|
202
202
|
rubygems_mfa_required: 'true'
|
|
203
203
|
rdoc_options: []
|