rubyzip 1.3.0 → 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 +123 -46
- data/Rakefile +13 -6
- data/lib/zip/central_directory.rb +166 -116
- data/lib/zip/compressor.rb +3 -1
- data/lib/zip/constants.rb +77 -21
- data/lib/zip/crypto/decrypted_io.rb +42 -0
- data/lib/zip/crypto/encryption.rb +4 -2
- data/lib/zip/crypto/null_encryption.rb +5 -3
- data/lib/zip/crypto/traditional_encryption.rb +14 -12
- data/lib/zip/decompressor.rb +21 -2
- data/lib/zip/deflater.rb +10 -8
- data/lib/zip/dirtyable.rb +32 -0
- data/lib/zip/dos_time.rb +53 -12
- data/lib/zip/entry.rb +306 -184
- data/lib/zip/entry_set.rb +11 -7
- data/lib/zip/errors.rb +115 -15
- data/lib/zip/extra_field/generic.rb +11 -17
- data/lib/zip/extra_field/ntfs.rb +8 -2
- data/lib/zip/extra_field/old_unix.rb +6 -2
- data/lib/zip/extra_field/universal_time.rb +45 -13
- data/lib/zip/extra_field/unix.rb +7 -3
- data/lib/zip/extra_field/unknown.rb +33 -0
- data/lib/zip/extra_field/zip64.rb +16 -7
- data/lib/zip/extra_field.rb +22 -26
- data/lib/zip/file.rb +196 -240
- 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 +31 -584
- data/lib/zip/inflater.rb +27 -37
- data/lib/zip/input_stream.rb +67 -42
- data/lib/zip/ioextras/abstract_input_stream.rb +32 -16
- data/lib/zip/ioextras/abstract_output_stream.rb +5 -3
- data/lib/zip/ioextras.rb +7 -7
- data/lib/zip/null_compressor.rb +3 -1
- data/lib/zip/null_decompressor.rb +4 -10
- data/lib/zip/null_input_stream.rb +3 -1
- data/lib/zip/output_stream.rb +58 -43
- data/lib/zip/pass_thru_compressor.rb +5 -3
- data/lib/zip/pass_thru_decompressor.rb +16 -23
- data/lib/zip/streamable_directory.rb +6 -4
- data/lib/zip/streamable_stream.rb +9 -10
- data/lib/zip/version.rb +3 -1
- data/lib/zip.rb +19 -4
- data/rubyzip.gemspec +38 -0
- data/samples/example.rb +9 -4
- data/samples/example_filesystem.rb +3 -2
- data/samples/example_recursive.rb +3 -1
- data/samples/gtk_ruby_zip.rb +22 -20
- data/samples/qtzip.rb +12 -11
- data/samples/write_simple.rb +3 -4
- data/samples/zipfind.rb +24 -22
- metadata +86 -179
- data/TODO +0 -15
- data/lib/zip/extra_field/zip64_placeholder.rb +0 -15
- 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/foo/bar/baz/foo.txt +0 -0
- data/test/data/globTest/foo.txt +0 -0
- data/test/data/globTest/food.txt +0 -0
- data/test/data/globTest.zip +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/tilde.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 -145
- data/test/file_permissions_test.rb +0 -65
- data/test/file_split_test.rb +0 -57
- data/test/file_test.rb +0 -666
- 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 -141
- 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
data/lib/zip/inflater.rb
CHANGED
@@ -1,64 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zip
|
2
|
-
class Inflater < Decompressor
|
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
|
4
|
+
class Inflater < Decompressor # :nodoc:all
|
5
|
+
def initialize(*args)
|
6
|
+
super
|
10
7
|
|
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)
|
8
|
+
@buffer = +''
|
9
|
+
@zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
20
10
|
end
|
21
11
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
12
|
+
def read(length = nil, outbuf = +'')
|
13
|
+
return (length.nil? || length.zero? ? '' : nil) if eof
|
14
|
+
|
15
|
+
while length.nil? || (@buffer.bytesize < length)
|
16
|
+
break if input_finished?
|
17
|
+
|
18
|
+
@buffer << produce_input
|
27
19
|
end
|
20
|
+
|
21
|
+
outbuf.replace(@buffer.slice!(0...(length || @buffer.bytesize)))
|
28
22
|
end
|
29
23
|
|
30
|
-
|
31
|
-
|
32
|
-
def input_finished?
|
33
|
-
@output_buffer.empty? && internal_input_finished?
|
24
|
+
def eof
|
25
|
+
@buffer.empty? && input_finished?
|
34
26
|
end
|
35
27
|
|
36
|
-
alias
|
37
|
-
alias :eof? input_finished?
|
28
|
+
alias eof? eof
|
38
29
|
|
39
30
|
private
|
40
31
|
|
41
|
-
def
|
32
|
+
def produce_input
|
42
33
|
retried = 0
|
43
34
|
begin
|
44
|
-
@zlib_inflater.inflate(
|
35
|
+
@zlib_inflater.inflate(input_stream.read(Decompressor::CHUNK_SIZE))
|
45
36
|
rescue Zlib::BufError
|
46
37
|
raise if retried >= 5 # how many times should we retry?
|
38
|
+
|
47
39
|
retried += 1
|
48
40
|
retry
|
49
41
|
end
|
42
|
+
rescue Zlib::Error => e
|
43
|
+
raise ::Zip::DecompressionError, e
|
50
44
|
end
|
51
45
|
|
52
|
-
def
|
46
|
+
def input_finished?
|
53
47
|
@zlib_inflater.finished?
|
54
48
|
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
49
|
end
|
50
|
+
|
51
|
+
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_DEFLATE, ::Zip::Inflater)
|
62
52
|
end
|
63
53
|
|
64
54
|
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
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,
|
@@ -39,6 +41,8 @@ module Zip
|
|
39
41
|
# class.
|
40
42
|
|
41
43
|
class InputStream
|
44
|
+
CHUNK_SIZE = 32_768
|
45
|
+
|
42
46
|
include ::Zip::IOExtras::AbstractInputStream
|
43
47
|
|
44
48
|
# Opens the indicated zip file. An exception is thrown
|
@@ -47,30 +51,37 @@ module Zip
|
|
47
51
|
#
|
48
52
|
# @param context [String||IO||StringIO] file path or IO/StringIO object
|
49
53
|
# @param offset [Integer] offset in the IO/StringIO
|
50
|
-
def initialize(context, offset
|
54
|
+
def initialize(context, offset: 0, decrypter: nil)
|
51
55
|
super()
|
52
56
|
@archive_io = get_io(context, offset)
|
53
|
-
@decompressor
|
54
|
-
@decrypter
|
57
|
+
@decompressor = ::Zip::NullDecompressor
|
58
|
+
@decrypter = decrypter || ::Zip::NullDecrypter.new
|
55
59
|
@current_entry = nil
|
60
|
+
@complete_entry = nil
|
56
61
|
end
|
57
62
|
|
58
63
|
def close
|
59
64
|
@archive_io.close
|
60
65
|
end
|
61
66
|
|
62
|
-
# Returns
|
63
|
-
# method on a newly created
|
64
|
-
# the first entry in the archive.
|
65
|
-
# 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.
|
66
71
|
def get_next_entry
|
67
|
-
@
|
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
|
+
|
68
78
|
open_entry
|
69
79
|
end
|
70
80
|
|
71
81
|
# Rewinds the stream to the beginning of the current entry
|
72
82
|
def rewind
|
73
83
|
return if @current_entry.nil?
|
84
|
+
|
74
85
|
@lineno = 0
|
75
86
|
@pos = 0
|
76
87
|
@archive_io.seek(@current_entry.local_header_offset, IO::SEEK_SET)
|
@@ -78,23 +89,25 @@ module Zip
|
|
78
89
|
end
|
79
90
|
|
80
91
|
# Modeled after IO.sysread
|
81
|
-
def sysread(
|
82
|
-
@decompressor.
|
92
|
+
def sysread(length = nil, outbuf = '')
|
93
|
+
@decompressor.read(length, outbuf)
|
83
94
|
end
|
84
95
|
|
85
|
-
|
86
|
-
|
87
|
-
|
96
|
+
# Returns the size of the current entry, or `nil` if there isn't one.
|
97
|
+
def size
|
98
|
+
return if @current_entry.nil?
|
88
99
|
|
89
|
-
|
100
|
+
@current_entry.size
|
101
|
+
end
|
90
102
|
|
91
103
|
class << self
|
92
104
|
# Same as #initialize but if a block is passed the opened
|
93
105
|
# stream is passed to the block and closed when the block
|
94
106
|
# returns.
|
95
|
-
def open(filename_or_io, offset
|
96
|
-
zio = new(filename_or_io, offset, decrypter)
|
107
|
+
def open(filename_or_io, offset: 0, decrypter: nil)
|
108
|
+
zio = new(filename_or_io, offset: offset, decrypter: decrypter)
|
97
109
|
return zio unless block_given?
|
110
|
+
|
98
111
|
begin
|
99
112
|
yield zio
|
100
113
|
ensure
|
@@ -102,9 +115,9 @@ module Zip
|
|
102
115
|
end
|
103
116
|
end
|
104
117
|
|
105
|
-
def open_buffer(filename_or_io, offset
|
106
|
-
|
107
|
-
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)
|
108
121
|
end
|
109
122
|
end
|
110
123
|
|
@@ -124,46 +137,58 @@ module Zip
|
|
124
137
|
|
125
138
|
def open_entry
|
126
139
|
@current_entry = ::Zip::Entry.read_local_entry(@archive_io)
|
127
|
-
if @current_entry
|
128
|
-
|
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'
|
129
145
|
end
|
130
|
-
|
131
|
-
|
132
|
-
&&
|
133
|
-
raise
|
134
|
-
'General purpose flag Bit 3 is set so not possible to get proper info from local header.' \
|
135
|
-
'Please use ::Zip::File instead of ::Zip::InputStream'
|
146
|
+
|
147
|
+
if @current_entry.incomplete? && @current_entry.compressed_size == 0 \
|
148
|
+
&& !@complete_entry
|
149
|
+
raise StreamingError, @current_entry
|
136
150
|
end
|
151
|
+
|
152
|
+
@decrypted_io = get_decrypted_io
|
137
153
|
@decompressor = get_decompressor
|
138
154
|
flush
|
139
155
|
@current_entry
|
140
156
|
end
|
141
157
|
|
158
|
+
def get_decrypted_io
|
159
|
+
header = @archive_io.read(@decrypter.header_bytesize)
|
160
|
+
@decrypter.reset!(header)
|
161
|
+
|
162
|
+
::Zip::DecryptedIo.new(@archive_io, @decrypter)
|
163
|
+
end
|
164
|
+
|
142
165
|
def get_decompressor
|
143
|
-
if @current_entry.nil?
|
144
|
-
|
145
|
-
|
146
|
-
if @current_entry.
|
147
|
-
|
166
|
+
return ::Zip::NullDecompressor if @current_entry.nil?
|
167
|
+
|
168
|
+
decompressed_size =
|
169
|
+
if @current_entry.incomplete? && @current_entry.crc == 0 \
|
170
|
+
&& @current_entry.size == 0 && @complete_entry
|
171
|
+
@complete_entry.size
|
148
172
|
else
|
149
|
-
|
173
|
+
@current_entry.size
|
150
174
|
end
|
151
|
-
|
152
|
-
|
153
|
-
@
|
154
|
-
|
155
|
-
|
156
|
-
raise ::Zip::CompressionMethodError,
|
157
|
-
"Unsupported compression method #{@current_entry.compression_method}"
|
175
|
+
|
176
|
+
decompressor_class = ::Zip::Decompressor.find_by_compression_method(
|
177
|
+
@current_entry.compression_method
|
178
|
+
)
|
179
|
+
if decompressor_class.nil?
|
180
|
+
raise ::Zip::CompressionMethodError, @current_entry.compression_method
|
158
181
|
end
|
182
|
+
|
183
|
+
decompressor_class.new(@decrypted_io, decompressed_size)
|
159
184
|
end
|
160
185
|
|
161
186
|
def produce_input
|
162
|
-
@decompressor.
|
187
|
+
@decompressor.read(CHUNK_SIZE)
|
163
188
|
end
|
164
189
|
|
165
190
|
def input_finished?
|
166
|
-
@decompressor.
|
191
|
+
@decompressor.eof
|
167
192
|
end
|
168
193
|
end
|
169
194
|
end
|
@@ -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,15 +13,15 @@ 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
|
@@ -34,7 +36,8 @@ 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?
|
40
|
+
|
38
41
|
return ''
|
39
42
|
end
|
40
43
|
|
@@ -48,13 +51,13 @@ module Zip
|
|
48
51
|
buf
|
49
52
|
end
|
50
53
|
|
51
|
-
def readlines(a_sep_string =
|
54
|
+
def readlines(a_sep_string = $INPUT_RECORD_SEPARATOR)
|
52
55
|
ret_val = []
|
53
56
|
each_line(a_sep_string) { |line| ret_val << line }
|
54
57
|
ret_val
|
55
58
|
end
|
56
59
|
|
57
|
-
def gets(a_sep_string =
|
60
|
+
def gets(a_sep_string = $INPUT_RECORD_SEPARATOR, number_of_bytes = nil)
|
58
61
|
@lineno = @lineno.next
|
59
62
|
|
60
63
|
if number_of_bytes.respond_to?(:to_int)
|
@@ -62,24 +65,29 @@ module Zip
|
|
62
65
|
a_sep_string = a_sep_string.to_str if a_sep_string
|
63
66
|
elsif a_sep_string.respond_to?(:to_int)
|
64
67
|
number_of_bytes = a_sep_string.to_int
|
65
|
-
a_sep_string =
|
68
|
+
a_sep_string = $INPUT_RECORD_SEPARATOR
|
66
69
|
else
|
67
70
|
number_of_bytes = nil
|
68
71
|
a_sep_string = a_sep_string.to_str if a_sep_string
|
69
72
|
end
|
70
73
|
|
71
74
|
return read(number_of_bytes) if a_sep_string.nil?
|
72
|
-
|
75
|
+
|
76
|
+
a_sep_string = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}" if a_sep_string.empty?
|
73
77
|
|
74
78
|
buffer_index = 0
|
75
79
|
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
|
76
80
|
while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit
|
77
81
|
buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max
|
78
82
|
return @output_buffer.empty? ? nil : flush if input_finished?
|
83
|
+
|
79
84
|
@output_buffer << produce_input
|
80
85
|
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
|
81
86
|
end
|
82
|
-
sep_index = [
|
87
|
+
sep_index = [
|
88
|
+
match_index + a_sep_string.bytesize,
|
89
|
+
number_of_bytes || @output_buffer.bytesize
|
90
|
+
].min
|
83
91
|
@pos += sep_index
|
84
92
|
@output_buffer.slice!(0...sep_index)
|
85
93
|
end
|
@@ -90,22 +98,30 @@ module Zip
|
|
90
98
|
|
91
99
|
def flush
|
92
100
|
ret_val = @output_buffer
|
93
|
-
@output_buffer = ''
|
101
|
+
@output_buffer = +''
|
94
102
|
ret_val
|
95
103
|
end
|
96
104
|
|
97
|
-
def readline(a_sep_string =
|
105
|
+
def readline(a_sep_string = $INPUT_RECORD_SEPARATOR)
|
98
106
|
ret_val = gets(a_sep_string)
|
99
107
|
raise EOFError unless ret_val
|
108
|
+
|
100
109
|
ret_val
|
101
110
|
end
|
102
111
|
|
103
|
-
def each_line(a_sep_string =
|
104
|
-
yield readline(a_sep_string)
|
112
|
+
def each_line(a_sep_string = $INPUT_RECORD_SEPARATOR)
|
113
|
+
loop { yield readline(a_sep_string) }
|
105
114
|
rescue EOFError
|
115
|
+
# We just need to catch this; we don't need to handle it.
|
116
|
+
end
|
117
|
+
|
118
|
+
alias each each_line
|
119
|
+
|
120
|
+
def eof
|
121
|
+
@output_buffer.empty? && input_finished?
|
106
122
|
end
|
107
123
|
|
108
|
-
|
124
|
+
alias eof? eof
|
109
125
|
end
|
110
126
|
end
|
111
127
|
end
|
@@ -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,31 +1,31 @@
|
|
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, '')) until istream.eof?
|
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
|
27
27
|
end
|
28
|
-
end
|
28
|
+
end
|
29
29
|
end
|
30
30
|
|
31
31
|
require 'zip/ioextras/abstract_input_stream'
|
data/lib/zip/null_compressor.rb
CHANGED
@@ -1,19 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Zip
|
2
|
-
module NullDecompressor
|
4
|
+
module NullDecompressor # :nodoc:all
|
3
5
|
module_function
|
4
6
|
|
5
|
-
def
|
6
|
-
nil
|
7
|
-
end
|
8
|
-
|
9
|
-
def produce_input
|
7
|
+
def read(_length = nil, _outbuf = nil)
|
10
8
|
nil
|
11
9
|
end
|
12
10
|
|
13
|
-
def input_finished?
|
14
|
-
true
|
15
|
-
end
|
16
|
-
|
17
11
|
def eof
|
18
12
|
true
|
19
13
|
end
|