rubyzip 2.2.0 → 2.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/Rakefile +3 -0
- data/lib/zip.rb +1 -0
- data/lib/zip/central_directory.rb +9 -5
- data/lib/zip/constants.rb +18 -18
- data/lib/zip/crypto/decrypted_io.rb +4 -3
- data/lib/zip/crypto/traditional_encryption.rb +9 -9
- data/lib/zip/dos_time.rb +7 -7
- data/lib/zip/entry.rb +35 -28
- data/lib/zip/entry_set.rb +2 -0
- data/lib/zip/extra_field.rb +11 -9
- data/lib/zip/extra_field/generic.rb +9 -8
- 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 +3 -0
- data/lib/zip/extra_field/unix.rb +3 -1
- data/lib/zip/extra_field/zip64.rb +4 -2
- data/lib/zip/file.rb +49 -38
- data/lib/zip/filesystem.rb +193 -177
- data/lib/zip/inflater.rb +5 -3
- data/lib/zip/input_stream.rb +6 -3
- data/lib/zip/ioextras.rb +1 -1
- data/lib/zip/ioextras/abstract_input_stream.rb +14 -9
- data/lib/zip/ioextras/abstract_output_stream.rb +1 -1
- data/lib/zip/output_stream.rb +14 -5
- data/lib/zip/pass_thru_compressor.rb +2 -2
- data/lib/zip/pass_thru_decompressor.rb +2 -2
- data/lib/zip/streamable_directory.rb +3 -3
- data/lib/zip/streamable_stream.rb +5 -4
- 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 +25 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
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/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
@@ -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
@@ -87,29 +87,29 @@ module Zip
|
|
87
87
|
COMPRESSION_METHOD_AES = 99
|
88
88
|
|
89
89
|
COMPRESSION_METHODS = {
|
90
|
-
COMPRESSION_METHOD_STORE
|
91
|
-
COMPRESSION_METHOD_SHRINK
|
92
|
-
COMPRESSION_METHOD_REDUCE_1
|
93
|
-
COMPRESSION_METHOD_REDUCE_2
|
94
|
-
COMPRESSION_METHOD_REDUCE_3
|
95
|
-
COMPRESSION_METHOD_REDUCE_4
|
96
|
-
COMPRESSION_METHOD_IMPLODE
|
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
97
|
# RESERVED = 7
|
98
|
-
COMPRESSION_METHOD_DEFLATE
|
99
|
-
COMPRESSION_METHOD_DEFLATE_64
|
98
|
+
COMPRESSION_METHOD_DEFLATE => 'Deflate',
|
99
|
+
COMPRESSION_METHOD_DEFLATE_64 => 'Deflate64(tm)',
|
100
100
|
COMPRESSION_METHOD_PKWARE_DCLI => 'PKWARE Data Compression Library Imploding (old IBM TERSE)',
|
101
101
|
# RESERVED = 11
|
102
|
-
COMPRESSION_METHOD_BZIP2
|
102
|
+
COMPRESSION_METHOD_BZIP2 => 'BZIP2',
|
103
103
|
# RESERVED = 13
|
104
|
-
COMPRESSION_METHOD_LZMA
|
104
|
+
COMPRESSION_METHOD_LZMA => 'LZMA',
|
105
105
|
# RESERVED = 15
|
106
|
-
COMPRESSION_METHOD_IBM_CMPSC
|
106
|
+
COMPRESSION_METHOD_IBM_CMPSC => 'IBM z/OS CMPSC Compression',
|
107
107
|
# RESERVED = 17
|
108
|
-
COMPRESSION_METHOD_IBM_TERSE
|
109
|
-
COMPRESSION_METHOD_IBM_LZ77
|
110
|
-
COMPRESSION_METHOD_JPEG
|
111
|
-
COMPRESSION_METHOD_WAVPACK
|
112
|
-
COMPRESSION_METHOD_PPMD
|
113
|
-
COMPRESSION_METHOD_AES
|
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
114
|
}.freeze
|
115
115
|
end
|
@@ -7,11 +7,12 @@ module Zip
|
|
7
7
|
@decrypter = decrypter
|
8
8
|
end
|
9
9
|
|
10
|
-
def read(length = nil, outbuf = '')
|
11
|
-
return (
|
10
|
+
def read(length = nil, outbuf = +'')
|
11
|
+
return (length.nil? || length.zero? ? '' : nil) if eof
|
12
12
|
|
13
13
|
while length.nil? || (buffer.bytesize < length)
|
14
14
|
break if input_finished?
|
15
|
+
|
15
16
|
buffer << produce_input
|
16
17
|
end
|
17
18
|
|
@@ -25,7 +26,7 @@ module Zip
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def buffer
|
28
|
-
@buffer ||= ''
|
29
|
+
@buffer ||= +''
|
29
30
|
end
|
30
31
|
|
31
32
|
def input_finished?
|
@@ -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
|
data/lib/zip/dos_time.rb
CHANGED
@@ -34,13 +34,13 @@ module Zip
|
|
34
34
|
local(time.year, time.month, time.day, time.hour, time.min, time.sec)
|
35
35
|
end
|
36
36
|
|
37
|
-
def self.parse_binary_dos_format(
|
38
|
-
second = 2 * (0b11111 &
|
39
|
-
minute = (0b11111100000 &
|
40
|
-
hour = (0b1111100000000000 &
|
41
|
-
day = (0b11111 &
|
42
|
-
month = (0b111100000 &
|
43
|
-
year = ((0b1111111000000000 &
|
37
|
+
def self.parse_binary_dos_format(bin_dos_date, bin_dos_time)
|
38
|
+
second = 2 * (0b11111 & bin_dos_time)
|
39
|
+
minute = (0b11111100000 & bin_dos_time) >> 5
|
40
|
+
hour = (0b1111100000000000 & bin_dos_time) >> 11
|
41
|
+
day = (0b11111 & bin_dos_date)
|
42
|
+
month = (0b111100000 & bin_dos_date) >> 5
|
43
|
+
year = ((0b1111111000000000 & bin_dos_date) >> 9) + 1980
|
44
44
|
begin
|
45
45
|
local(year, month, day, hour, minute, second)
|
46
46
|
end
|
data/lib/zip/entry.rb
CHANGED
@@ -48,6 +48,7 @@ module Zip
|
|
48
48
|
|
49
49
|
def check_name(name)
|
50
50
|
return unless name.start_with?('/')
|
51
|
+
|
51
52
|
raise ::Zip::EntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
|
52
53
|
end
|
53
54
|
|
@@ -69,7 +70,7 @@ module Zip
|
|
69
70
|
@time = args[8] || ::Zip::DOSTime.now
|
70
71
|
|
71
72
|
@ftype = name_is_directory? ? :directory : :file
|
72
|
-
@extra = ::Zip::ExtraField.new(@extra.to_s) unless @extra.
|
73
|
+
@extra = ::Zip::ExtraField.new(@extra.to_s) unless @extra.kind_of?(::Zip::ExtraField)
|
73
74
|
end
|
74
75
|
|
75
76
|
def encrypted?
|
@@ -99,11 +100,12 @@ module Zip
|
|
99
100
|
@extra.create('UniversalTime')
|
100
101
|
end
|
101
102
|
(@extra['UniversalTime'] || @extra['NTFS']).mtime = value
|
102
|
-
@time
|
103
|
+
@time = value
|
103
104
|
end
|
104
105
|
|
105
106
|
def file_type_is?(type)
|
106
107
|
raise InternalError, "current filetype is unknown: #{inspect}" unless @ftype
|
108
|
+
|
107
109
|
@ftype == type
|
108
110
|
end
|
109
111
|
|
@@ -124,6 +126,7 @@ module Zip
|
|
124
126
|
def name_safe?
|
125
127
|
cleanpath = Pathname.new(@name).cleanpath
|
126
128
|
return false unless cleanpath.relative?
|
129
|
+
|
127
130
|
root = ::File::SEPARATOR
|
128
131
|
naive_expanded_path = ::File.join(root, cleanpath.to_s)
|
129
132
|
::File.absolute_path(cleanpath.to_s, root) == naive_expanded_path
|
@@ -153,6 +156,7 @@ module Zip
|
|
153
156
|
# that we didn't change the header size (and thus clobber file data or something)
|
154
157
|
def verify_local_header_size!
|
155
158
|
return if @local_header_size.nil?
|
159
|
+
|
156
160
|
new_size = calculate_local_header_size
|
157
161
|
raise Error, "local header size changed (#{@local_header_size} -> #{new_size})" if @local_header_size != new_size
|
158
162
|
end
|
@@ -178,12 +182,9 @@ module Zip
|
|
178
182
|
dest_path ||= @name
|
179
183
|
block ||= proc { ::Zip.on_exists_proc }
|
180
184
|
|
181
|
-
|
182
|
-
__send__("create_#{@ftype}", dest_path, &block)
|
183
|
-
else
|
184
|
-
raise "unknown file type #{inspect}"
|
185
|
-
end
|
185
|
+
raise "unknown file type #{inspect}" unless directory? || file? || symlink?
|
186
186
|
|
187
|
+
__send__("create_#{@ftype}", dest_path, &block)
|
187
188
|
self
|
188
189
|
end
|
189
190
|
|
@@ -193,15 +194,15 @@ module Zip
|
|
193
194
|
|
194
195
|
class << self
|
195
196
|
def read_zip_short(io) # :nodoc:
|
196
|
-
io.read(2).
|
197
|
+
io.read(2).unpack1('v')
|
197
198
|
end
|
198
199
|
|
199
200
|
def read_zip_long(io) # :nodoc:
|
200
|
-
io.read(4).
|
201
|
+
io.read(4).unpack1('V')
|
201
202
|
end
|
202
203
|
|
203
204
|
def read_zip_64_long(io) # :nodoc:
|
204
|
-
io.read(8).
|
205
|
+
io.read(8).unpack1('Q<')
|
205
206
|
end
|
206
207
|
|
207
208
|
def read_c_dir_entry(io) #:nodoc:all
|
@@ -226,8 +227,6 @@ module Zip
|
|
226
227
|
end
|
227
228
|
end
|
228
229
|
|
229
|
-
public
|
230
|
-
|
231
230
|
def unpack_local_entry(buf)
|
232
231
|
@header_signature,
|
233
232
|
@version,
|
@@ -257,6 +256,7 @@ module Zip
|
|
257
256
|
unless @header_signature == ::Zip::LOCAL_ENTRY_SIGNATURE
|
258
257
|
raise ::Zip::Error, "Zip local header magic not found at location '#{local_header_offset}'"
|
259
258
|
end
|
259
|
+
|
260
260
|
set_time(@last_mod_date, @last_mod_time)
|
261
261
|
|
262
262
|
@name = io.read(@name_length)
|
@@ -269,13 +269,14 @@ module Zip
|
|
269
269
|
|
270
270
|
if extra && extra.bytesize != @extra_length
|
271
271
|
raise ::Zip::Error, 'Truncated local zip entry header'
|
272
|
+
end
|
273
|
+
|
274
|
+
if @extra.kind_of?(::Zip::ExtraField)
|
275
|
+
@extra.merge(extra) if extra
|
272
276
|
else
|
273
|
-
|
274
|
-
@extra.merge(extra) if extra
|
275
|
-
else
|
276
|
-
@extra = ::Zip::ExtraField.new(extra)
|
277
|
-
end
|
277
|
+
@extra = ::Zip::ExtraField.new(extra)
|
278
278
|
end
|
279
|
+
|
279
280
|
parse_zip64_extra(true)
|
280
281
|
@local_header_size = calculate_local_header_size
|
281
282
|
end
|
@@ -362,21 +363,24 @@ module Zip
|
|
362
363
|
|
363
364
|
def check_c_dir_entry_static_header_length(buf)
|
364
365
|
return if buf.bytesize == ::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH
|
366
|
+
|
365
367
|
raise Error, 'Premature end of file. Not enough data for zip cdir entry header'
|
366
368
|
end
|
367
369
|
|
368
370
|
def check_c_dir_entry_signature
|
369
371
|
return if header_signature == ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
|
372
|
+
|
370
373
|
raise Error, "Zip local header magic not found at location '#{local_header_offset}'"
|
371
374
|
end
|
372
375
|
|
373
376
|
def check_c_dir_entry_comment_size
|
374
377
|
return if @comment && @comment.bytesize == @comment_length
|
378
|
+
|
375
379
|
raise ::Zip::Error, 'Truncated cdir zip entry header'
|
376
380
|
end
|
377
381
|
|
378
382
|
def read_c_dir_extra_field(io)
|
379
|
-
if @extra.
|
383
|
+
if @extra.kind_of?(::Zip::ExtraField)
|
380
384
|
@extra.merge(io.read(@extra_length))
|
381
385
|
else
|
382
386
|
@extra = ::Zip::ExtraField.new(io.read(@extra_length))
|
@@ -410,6 +414,7 @@ module Zip
|
|
410
414
|
|
411
415
|
def get_extra_attributes_from_path(path) # :nodoc:
|
412
416
|
return if Zip::RUNNING_ON_WINDOWS
|
417
|
+
|
413
418
|
stat = file_stat(path)
|
414
419
|
@unix_uid = stat.uid
|
415
420
|
@unix_gid = stat.gid
|
@@ -496,6 +501,7 @@ module Zip
|
|
496
501
|
|
497
502
|
def ==(other)
|
498
503
|
return false unless other.class == self.class
|
504
|
+
|
499
505
|
# Compares contents of local entry and exposed fields
|
500
506
|
keys_equal = %w[compression_method crc compressed_size size name extra filepath].all? do |k|
|
501
507
|
other.__send__(k.to_sym) == __send__(k.to_sym)
|
@@ -615,19 +621,17 @@ module Zip
|
|
615
621
|
get_input_stream do |is|
|
616
622
|
bytes_written = 0
|
617
623
|
warned = false
|
618
|
-
buf = ''
|
624
|
+
buf = +''
|
619
625
|
while (buf = is.sysread(::Zip::Decompressor::CHUNK_SIZE, buf))
|
620
626
|
os << buf
|
621
627
|
bytes_written += buf.bytesize
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
end
|
630
|
-
end
|
628
|
+
next unless bytes_written > size && !warned
|
629
|
+
|
630
|
+
message = "entry '#{name}' should be #{size}B, but is larger when inflated."
|
631
|
+
raise ::Zip::EntrySizeError, message if ::Zip.validate_entry_sizes
|
632
|
+
|
633
|
+
warn "WARNING: #{message}"
|
634
|
+
warned = true
|
631
635
|
end
|
632
636
|
end
|
633
637
|
end
|
@@ -637,6 +641,7 @@ module Zip
|
|
637
641
|
|
638
642
|
def create_directory(dest_path)
|
639
643
|
return if ::File.directory?(dest_path)
|
644
|
+
|
640
645
|
if ::File.exist?(dest_path)
|
641
646
|
if block_given? && yield(self, dest_path)
|
642
647
|
::FileUtils.rm_f dest_path
|
@@ -661,6 +666,7 @@ module Zip
|
|
661
666
|
# (required when file sizes exceed 2**32, but can be used for all files)
|
662
667
|
def parse_zip64_extra(for_local_header) #:nodoc:all
|
663
668
|
return if @extra['Zip64'].nil?
|
669
|
+
|
664
670
|
if for_local_header
|
665
671
|
@size, @compressed_size = @extra['Zip64'].parse(@size, @compressed_size)
|
666
672
|
else
|
@@ -675,6 +681,7 @@ module Zip
|
|
675
681
|
# create a zip64 extra information field if we need one
|
676
682
|
def prep_zip64_extra(for_local_header) #:nodoc:all
|
677
683
|
return unless ::Zip.write_zip64_support
|
684
|
+
|
678
685
|
need_zip64 = @size >= 0xFFFFFFFF || @compressed_size >= 0xFFFFFFFF
|
679
686
|
need_zip64 ||= @local_header_offset >= 0xFFFFFFFF unless for_local_header
|
680
687
|
if need_zip64
|
data/lib/zip/entry_set.rb
CHANGED
@@ -50,6 +50,7 @@ module Zip
|
|
50
50
|
|
51
51
|
def ==(other)
|
52
52
|
return false unless other.kind_of?(EntrySet)
|
53
|
+
|
53
54
|
@entry_set.values == other.entry_set.values
|
54
55
|
end
|
55
56
|
|
@@ -60,6 +61,7 @@ module Zip
|
|
60
61
|
def glob(pattern, flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB)
|
61
62
|
entries.map do |entry|
|
62
63
|
next nil unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags)
|
64
|
+
|
63
65
|
yield(entry) if block_given?
|
64
66
|
entry
|
65
67
|
end.compact
|
data/lib/zip/extra_field.rb
CHANGED
@@ -6,27 +6,27 @@ module Zip
|
|
6
6
|
merge(binstr) if binstr
|
7
7
|
end
|
8
8
|
|
9
|
-
def extra_field_type_exist(binstr, id, len,
|
9
|
+
def extra_field_type_exist(binstr, id, len, index)
|
10
10
|
field_name = ID_MAP[id].name
|
11
11
|
if member?(field_name)
|
12
|
-
self[field_name].merge(binstr[
|
12
|
+
self[field_name].merge(binstr[index, len + 4])
|
13
13
|
else
|
14
|
-
field_obj = ID_MAP[id].new(binstr[
|
14
|
+
field_obj = ID_MAP[id].new(binstr[index, len + 4])
|
15
15
|
self[field_name] = field_obj
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def extra_field_type_unknown(binstr, len,
|
19
|
+
def extra_field_type_unknown(binstr, len, index)
|
20
20
|
create_unknown_item unless self['Unknown']
|
21
|
-
if !len || len + 4 > binstr[
|
22
|
-
self['Unknown'] << binstr[
|
21
|
+
if !len || len + 4 > binstr[index..-1].bytesize
|
22
|
+
self['Unknown'] << binstr[index..-1]
|
23
23
|
return
|
24
24
|
end
|
25
|
-
self['Unknown'] << binstr[
|
25
|
+
self['Unknown'] << binstr[index, len + 4]
|
26
26
|
end
|
27
27
|
|
28
28
|
def create_unknown_item
|
29
|
-
s = ''
|
29
|
+
s = +''
|
30
30
|
class << s
|
31
31
|
alias_method :to_c_dir_bin, :to_s
|
32
32
|
alias_method :to_local_bin, :to_s
|
@@ -36,10 +36,11 @@ module Zip
|
|
36
36
|
|
37
37
|
def merge(binstr)
|
38
38
|
return if binstr.empty?
|
39
|
+
|
39
40
|
i = 0
|
40
41
|
while i < binstr.bytesize
|
41
42
|
id = binstr[i, 2]
|
42
|
-
len = binstr[i + 2, 2].to_s.
|
43
|
+
len = binstr[i + 2, 2].to_s.unpack1('v')
|
43
44
|
if id && ID_MAP.member?(id)
|
44
45
|
extra_field_type_exist(binstr, id, len, i)
|
45
46
|
elsif id
|
@@ -54,6 +55,7 @@ module Zip
|
|
54
55
|
unless (field_class = ID_MAP.values.find { |k| k.name == name })
|
55
56
|
raise Error, "Unknown extra field '#{name}'"
|
56
57
|
end
|
58
|
+
|
57
59
|
self[name] = field_class.new
|
58
60
|
end
|
59
61
|
|