rubyzip 3.0.0.alpha → 3.0.0.rc1
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 +51 -0
- data/LICENSE.md +24 -0
- data/README.md +37 -12
- data/Rakefile +1 -1
- data/lib/zip/central_directory.rb +10 -10
- data/lib/zip/constants.rb +4 -0
- data/lib/zip/crypto/decrypted_io.rb +1 -1
- data/lib/zip/crypto/null_encryption.rb +1 -1
- data/lib/zip/crypto/traditional_encryption.rb +3 -3
- data/lib/zip/dos_time.rb +11 -1
- data/lib/zip/entry.rb +74 -47
- data/lib/zip/entry_set.rb +2 -2
- data/lib/zip/errors.rb +24 -3
- data/lib/zip/extra_field/generic.rb +3 -3
- data/lib/zip/extra_field/ntfs.rb +2 -2
- data/lib/zip/extra_field.rb +2 -2
- data/lib/zip/file.rb +38 -15
- data/lib/zip/file_split.rb +1 -7
- data/lib/zip/filesystem/dir.rb +2 -2
- data/lib/zip/filesystem/zip_file_name_mapper.rb +1 -1
- data/lib/zip/filesystem.rb +1 -1
- data/lib/zip/input_stream.rb +13 -18
- data/lib/zip/ioextras/abstract_input_stream.rb +2 -2
- data/lib/zip/ioextras.rb +1 -1
- data/lib/zip/output_stream.rb +8 -8
- data/lib/zip/version.rb +1 -1
- data/lib/zip.rb +4 -3
- data/rubyzip.gemspec +16 -15
- data/samples/example_filesystem.rb +1 -1
- data/samples/write_simple.rb +1 -1
- metadata +23 -21
data/lib/zip/entry.rb
CHANGED
@@ -9,16 +9,19 @@ module Zip
|
|
9
9
|
class Entry
|
10
10
|
include Dirtyable
|
11
11
|
|
12
|
+
# Constant used to specify that the entry is stored (i.e., not compressed).
|
12
13
|
STORED = ::Zip::COMPRESSION_METHOD_STORE
|
14
|
+
|
15
|
+
# Constant used to specify that the entry is deflated (i.e., compressed).
|
13
16
|
DEFLATED = ::Zip::COMPRESSION_METHOD_DEFLATE
|
14
17
|
|
15
18
|
# Language encoding flag (EFS) bit
|
16
|
-
EFS = 0b100000000000
|
19
|
+
EFS = 0b100000000000 # :nodoc:
|
17
20
|
|
18
21
|
# Compression level flags (used as part of the gp flags).
|
19
|
-
COMPRESSION_LEVEL_SUPERFAST_GPFLAG = 0b110
|
20
|
-
COMPRESSION_LEVEL_FAST_GPFLAG = 0b100
|
21
|
-
COMPRESSION_LEVEL_MAX_GPFLAG = 0b010
|
22
|
+
COMPRESSION_LEVEL_SUPERFAST_GPFLAG = 0b110 # :nodoc:
|
23
|
+
COMPRESSION_LEVEL_FAST_GPFLAG = 0b100 # :nodoc:
|
24
|
+
COMPRESSION_LEVEL_MAX_GPFLAG = 0b010 # :nodoc:
|
22
25
|
|
23
26
|
attr_accessor :comment, :compressed_size, :follow_symlinks, :name,
|
24
27
|
:restore_ownership, :restore_permissions, :restore_times,
|
@@ -35,7 +38,7 @@ module Zip
|
|
35
38
|
:fstype=, :gp_flags=, :name=, :size=,
|
36
39
|
:unix_gid=, :unix_perms=, :unix_uid=
|
37
40
|
|
38
|
-
def set_default_vars_values
|
41
|
+
def set_default_vars_values # :nodoc:
|
39
42
|
@local_header_offset = 0
|
40
43
|
@local_header_size = nil # not known until local entry is created or read
|
41
44
|
@internal_file_attributes = 1
|
@@ -63,11 +66,12 @@ module Zip
|
|
63
66
|
@unix_perms = nil
|
64
67
|
end
|
65
68
|
|
66
|
-
def check_name(name)
|
69
|
+
def check_name(name) # :nodoc:
|
67
70
|
raise EntryNameError, name if name.start_with?('/')
|
68
71
|
raise EntryNameError if name.length > 65_535
|
69
72
|
end
|
70
73
|
|
74
|
+
# Create a new Zip::Entry.
|
71
75
|
def initialize(
|
72
76
|
zipfile = '', name = '',
|
73
77
|
comment: '', size: nil, compressed_size: 0, crc: 0,
|
@@ -103,18 +107,23 @@ module Zip
|
|
103
107
|
set_compression_level_flags
|
104
108
|
end
|
105
109
|
|
110
|
+
# Is this entry encrypted?
|
106
111
|
def encrypted?
|
107
112
|
gp_flags & 1 == 1
|
108
113
|
end
|
109
114
|
|
110
|
-
def incomplete?
|
115
|
+
def incomplete? # :nodoc:
|
111
116
|
gp_flags & 8 == 8
|
112
117
|
end
|
113
118
|
|
119
|
+
# The uncompressed size of the entry.
|
114
120
|
def size
|
115
121
|
@size || 0
|
116
122
|
end
|
117
123
|
|
124
|
+
# Get a timestamp component of this entry.
|
125
|
+
#
|
126
|
+
# Returns modification time by default.
|
118
127
|
def time(component: :mtime)
|
119
128
|
time =
|
120
129
|
if @extra['UniversalTime']
|
@@ -130,14 +139,19 @@ module Zip
|
|
130
139
|
|
131
140
|
alias mtime time
|
132
141
|
|
142
|
+
# Get the last access time of this entry, if available.
|
133
143
|
def atime
|
134
144
|
time(component: :atime)
|
135
145
|
end
|
136
146
|
|
147
|
+
# Get the creation time of this entry, if available.
|
137
148
|
def ctime
|
138
149
|
time(component: :ctime)
|
139
150
|
end
|
140
151
|
|
152
|
+
# Set a timestamp component of this entry.
|
153
|
+
#
|
154
|
+
# Sets modification time by default.
|
141
155
|
def time=(value, component: :mtime)
|
142
156
|
@dirty = true
|
143
157
|
unless @extra.member?('UniversalTime') || @extra.member?('NTFS')
|
@@ -152,30 +166,43 @@ module Zip
|
|
152
166
|
|
153
167
|
alias mtime= time=
|
154
168
|
|
169
|
+
# Set the last access time of this entry.
|
155
170
|
def atime=(value)
|
156
171
|
send(:time=, value, component: :atime)
|
157
172
|
end
|
158
173
|
|
174
|
+
# Set the creation time of this entry.
|
159
175
|
def ctime=(value)
|
160
176
|
send(:time=, value, component: :ctime)
|
161
177
|
end
|
162
178
|
|
179
|
+
# Does this entry return time fields with accurate timezone information?
|
180
|
+
def absolute_time?
|
181
|
+
@extra.member?('UniversalTime') || @extra.member?('NTFS')
|
182
|
+
end
|
183
|
+
|
184
|
+
# Return the compression method for this entry.
|
185
|
+
#
|
186
|
+
# Returns STORED if the entry is a directory or if the compression
|
187
|
+
# level is 0.
|
163
188
|
def compression_method
|
164
189
|
return STORED if ftype == :directory || @compression_level == 0
|
165
190
|
|
166
191
|
@compression_method
|
167
192
|
end
|
168
193
|
|
194
|
+
# Set the compression method for this entry.
|
169
195
|
def compression_method=(method)
|
170
196
|
@dirty = true
|
171
197
|
@compression_method = (ftype == :directory ? STORED : method)
|
172
198
|
end
|
173
199
|
|
200
|
+
# Does this entry use the ZIP64 extensions?
|
174
201
|
def zip64?
|
175
202
|
!@extra['Zip64'].nil?
|
176
203
|
end
|
177
204
|
|
178
|
-
def file_type_is?(type)
|
205
|
+
def file_type_is?(type) # :nodoc:
|
179
206
|
ftype == type
|
180
207
|
end
|
181
208
|
|
@@ -185,19 +212,19 @@ module Zip
|
|
185
212
|
|
186
213
|
# Dynamic checkers
|
187
214
|
%w[directory file symlink].each do |k|
|
188
|
-
define_method "#{k}?" do
|
215
|
+
define_method :"#{k}?" do
|
189
216
|
file_type_is?(k.to_sym)
|
190
217
|
end
|
191
218
|
end
|
192
219
|
|
193
|
-
def name_is_directory?
|
220
|
+
def name_is_directory? # :nodoc:
|
194
221
|
@name.end_with?('/')
|
195
222
|
end
|
196
223
|
|
197
224
|
# Is the name a relative path, free of `..` patterns that could lead to
|
198
225
|
# path traversal attacks? This does NOT handle symlinks; if the path
|
199
226
|
# contains symlinks, this check is NOT enough to guarantee safety.
|
200
|
-
def name_safe?
|
227
|
+
def name_safe? # :nodoc:
|
201
228
|
cleanpath = Pathname.new(@name).cleanpath
|
202
229
|
return false unless cleanpath.relative?
|
203
230
|
|
@@ -207,29 +234,29 @@ module Zip
|
|
207
234
|
::File.absolute_path(cleanpath.to_s, root).match?(/([A-Z]:)?#{naive}/i)
|
208
235
|
end
|
209
236
|
|
210
|
-
def local_entry_offset
|
237
|
+
def local_entry_offset # :nodoc:
|
211
238
|
local_header_offset + @local_header_size
|
212
239
|
end
|
213
240
|
|
214
|
-
def name_size
|
241
|
+
def name_size # :nodoc:
|
215
242
|
@name ? @name.bytesize : 0
|
216
243
|
end
|
217
244
|
|
218
|
-
def extra_size
|
245
|
+
def extra_size # :nodoc:
|
219
246
|
@extra ? @extra.local_size : 0
|
220
247
|
end
|
221
248
|
|
222
|
-
def comment_size
|
249
|
+
def comment_size # :nodoc:
|
223
250
|
@comment ? @comment.bytesize : 0
|
224
251
|
end
|
225
252
|
|
226
|
-
def calculate_local_header_size
|
253
|
+
def calculate_local_header_size # :nodoc:
|
227
254
|
LOCAL_ENTRY_STATIC_HEADER_LENGTH + name_size + extra_size
|
228
255
|
end
|
229
256
|
|
230
257
|
# check before rewriting an entry (after file sizes are known)
|
231
258
|
# that we didn't change the header size (and thus clobber file data or something)
|
232
|
-
def verify_local_header_size!
|
259
|
+
def verify_local_header_size! # :nodoc:
|
233
260
|
return if @local_header_size.nil?
|
234
261
|
|
235
262
|
new_size = calculate_local_header_size
|
@@ -239,12 +266,12 @@ module Zip
|
|
239
266
|
"Local header size changed (#{@local_header_size} -> #{new_size})"
|
240
267
|
end
|
241
268
|
|
242
|
-
def cdir_header_size
|
269
|
+
def cdir_header_size # :nodoc:
|
243
270
|
CDIR_ENTRY_STATIC_HEADER_LENGTH + name_size +
|
244
271
|
(@extra ? @extra.c_dir_size : 0) + comment_size
|
245
272
|
end
|
246
273
|
|
247
|
-
def next_header_offset
|
274
|
+
def next_header_offset # :nodoc:
|
248
275
|
local_entry_offset + compressed_size
|
249
276
|
end
|
250
277
|
|
@@ -266,16 +293,16 @@ module Zip
|
|
266
293
|
|
267
294
|
raise "unknown file type #{inspect}" unless directory? || file? || symlink?
|
268
295
|
|
269
|
-
__send__("create_#{ftype}", extract_path, &block)
|
296
|
+
__send__(:"create_#{ftype}", extract_path, &block)
|
270
297
|
self
|
271
298
|
end
|
272
299
|
|
273
|
-
def to_s
|
300
|
+
def to_s # :nodoc:
|
274
301
|
@name
|
275
302
|
end
|
276
303
|
|
277
304
|
class << self
|
278
|
-
def read_c_dir_entry(io)
|
305
|
+
def read_c_dir_entry(io) # :nodoc:
|
279
306
|
path = if io.respond_to?(:path)
|
280
307
|
io.path
|
281
308
|
else
|
@@ -288,7 +315,7 @@ module Zip
|
|
288
315
|
nil
|
289
316
|
end
|
290
317
|
|
291
|
-
def read_local_entry(io)
|
318
|
+
def read_local_entry(io) # :nodoc:
|
292
319
|
entry = new(io)
|
293
320
|
entry.read_local_entry(io)
|
294
321
|
entry
|
@@ -299,7 +326,7 @@ module Zip
|
|
299
326
|
end
|
300
327
|
end
|
301
328
|
|
302
|
-
def unpack_local_entry(buf)
|
329
|
+
def unpack_local_entry(buf) # :nodoc:
|
303
330
|
@header_signature,
|
304
331
|
@version,
|
305
332
|
@fstype,
|
@@ -314,7 +341,7 @@ module Zip
|
|
314
341
|
@extra_length = buf.unpack('VCCvvvvVVVvv')
|
315
342
|
end
|
316
343
|
|
317
|
-
def read_local_entry(io)
|
344
|
+
def read_local_entry(io) # :nodoc:
|
318
345
|
@dirty = false # No changes at this point.
|
319
346
|
@local_header_offset = io.tell
|
320
347
|
|
@@ -356,7 +383,7 @@ module Zip
|
|
356
383
|
@local_header_size = calculate_local_header_size
|
357
384
|
end
|
358
385
|
|
359
|
-
def pack_local_entry
|
386
|
+
def pack_local_entry # :nodoc:
|
360
387
|
zip64 = @extra['Zip64']
|
361
388
|
[::Zip::LOCAL_ENTRY_SIGNATURE,
|
362
389
|
@version_needed_to_extract, # version needed to extract
|
@@ -371,7 +398,7 @@ module Zip
|
|
371
398
|
@extra ? @extra.local_size : 0].pack('VvvvvvVVVvv')
|
372
399
|
end
|
373
400
|
|
374
|
-
def write_local_entry(io, rewrite: false)
|
401
|
+
def write_local_entry(io, rewrite: false) # :nodoc:
|
375
402
|
prep_local_zip64_extra
|
376
403
|
verify_local_header_size! if rewrite
|
377
404
|
@local_header_offset = io.tell
|
@@ -383,7 +410,7 @@ module Zip
|
|
383
410
|
@local_header_size = io.tell - @local_header_offset
|
384
411
|
end
|
385
412
|
|
386
|
-
def unpack_c_dir_entry(buf)
|
413
|
+
def unpack_c_dir_entry(buf) # :nodoc:
|
387
414
|
@header_signature,
|
388
415
|
@version, # version of encoding software
|
389
416
|
@fstype, # filesystem type
|
@@ -407,7 +434,7 @@ module Zip
|
|
407
434
|
@comment = buf.unpack('VCCvvvvvVVVvvvvvVV')
|
408
435
|
end
|
409
436
|
|
410
|
-
def set_ftype_from_c_dir_entry
|
437
|
+
def set_ftype_from_c_dir_entry # :nodoc:
|
411
438
|
@ftype = case @fstype
|
412
439
|
when ::Zip::FSTYPE_UNIX
|
413
440
|
@unix_perms = (@external_file_attributes >> 16) & 0o7777
|
@@ -437,25 +464,25 @@ module Zip
|
|
437
464
|
end
|
438
465
|
end
|
439
466
|
|
440
|
-
def check_c_dir_entry_static_header_length(buf)
|
467
|
+
def check_c_dir_entry_static_header_length(buf) # :nodoc:
|
441
468
|
return unless buf.nil? || buf.bytesize != ::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH
|
442
469
|
|
443
470
|
raise Error, 'Premature end of file. Not enough data for zip cdir entry header'
|
444
471
|
end
|
445
472
|
|
446
|
-
def check_c_dir_entry_signature
|
473
|
+
def check_c_dir_entry_signature # :nodoc:
|
447
474
|
return if @header_signature == ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
|
448
475
|
|
449
476
|
raise Error, "Zip local header magic not found at location '#{local_header_offset}'"
|
450
477
|
end
|
451
478
|
|
452
|
-
def check_c_dir_entry_comment_size
|
479
|
+
def check_c_dir_entry_comment_size # :nodoc:
|
453
480
|
return if @comment && @comment.bytesize == @comment_length
|
454
481
|
|
455
482
|
raise ::Zip::Error, 'Truncated cdir zip entry header'
|
456
483
|
end
|
457
484
|
|
458
|
-
def read_extra_field(buf, local: false)
|
485
|
+
def read_extra_field(buf, local: false) # :nodoc:
|
459
486
|
if @extra.kind_of?(::Zip::ExtraField)
|
460
487
|
@extra.merge(buf, local: local) if buf
|
461
488
|
else
|
@@ -463,7 +490,7 @@ module Zip
|
|
463
490
|
end
|
464
491
|
end
|
465
492
|
|
466
|
-
def read_c_dir_entry(io)
|
493
|
+
def read_c_dir_entry(io) # :nodoc:
|
467
494
|
@dirty = false # No changes at this point.
|
468
495
|
static_sized_fields_buf = io.read(::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH)
|
469
496
|
check_c_dir_entry_static_header_length(static_sized_fields_buf)
|
@@ -503,7 +530,7 @@ module Zip
|
|
503
530
|
end
|
504
531
|
|
505
532
|
# rubocop:disable Style/GuardClause
|
506
|
-
def set_unix_attributes_on_path(dest_path)
|
533
|
+
def set_unix_attributes_on_path(dest_path) # :nodoc:
|
507
534
|
# Ignore setuid/setgid bits by default. Honour if @restore_ownership.
|
508
535
|
unix_perms_mask = (@restore_ownership ? 0o7777 : 0o1777)
|
509
536
|
if @restore_permissions && @unix_perms
|
@@ -529,7 +556,7 @@ module Zip
|
|
529
556
|
::FileUtils.touch(dest_path, mtime: time) if @restore_times
|
530
557
|
end
|
531
558
|
|
532
|
-
def pack_c_dir_entry
|
559
|
+
def pack_c_dir_entry # :nodoc:
|
533
560
|
zip64 = @extra['Zip64']
|
534
561
|
[
|
535
562
|
@header_signature,
|
@@ -556,7 +583,7 @@ module Zip
|
|
556
583
|
].pack('VCCvvvvvVVVvvvvvVV')
|
557
584
|
end
|
558
585
|
|
559
|
-
def write_c_dir_entry(io)
|
586
|
+
def write_c_dir_entry(io) # :nodoc:
|
560
587
|
prep_cdir_zip64_extra
|
561
588
|
|
562
589
|
case @fstype
|
@@ -574,7 +601,7 @@ module Zip
|
|
574
601
|
end
|
575
602
|
|
576
603
|
unless ft.nil?
|
577
|
-
@external_file_attributes = (ft << 12 | (@unix_perms & 0o7777)) << 16
|
604
|
+
@external_file_attributes = ((ft << 12) | (@unix_perms & 0o7777)) << 16
|
578
605
|
end
|
579
606
|
end
|
580
607
|
|
@@ -585,7 +612,7 @@ module Zip
|
|
585
612
|
io << @comment
|
586
613
|
end
|
587
614
|
|
588
|
-
def ==(other)
|
615
|
+
def ==(other) # :nodoc:
|
589
616
|
return false unless other.class == self.class
|
590
617
|
|
591
618
|
# Compares contents of local entry and exposed fields
|
@@ -594,7 +621,7 @@ module Zip
|
|
594
621
|
end
|
595
622
|
end
|
596
623
|
|
597
|
-
def <=>(other)
|
624
|
+
def <=>(other) # :nodoc:
|
598
625
|
to_s <=> other.to_s
|
599
626
|
end
|
600
627
|
|
@@ -639,7 +666,7 @@ module Zip
|
|
639
666
|
if name_is_directory?
|
640
667
|
raise ArgumentError,
|
641
668
|
"entry name '#{newEntry}' indicates directory entry, but " \
|
642
|
-
|
669
|
+
"'#{src_path}' is not a directory"
|
643
670
|
end
|
644
671
|
:file
|
645
672
|
when 'directory'
|
@@ -649,7 +676,7 @@ module Zip
|
|
649
676
|
if name_is_directory?
|
650
677
|
raise ArgumentError,
|
651
678
|
"entry name '#{newEntry}' indicates directory entry, but " \
|
652
|
-
|
679
|
+
"'#{src_path}' is not a directory"
|
653
680
|
end
|
654
681
|
:symlink
|
655
682
|
else
|
@@ -661,7 +688,7 @@ module Zip
|
|
661
688
|
get_extra_attributes_from_path(@filepath)
|
662
689
|
end
|
663
690
|
|
664
|
-
def write_to_zip_output_stream(zip_output_stream)
|
691
|
+
def write_to_zip_output_stream(zip_output_stream) # :nodoc:
|
665
692
|
if ftype == :directory
|
666
693
|
zip_output_stream.put_next_entry(self)
|
667
694
|
elsif @filepath
|
@@ -674,13 +701,13 @@ module Zip
|
|
674
701
|
end
|
675
702
|
end
|
676
703
|
|
677
|
-
def parent_as_string
|
704
|
+
def parent_as_string # :nodoc:
|
678
705
|
entry_name = name.chomp('/')
|
679
706
|
slash_index = entry_name.rindex('/')
|
680
707
|
slash_index ? entry_name.slice(0, slash_index + 1) : nil
|
681
708
|
end
|
682
709
|
|
683
|
-
def get_raw_input_stream(&block)
|
710
|
+
def get_raw_input_stream(&block) # :nodoc:
|
684
711
|
if @zipfile.respond_to?(:seek) && @zipfile.respond_to?(:read)
|
685
712
|
yield @zipfile
|
686
713
|
else
|
@@ -688,7 +715,7 @@ module Zip
|
|
688
715
|
end
|
689
716
|
end
|
690
717
|
|
691
|
-
def clean_up
|
718
|
+
def clean_up # :nodoc:
|
692
719
|
@dirty = false # Any changes are written at this point.
|
693
720
|
end
|
694
721
|
|
@@ -749,7 +776,7 @@ module Zip
|
|
749
776
|
|
750
777
|
# apply missing data from the zip64 extra information field, if present
|
751
778
|
# (required when file sizes exceed 2**32, but can be used for all files)
|
752
|
-
def parse_zip64_extra(for_local_header)
|
779
|
+
def parse_zip64_extra(for_local_header) # :nodoc:
|
753
780
|
return unless zip64?
|
754
781
|
|
755
782
|
if for_local_header
|
data/lib/zip/entry_set.rb
CHANGED
@@ -61,12 +61,12 @@ module Zip
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def glob(pattern, flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB)
|
64
|
-
entries.
|
64
|
+
entries.filter_map do |entry|
|
65
65
|
next nil unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags)
|
66
66
|
|
67
67
|
yield(entry) if block_given?
|
68
68
|
entry
|
69
|
-
end
|
69
|
+
end
|
70
70
|
end
|
71
71
|
|
72
72
|
protected
|
data/lib/zip/errors.rb
CHANGED
@@ -7,13 +7,17 @@ module Zip
|
|
7
7
|
|
8
8
|
# Error raised if an unsupported compression method is used.
|
9
9
|
class CompressionMethodError < Error
|
10
|
+
# The compression method that has caused this error.
|
10
11
|
attr_reader :compression_method
|
11
12
|
|
13
|
+
# Create a new CompressionMethodError with the specified incorrect
|
14
|
+
# compression method.
|
12
15
|
def initialize(method)
|
13
16
|
super()
|
14
17
|
@compression_method = method
|
15
18
|
end
|
16
19
|
|
20
|
+
# The message returned by this error.
|
17
21
|
def message
|
18
22
|
"Unsupported compression method: #{COMPRESSION_METHODS[@compression_method]}."
|
19
23
|
end
|
@@ -21,13 +25,17 @@ module Zip
|
|
21
25
|
|
22
26
|
# Error raised if there is a problem while decompressing an archive entry.
|
23
27
|
class DecompressionError < Error
|
28
|
+
# The error from the underlying Zlib library that caused this error.
|
24
29
|
attr_reader :zlib_error
|
25
30
|
|
31
|
+
# Create a new DecompressionError with the specified underlying Zlib
|
32
|
+
# error.
|
26
33
|
def initialize(zlib_error)
|
27
34
|
super()
|
28
35
|
@zlib_error = zlib_error
|
29
36
|
end
|
30
37
|
|
38
|
+
# The message returned by this error.
|
31
39
|
def message
|
32
40
|
"Zlib error ('#{@zlib_error.message}') while inflating."
|
33
41
|
end
|
@@ -36,26 +44,30 @@ module Zip
|
|
36
44
|
# Error raised when trying to extract an archive entry over an
|
37
45
|
# existing file.
|
38
46
|
class DestinationExistsError < Error
|
47
|
+
# Create a new DestinationExistsError with the clashing destination.
|
39
48
|
def initialize(destination)
|
40
49
|
super()
|
41
50
|
@destination = destination
|
42
51
|
end
|
43
52
|
|
53
|
+
# The message returned by this error.
|
44
54
|
def message
|
45
55
|
"Cannot create file or directory '#{@destination}'. " \
|
46
|
-
|
56
|
+
'A file already exists with that name.'
|
47
57
|
end
|
48
58
|
end
|
49
59
|
|
50
60
|
# Error raised when trying to add an entry to an archive where the
|
51
61
|
# entry name already exists.
|
52
62
|
class EntryExistsError < Error
|
63
|
+
# Create a new EntryExistsError with the specified source and name.
|
53
64
|
def initialize(source, name)
|
54
65
|
super()
|
55
66
|
@source = source
|
56
67
|
@name = name
|
57
68
|
end
|
58
69
|
|
70
|
+
# The message returned by this error.
|
59
71
|
def message
|
60
72
|
"'#{@source}' failed. Entry #{@name} already exists."
|
61
73
|
end
|
@@ -63,11 +75,13 @@ module Zip
|
|
63
75
|
|
64
76
|
# Error raised when an entry name is invalid.
|
65
77
|
class EntryNameError < Error
|
78
|
+
# Create a new EntryNameError with the specified name.
|
66
79
|
def initialize(name = nil)
|
67
80
|
super()
|
68
81
|
@name = name
|
69
82
|
end
|
70
83
|
|
84
|
+
# The message returned by this error.
|
71
85
|
def message
|
72
86
|
if @name.nil?
|
73
87
|
'Illegal entry name. Names must have fewer than 65,536 characters.'
|
@@ -80,13 +94,16 @@ module Zip
|
|
80
94
|
# Error raised if an entry is larger on extraction than it is advertised
|
81
95
|
# to be.
|
82
96
|
class EntrySizeError < Error
|
97
|
+
# The entry that has caused this error.
|
83
98
|
attr_reader :entry
|
84
99
|
|
100
|
+
# Create a new EntrySizeError with the specified entry.
|
85
101
|
def initialize(entry)
|
86
102
|
super()
|
87
103
|
@entry = entry
|
88
104
|
end
|
89
105
|
|
106
|
+
# The message returned by this error.
|
90
107
|
def message
|
91
108
|
"Entry '#{@entry.name}' should be #{@entry.size}B, but is larger when inflated."
|
92
109
|
end
|
@@ -95,6 +112,7 @@ module Zip
|
|
95
112
|
# Error raised if a split archive is read. Rubyzip does not support reading
|
96
113
|
# split archives.
|
97
114
|
class SplitArchiveError < Error
|
115
|
+
# The message returned by this error.
|
98
116
|
def message
|
99
117
|
'Rubyzip cannot extract from split archives at this time.'
|
100
118
|
end
|
@@ -102,17 +120,20 @@ module Zip
|
|
102
120
|
|
103
121
|
# Error raised if there is not enough metadata for the entry to be streamed.
|
104
122
|
class StreamingError < Error
|
123
|
+
# The entry that has caused this error.
|
105
124
|
attr_reader :entry
|
106
125
|
|
126
|
+
# Create a new StreamingError with the specified entry.
|
107
127
|
def initialize(entry)
|
108
128
|
super()
|
109
129
|
@entry = entry
|
110
130
|
end
|
111
131
|
|
132
|
+
# The message returned by this error.
|
112
133
|
def message
|
113
134
|
"The local header of this entry ('#{@entry.name}') does not contain " \
|
114
|
-
|
115
|
-
|
135
|
+
'the correct metadata for `Zip::InputStream` to be able to ' \
|
136
|
+
'uncompress it. Please use `Zip::File` instead of `Zip::InputStream`.'
|
116
137
|
end
|
117
138
|
end
|
118
139
|
end
|
@@ -21,17 +21,17 @@ module Zip
|
|
21
21
|
return false
|
22
22
|
end
|
23
23
|
|
24
|
-
[binstr[2, 2].unpack1('v'), binstr[4
|
24
|
+
[binstr[2, 2].unpack1('v'), binstr[4..]]
|
25
25
|
end
|
26
26
|
|
27
27
|
def to_local_bin
|
28
28
|
s = pack_for_local
|
29
|
-
self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v') << s
|
29
|
+
(self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v')) << s
|
30
30
|
end
|
31
31
|
|
32
32
|
def to_c_dir_bin
|
33
33
|
s = pack_for_c_dir
|
34
|
-
self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v') << s
|
34
|
+
(self.class.const_get(:HEADER_ID) + [s.bytesize].pack('v')) << s
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/zip/extra_field/ntfs.rb
CHANGED
@@ -25,7 +25,7 @@ module Zip
|
|
25
25
|
size, content = initial_parse(binstr)
|
26
26
|
(size && content) || return
|
27
27
|
|
28
|
-
content = content[4
|
28
|
+
content = content[4..]
|
29
29
|
tags = parse_tags(content)
|
30
30
|
|
31
31
|
tag1 = tags[1]
|
@@ -86,7 +86,7 @@ module Zip
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def from_ntfs_time(ntfs_time)
|
89
|
-
::Zip::DOSTime.at(ntfs_time / WINDOWS_TICK - SEC_TO_UNIX_EPOCH)
|
89
|
+
::Zip::DOSTime.at((ntfs_time / WINDOWS_TICK) - SEC_TO_UNIX_EPOCH)
|
90
90
|
end
|
91
91
|
|
92
92
|
def to_ntfs_time(time)
|
data/lib/zip/extra_field.rb
CHANGED
@@ -21,8 +21,8 @@ module Zip
|
|
21
21
|
def extra_field_type_unknown(binstr, len, index, local)
|
22
22
|
self['Unknown'] ||= Unknown.new
|
23
23
|
|
24
|
-
if !len || len + 4 > binstr[index
|
25
|
-
self['Unknown'].merge(binstr[index
|
24
|
+
if !len || len + 4 > binstr[index..].bytesize
|
25
|
+
self['Unknown'].merge(binstr[index..], local: local)
|
26
26
|
return
|
27
27
|
end
|
28
28
|
|