rubyzip 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|