rubyzip 1.1.7 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubyzip might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +75 -40
- data/Rakefile +3 -4
- data/lib/zip.rb +3 -5
- data/lib/zip/central_directory.rb +7 -7
- data/lib/zip/compressor.rb +0 -0
- data/lib/zip/constants.rb +2 -2
- data/lib/zip/crypto/null_encryption.rb +3 -3
- data/lib/zip/crypto/traditional_encryption.rb +5 -5
- data/lib/zip/decompressor.rb +2 -2
- data/lib/zip/deflater.rb +8 -6
- data/lib/zip/dos_time.rb +4 -5
- data/lib/zip/entry.rb +75 -81
- data/lib/zip/entry_set.rb +11 -11
- data/lib/zip/errors.rb +1 -0
- data/lib/zip/extra_field.rb +6 -6
- data/lib/zip/extra_field/generic.rb +7 -7
- data/lib/zip/extra_field/ntfs.rb +14 -16
- data/lib/zip/extra_field/old_unix.rb +9 -10
- data/lib/zip/extra_field/universal_time.rb +14 -14
- data/lib/zip/extra_field/unix.rb +8 -9
- data/lib/zip/extra_field/zip64.rb +12 -11
- data/lib/zip/extra_field/zip64_placeholder.rb +1 -1
- data/lib/zip/file.rb +47 -60
- data/lib/zip/filesystem.rb +132 -135
- data/lib/zip/inflater.rb +3 -3
- data/lib/zip/input_stream.rb +13 -7
- data/lib/zip/ioextras.rb +1 -3
- data/lib/zip/ioextras/abstract_input_stream.rb +5 -9
- data/lib/zip/ioextras/abstract_output_stream.rb +2 -4
- data/lib/zip/null_compressor.rb +2 -2
- data/lib/zip/null_decompressor.rb +3 -3
- data/lib/zip/null_input_stream.rb +0 -0
- data/lib/zip/output_stream.rb +8 -9
- data/lib/zip/pass_thru_compressor.rb +4 -4
- data/lib/zip/pass_thru_decompressor.rb +2 -3
- data/lib/zip/streamable_directory.rb +2 -2
- data/lib/zip/streamable_stream.rb +2 -2
- data/lib/zip/version.rb +1 -1
- data/samples/example.rb +29 -39
- data/samples/example_filesystem.rb +16 -18
- data/samples/example_recursive.rb +32 -25
- data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +23 -25
- data/samples/qtzip.rb +17 -26
- data/samples/write_simple.rb +12 -13
- data/samples/zipfind.rb +24 -32
- data/test/basic_zip_file_test.rb +11 -15
- data/test/case_sensitivity_test.rb +69 -0
- data/test/central_directory_entry_test.rb +32 -36
- data/test/central_directory_test.rb +46 -50
- data/test/crypto/null_encryption_test.rb +8 -4
- data/test/crypto/traditional_encryption_test.rb +5 -5
- data/test/data/notzippedruby.rb +1 -1
- data/test/data/oddExtraField.zip +0 -0
- data/test/data/test.xls +0 -0
- data/test/deflater_test.rb +10 -12
- data/test/encryption_test.rb +2 -2
- data/test/entry_set_test.rb +50 -25
- data/test/entry_test.rb +76 -87
- data/test/errors_test.rb +0 -2
- data/test/extra_field_test.rb +19 -21
- data/test/file_extract_directory_test.rb +12 -14
- data/test/file_extract_test.rb +33 -40
- data/test/file_permissions_test.rb +69 -0
- data/test/file_split_test.rb +24 -27
- data/test/file_test.rb +196 -172
- data/test/filesystem/dir_iterator_test.rb +13 -17
- data/test/filesystem/directory_test.rb +80 -90
- data/test/filesystem/file_mutating_test.rb +51 -63
- data/test/filesystem/file_nonmutating_test.rb +222 -228
- data/test/filesystem/file_stat_test.rb +17 -19
- data/test/gentestfiles.rb +47 -55
- data/test/inflater_test.rb +1 -1
- data/test/input_stream_test.rb +46 -34
- data/test/ioextras/abstract_input_stream_test.rb +22 -23
- data/test/ioextras/abstract_output_stream_test.rb +32 -32
- data/test/ioextras/fake_io_test.rb +1 -1
- data/test/local_entry_test.rb +36 -38
- data/test/output_stream_test.rb +20 -21
- data/test/pass_thru_compressor_test.rb +5 -6
- data/test/pass_thru_decompressor_test.rb +0 -1
- data/test/samples/example_recursive_test.rb +37 -0
- data/test/settings_test.rb +18 -15
- data/test/test_helper.rb +50 -44
- data/test/unicode_file_names_and_comments_test.rb +5 -7
- data/test/zip64_full_test.rb +9 -11
- data/test/zip64_support_test.rb +0 -1
- metadata +14 -32
data/lib/zip/dos_time.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Zip
|
2
2
|
class DOSTime < Time #:nodoc:all
|
3
|
-
|
4
|
-
#MS-DOS File Date and Time format as used in Interrupt 21H Function 57H:
|
3
|
+
# MS-DOS File Date and Time format as used in Interrupt 21H Function 57H:
|
5
4
|
|
6
5
|
# Register CX, the Time:
|
7
6
|
# Bits 0-4 2 second increments (0-29)
|
@@ -14,7 +13,7 @@ module Zip
|
|
14
13
|
# bits 9-15 year (four digit year minus 1980)
|
15
14
|
|
16
15
|
def to_binary_dos_time
|
17
|
-
(sec/2) +
|
16
|
+
(sec / 2) +
|
18
17
|
(min << 5) +
|
19
18
|
(hour << 11)
|
20
19
|
end
|
@@ -27,7 +26,7 @@ module Zip
|
|
27
26
|
|
28
27
|
# Dos time is only stored with two seconds accuracy
|
29
28
|
def dos_equals(other)
|
30
|
-
to_i/2 == other.to_i/2
|
29
|
+
to_i / 2 == other.to_i / 2
|
31
30
|
end
|
32
31
|
|
33
32
|
def self.parse_binary_dos_format(binaryDosDate, binaryDosTime)
|
@@ -38,7 +37,7 @@ module Zip
|
|
38
37
|
month = (0b111100000 & binaryDosDate) >> 5
|
39
38
|
year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
|
40
39
|
begin
|
41
|
-
|
40
|
+
local(year, month, day, hour, minute, second)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|
data/lib/zip/entry.rb
CHANGED
@@ -7,6 +7,7 @@ module Zip
|
|
7
7
|
|
8
8
|
attr_accessor :comment, :compressed_size, :crc, :extra, :compression_method,
|
9
9
|
:name, :size, :local_header_offset, :zipfile, :fstype, :external_file_attributes,
|
10
|
+
:internal_file_attributes,
|
10
11
|
:gp_flags, :header_signature, :follow_symlinks,
|
11
12
|
:restore_times, :restore_permissions, :restore_ownership,
|
12
13
|
:unix_uid, :unix_gid, :unix_perms,
|
@@ -39,15 +40,14 @@ module Zip
|
|
39
40
|
@unix_uid = nil
|
40
41
|
@unix_gid = nil
|
41
42
|
@unix_perms = nil
|
42
|
-
|
43
|
-
|
43
|
+
# @posix_acl = nil
|
44
|
+
# @ntfs_acl = nil
|
44
45
|
@dirty = false
|
45
46
|
end
|
46
47
|
|
47
48
|
def check_name(name)
|
48
|
-
|
49
|
-
|
50
|
-
end
|
49
|
+
return unless name.start_with?('/')
|
50
|
+
raise ::Zip::EntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
|
51
51
|
end
|
52
52
|
|
53
53
|
def initialize(*args)
|
@@ -68,7 +68,7 @@ module Zip
|
|
68
68
|
@time = args[8] || ::Zip::DOSTime.now
|
69
69
|
|
70
70
|
@ftype = name_is_directory? ? :directory : :file
|
71
|
-
@extra = ::Zip::ExtraField.new(@extra.to_s) unless ::Zip::ExtraField
|
71
|
+
@extra = ::Zip::ExtraField.new(@extra.to_s) unless @extra.is_a?(::Zip::ExtraField)
|
72
72
|
end
|
73
73
|
|
74
74
|
def time
|
@@ -83,7 +83,7 @@ module Zip
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
alias
|
86
|
+
alias mtime time
|
87
87
|
|
88
88
|
def time=(value)
|
89
89
|
unless @extra.member?('UniversalTime') || @extra.member?('NTFS')
|
@@ -94,7 +94,7 @@ module Zip
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def file_type_is?(type)
|
97
|
-
raise InternalError, "current filetype is unknown: #{
|
97
|
+
raise InternalError, "current filetype is unknown: #{inspect}" unless @ftype
|
98
98
|
@ftype == type
|
99
99
|
end
|
100
100
|
|
@@ -143,17 +143,22 @@ module Zip
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def next_header_offset #:nodoc:all
|
146
|
-
local_entry_offset +
|
146
|
+
local_entry_offset + compressed_size + data_descriptor_size
|
147
147
|
end
|
148
148
|
|
149
149
|
# Extracts entry to file dest_path (defaults to @name).
|
150
150
|
def extract(dest_path = @name, &block)
|
151
151
|
block ||= proc { ::Zip.on_exists_proc }
|
152
152
|
|
153
|
+
if @name.squeeze('/') =~ /\.{2}(?:\/|\z)/
|
154
|
+
puts "WARNING: skipped \"../\" path component(s) in #{@name}"
|
155
|
+
return self
|
156
|
+
end
|
157
|
+
|
153
158
|
if directory? || file? || symlink?
|
154
|
-
|
159
|
+
__send__("create_#{@ftype}", dest_path, &block)
|
155
160
|
else
|
156
|
-
raise
|
161
|
+
raise "unknown file type #{inspect}"
|
157
162
|
end
|
158
163
|
|
159
164
|
self
|
@@ -163,8 +168,6 @@ module Zip
|
|
163
168
|
@name
|
164
169
|
end
|
165
170
|
|
166
|
-
protected
|
167
|
-
|
168
171
|
class << self
|
169
172
|
def read_zip_short(io) # :nodoc:
|
170
173
|
io.read(2).unpack('v')[0]
|
@@ -179,11 +182,11 @@ module Zip
|
|
179
182
|
end
|
180
183
|
|
181
184
|
def read_c_dir_entry(io) #:nodoc:all
|
182
|
-
path = if io.
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
185
|
+
path = if io.respond_to?(:path)
|
186
|
+
io.path
|
187
|
+
else
|
188
|
+
io
|
189
|
+
end
|
187
190
|
entry = new(path)
|
188
191
|
entry.read_c_dir_entry(io)
|
189
192
|
entry
|
@@ -192,13 +195,12 @@ module Zip
|
|
192
195
|
end
|
193
196
|
|
194
197
|
def read_local_entry(io)
|
195
|
-
entry =
|
198
|
+
entry = new(io)
|
196
199
|
entry.read_local_entry(io)
|
197
200
|
entry
|
198
201
|
rescue Error
|
199
202
|
nil
|
200
203
|
end
|
201
|
-
|
202
204
|
end
|
203
205
|
|
204
206
|
public
|
@@ -221,10 +223,10 @@ module Zip
|
|
221
223
|
def read_local_entry(io) #:nodoc:all
|
222
224
|
@local_header_offset = io.tell
|
223
225
|
|
224
|
-
static_sized_fields_buf = io.read(::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH)
|
226
|
+
static_sized_fields_buf = io.read(::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH) || ''
|
225
227
|
|
226
228
|
unless static_sized_fields_buf.bytesize == ::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH
|
227
|
-
raise Error,
|
229
|
+
raise Error, 'Premature end of file. Not enough data for zip entry local header'
|
228
230
|
end
|
229
231
|
|
230
232
|
unpack_local_entry(static_sized_fields_buf)
|
@@ -240,10 +242,10 @@ module Zip
|
|
240
242
|
@name.gsub!('\\', '/')
|
241
243
|
|
242
244
|
if extra && extra.bytesize != @extra_length
|
243
|
-
raise ::Zip::Error,
|
245
|
+
raise ::Zip::Error, 'Truncated local zip entry header'
|
244
246
|
else
|
245
|
-
if ::Zip::ExtraField
|
246
|
-
@extra.merge(extra)
|
247
|
+
if @extra.is_a?(::Zip::ExtraField)
|
248
|
+
@extra.merge(extra) if extra
|
247
249
|
else
|
248
250
|
@extra = ::Zip::ExtraField.new(extra)
|
249
251
|
end
|
@@ -315,8 +317,8 @@ module Zip
|
|
315
317
|
when ::Zip::FILE_TYPE_SYMLINK
|
316
318
|
:symlink
|
317
319
|
else
|
318
|
-
#best case guess for whether it is a file or not
|
319
|
-
#Otherwise this would be set to unknown and that entry would never be able to extracted
|
320
|
+
# best case guess for whether it is a file or not
|
321
|
+
# Otherwise this would be set to unknown and that entry would never be able to extracted
|
320
322
|
if name_is_directory?
|
321
323
|
:directory
|
322
324
|
else
|
@@ -333,21 +335,18 @@ module Zip
|
|
333
335
|
end
|
334
336
|
|
335
337
|
def check_c_dir_entry_static_header_length(buf)
|
336
|
-
|
337
|
-
|
338
|
-
end
|
338
|
+
return if buf.bytesize == ::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH
|
339
|
+
raise Error, 'Premature end of file. Not enough data for zip cdir entry header'
|
339
340
|
end
|
340
341
|
|
341
342
|
def check_c_dir_entry_signature
|
342
|
-
|
343
|
-
|
344
|
-
end
|
343
|
+
return if header_signature == ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
|
344
|
+
raise Error, "Zip local header magic not found at location '#{local_header_offset}'"
|
345
345
|
end
|
346
346
|
|
347
347
|
def check_c_dir_entry_comment_size
|
348
|
-
|
349
|
-
|
350
|
-
end
|
348
|
+
return if @comment && @comment.bytesize == @comment_length
|
349
|
+
raise ::Zip::Error, 'Truncated cdir zip entry header'
|
351
350
|
end
|
352
351
|
|
353
352
|
def read_c_dir_extra_field(io)
|
@@ -364,7 +363,7 @@ module Zip
|
|
364
363
|
unpack_c_dir_entry(static_sized_fields_buf)
|
365
364
|
check_c_dir_entry_signature
|
366
365
|
set_time(@last_mod_date, @last_mod_time)
|
367
|
-
@name = io.read(@name_length)
|
366
|
+
@name = io.read(@name_length)
|
368
367
|
read_c_dir_extra_field(io)
|
369
368
|
@comment = io.read(@comment_length)
|
370
369
|
check_c_dir_entry_comment_size
|
@@ -374,19 +373,18 @@ module Zip
|
|
374
373
|
|
375
374
|
def file_stat(path) # :nodoc:
|
376
375
|
if @follow_symlinks
|
377
|
-
::File
|
376
|
+
::File.stat(path)
|
378
377
|
else
|
379
|
-
::File
|
378
|
+
::File.lstat(path)
|
380
379
|
end
|
381
380
|
end
|
382
381
|
|
383
382
|
def get_extra_attributes_from_path(path) # :nodoc:
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
end
|
383
|
+
return if Zip::RUNNING_ON_WINDOWS
|
384
|
+
stat = file_stat(path)
|
385
|
+
@unix_uid = stat.uid
|
386
|
+
@unix_gid = stat.gid
|
387
|
+
@unix_perms = stat.mode & 07777
|
390
388
|
end
|
391
389
|
|
392
390
|
def set_unix_permissions_on_path(dest_path)
|
@@ -400,7 +398,7 @@ module Zip
|
|
400
398
|
end
|
401
399
|
|
402
400
|
def set_extra_attributes_on_path(dest_path) # :nodoc:
|
403
|
-
return unless
|
401
|
+
return unless file? || directory?
|
404
402
|
|
405
403
|
case @fstype
|
406
404
|
when ::Zip::FSTYPE_UNIX
|
@@ -467,13 +465,13 @@ module Zip
|
|
467
465
|
return false unless other.class == self.class
|
468
466
|
# Compares contents of local entry and exposed fields
|
469
467
|
keys_equal = %w(compression_method crc compressed_size size name extra filepath).all? do |k|
|
470
|
-
other.__send__(k.to_sym) ==
|
468
|
+
other.__send__(k.to_sym) == __send__(k.to_sym)
|
471
469
|
end
|
472
|
-
keys_equal &&
|
470
|
+
keys_equal && time.dos_equals(other.time)
|
473
471
|
end
|
474
472
|
|
475
|
-
def <=>
|
476
|
-
|
473
|
+
def <=>(other)
|
474
|
+
to_s <=> other.to_s
|
477
475
|
end
|
478
476
|
|
479
477
|
# Returns an IO like object for the given ZipEntry.
|
@@ -496,6 +494,7 @@ module Zip
|
|
496
494
|
end
|
497
495
|
else
|
498
496
|
zis = ::Zip::InputStream.new(@zipfile, local_header_offset)
|
497
|
+
zis.instance_variable_set(:@internal, true)
|
499
498
|
zis.get_next_entry
|
500
499
|
if block_given?
|
501
500
|
begin
|
@@ -515,8 +514,8 @@ module Zip
|
|
515
514
|
when 'file'
|
516
515
|
if name_is_directory?
|
517
516
|
raise ArgumentError,
|
518
|
-
"entry name '#{newEntry}' indicates directory entry, but "
|
519
|
-
|
517
|
+
"entry name '#{newEntry}' indicates directory entry, but " \
|
518
|
+
"'#{src_path}' is not a directory"
|
520
519
|
end
|
521
520
|
:file
|
522
521
|
when 'directory'
|
@@ -525,12 +524,12 @@ module Zip
|
|
525
524
|
when 'link'
|
526
525
|
if name_is_directory?
|
527
526
|
raise ArgumentError,
|
528
|
-
"entry name '#{newEntry}' indicates directory entry, but "
|
529
|
-
|
527
|
+
"entry name '#{newEntry}' indicates directory entry, but " \
|
528
|
+
"'#{src_path}' is not a directory"
|
530
529
|
end
|
531
530
|
:symlink
|
532
531
|
else
|
533
|
-
raise
|
532
|
+
raise "unknown file type: #{src_path.inspect} #{stat.inspect}"
|
534
533
|
end
|
535
534
|
|
536
535
|
@filepath = src_path
|
@@ -541,7 +540,7 @@ module Zip
|
|
541
540
|
if @ftype == :directory
|
542
541
|
zip_output_stream.put_next_entry(self, nil, nil, ::Zip::Entry::STORED)
|
543
542
|
elsif @filepath
|
544
|
-
zip_output_stream.put_next_entry(self, nil, nil,
|
543
|
+
zip_output_stream.put_next_entry(self, nil, nil, compression_method || ::Zip::Entry::DEFLATED)
|
545
544
|
get_input_stream { |is| ::Zip::IOExtras.copy_stream(zip_output_stream, is) }
|
546
545
|
else
|
547
546
|
zip_output_stream.copy_raw_entry(self)
|
@@ -551,14 +550,14 @@ module Zip
|
|
551
550
|
def parent_as_string
|
552
551
|
entry_name = name.chomp('/')
|
553
552
|
slash_index = entry_name.rindex('/')
|
554
|
-
slash_index ? entry_name.slice(0, slash_index+1) : nil
|
553
|
+
slash_index ? entry_name.slice(0, slash_index + 1) : nil
|
555
554
|
end
|
556
555
|
|
557
556
|
def get_raw_input_stream(&block)
|
558
|
-
if @zipfile.
|
557
|
+
if @zipfile.respond_to?(:seek) && @zipfile.respond_to?(:read)
|
559
558
|
yield @zipfile
|
560
559
|
else
|
561
|
-
::File.open(@zipfile,
|
560
|
+
::File.open(@zipfile, 'rb', &block)
|
562
561
|
end
|
563
562
|
end
|
564
563
|
|
@@ -571,20 +570,20 @@ module Zip
|
|
571
570
|
def set_time(binary_dos_date, binary_dos_time)
|
572
571
|
@time = ::Zip::DOSTime.parse_binary_dos_format(binary_dos_date, binary_dos_time)
|
573
572
|
rescue ArgumentError
|
574
|
-
|
573
|
+
warn 'Invalid date/time in zip entry' if ::Zip.warn_invalid_date
|
575
574
|
end
|
576
575
|
|
577
|
-
def create_file(dest_path,
|
576
|
+
def create_file(dest_path, _continue_on_exists_proc = proc { Zip.continue_on_exists_proc })
|
578
577
|
if ::File.exist?(dest_path) && !yield(self, dest_path)
|
579
578
|
raise ::Zip::DestinationFileExistsError,
|
580
579
|
"Destination '#{dest_path}' already exists"
|
581
580
|
end
|
582
|
-
::File.open(dest_path,
|
581
|
+
::File.open(dest_path, 'wb') do |os|
|
583
582
|
get_input_stream do |is|
|
584
583
|
set_extra_attributes_on_path(dest_path)
|
585
584
|
|
586
585
|
buf = ''
|
587
|
-
while buf = is.sysread(::Zip::Decompressor::CHUNK_SIZE, buf)
|
586
|
+
while (buf = is.sysread(::Zip::Decompressor::CHUNK_SIZE, buf))
|
588
587
|
os << buf
|
589
588
|
end
|
590
589
|
end
|
@@ -595,11 +594,11 @@ module Zip
|
|
595
594
|
return if ::File.directory?(dest_path)
|
596
595
|
if ::File.exist?(dest_path)
|
597
596
|
if block_given? && yield(self, dest_path)
|
598
|
-
::FileUtils
|
597
|
+
::FileUtils.rm_f dest_path
|
599
598
|
else
|
600
599
|
raise ::Zip::DestinationFileExistsError,
|
601
|
-
"Cannot create directory '#{dest_path}'. "
|
602
|
-
|
600
|
+
"Cannot create directory '#{dest_path}'. " \
|
601
|
+
'A file already exists with that name'
|
603
602
|
end
|
604
603
|
end
|
605
604
|
::FileUtils.mkdir_p(dest_path)
|
@@ -623,13 +622,13 @@ module Zip
|
|
623
622
|
return
|
624
623
|
else
|
625
624
|
raise ::Zip::DestinationFileExistsError,
|
626
|
-
"Cannot create symlink '#{dest_path}'. "
|
627
|
-
|
625
|
+
"Cannot create symlink '#{dest_path}'. " \
|
626
|
+
'A symlink already exists with that name'
|
628
627
|
end
|
629
628
|
else
|
630
629
|
raise ::Zip::DestinationFileExistsError,
|
631
|
-
"Cannot create symlink '#{dest_path}'. "
|
632
|
-
|
630
|
+
"Cannot create symlink '#{dest_path}'. " \
|
631
|
+
'A file already exists with that name'
|
633
632
|
end
|
634
633
|
end
|
635
634
|
|
@@ -639,12 +638,11 @@ module Zip
|
|
639
638
|
# apply missing data from the zip64 extra information field, if present
|
640
639
|
# (required when file sizes exceed 2**32, but can be used for all files)
|
641
640
|
def parse_zip64_extra(for_local_header) #:nodoc:all
|
642
|
-
if
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
end
|
641
|
+
return if @extra['Zip64'].nil?
|
642
|
+
if for_local_header
|
643
|
+
@size, @compressed_size = @extra['Zip64'].parse(@size, @compressed_size)
|
644
|
+
else
|
645
|
+
@size, @compressed_size, @local_header_offset = @extra['Zip64'].parse(@size, @compressed_size, @local_header_offset)
|
648
646
|
end
|
649
647
|
end
|
650
648
|
|
@@ -656,10 +654,7 @@ module Zip
|
|
656
654
|
def prep_zip64_extra(for_local_header) #:nodoc:all
|
657
655
|
return unless ::Zip.write_zip64_support
|
658
656
|
need_zip64 = @size >= 0xFFFFFFFF || @compressed_size >= 0xFFFFFFFF
|
659
|
-
unless for_local_header
|
660
|
-
need_zip64 ||= @local_header_offset >= 0xFFFFFFFF
|
661
|
-
end
|
662
|
-
|
657
|
+
need_zip64 ||= @local_header_offset >= 0xFFFFFFFF unless for_local_header
|
663
658
|
if need_zip64
|
664
659
|
@version_needed_to_extract = VERSION_NEEDED_TO_EXTRACT_ZIP64
|
665
660
|
@extra.delete('Zip64Placeholder')
|
@@ -687,7 +682,6 @@ module Zip
|
|
687
682
|
end
|
688
683
|
end
|
689
684
|
end
|
690
|
-
|
691
685
|
end
|
692
686
|
end
|
693
687
|
|
data/lib/zip/entry_set.rb
CHANGED
@@ -18,23 +18,19 @@ module Zip
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def <<(entry)
|
21
|
-
@entry_set[to_key(entry)] = entry
|
21
|
+
@entry_set[to_key(entry)] = entry if entry
|
22
22
|
end
|
23
23
|
|
24
|
-
alias
|
24
|
+
alias push <<
|
25
25
|
|
26
26
|
def size
|
27
27
|
@entry_set.size
|
28
28
|
end
|
29
29
|
|
30
|
-
alias
|
30
|
+
alias length size
|
31
31
|
|
32
32
|
def delete(entry)
|
33
|
-
if @entry_set.delete(to_key(entry))
|
34
|
-
entry
|
35
|
-
else
|
36
|
-
nil
|
37
|
-
end
|
33
|
+
entry if @entry_set.delete(to_key(entry))
|
38
34
|
end
|
39
35
|
|
40
36
|
def each(&block)
|
@@ -49,7 +45,7 @@ module Zip
|
|
49
45
|
|
50
46
|
# deep clone
|
51
47
|
def dup
|
52
|
-
EntrySet.new(@entry_set.map
|
48
|
+
EntrySet.new(@entry_set.values.map(&:dup))
|
53
49
|
end
|
54
50
|
|
55
51
|
def ==(other)
|
@@ -61,7 +57,7 @@ module Zip
|
|
61
57
|
@entry_set[to_key(entry.parent_as_string)]
|
62
58
|
end
|
63
59
|
|
64
|
-
def glob(pattern, flags = ::File::FNM_PATHNAME
|
60
|
+
def glob(pattern, flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB)
|
65
61
|
entries.map do |entry|
|
66
62
|
next nil unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags)
|
67
63
|
yield(entry) if block_given?
|
@@ -70,13 +66,17 @@ module Zip
|
|
70
66
|
end
|
71
67
|
|
72
68
|
protected
|
69
|
+
|
73
70
|
def sorted_entries
|
74
71
|
::Zip.sort_entries ? Hash[@entry_set.sort] : @entry_set
|
75
72
|
end
|
76
73
|
|
77
74
|
private
|
75
|
+
|
78
76
|
def to_key(entry)
|
79
|
-
entry.to_s.chomp('/')
|
77
|
+
k = entry.to_s.chomp('/')
|
78
|
+
k.downcase! if ::Zip.case_insensitive_match
|
79
|
+
k
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|