rubyzip 2.0.0 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e2be8aa3dea85f1e99fa26b5b2530ede874228f35379181d5219eb3864a0e33
4
- data.tar.gz: '0985b8cd0b421a0bdf83953ba907ddad52d236948a81a242f322f0f5fa2145a6'
3
+ metadata.gz: 35bd078119c42cd2250fadd127a0feae3299184b0bf90804c3ff0bc28d1c427f
4
+ data.tar.gz: 98e034b50a428ff970f25b28348993d938a88c5d5c93506561761f260062c059
5
5
  SHA512:
6
- metadata.gz: c870bef8352ddb4e706a847f66da596fe556938d1b1422c3541f8ab24aa10bbdb6be577cd031853459101e24a4290aa816436834d1cae66dd26238b451f41d15
7
- data.tar.gz: bb5c8ca7d286346bfad64a6e1bd637cb8a40a99974bc62fbd76ea1a5ee139d16dcf52a8480cc219e48e311d84046feafab2c497cfbeb0721940a06a5c7a163a2
6
+ metadata.gz: 421a8884fbfe6f720e2e0da35f34e4208b96f83529faf5cba03501aa2693d95d51b9c19e04e4567801de1822120a0e14faf1c4d0991a164b8f0d011eaa6c0f7b
7
+ data.tar.gz: 59f29c6b49a14c777605224b351d8d14f7fdfe88a2ffc75a5f2120f51152831ed9afa04d8daf1f971bad982c3bcdd86e17d5616c8c9d57ddff7509b7f59e58b1
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
@@ -1,10 +1,11 @@
1
+ require 'English'
1
2
  require 'delegate'
2
3
  require 'singleton'
3
4
  require 'tempfile'
4
- require 'tmpdir'
5
5
  require 'fileutils'
6
6
  require 'stringio'
7
7
  require 'zlib'
8
+ require 'zip/constants'
8
9
  require 'zip/dos_time'
9
10
  require 'zip/ioextras'
10
11
  require 'rbconfig'
@@ -22,6 +23,7 @@ require 'zip/null_compressor'
22
23
  require 'zip/null_input_stream'
23
24
  require 'zip/pass_thru_compressor'
24
25
  require 'zip/pass_thru_decompressor'
26
+ require 'zip/crypto/decrypted_io'
25
27
  require 'zip/crypto/encryption'
26
28
  require 'zip/crypto/null_encryption'
27
29
  require 'zip/crypto/traditional_encryption'
@@ -29,7 +31,6 @@ require 'zip/inflater'
29
31
  require 'zip/deflater'
30
32
  require 'zip/streamable_stream'
31
33
  require 'zip/streamable_directory'
32
- require 'zip/constants'
33
34
  require 'zip/errors'
34
35
 
35
36
  module Zip
@@ -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, # offset of start of central directory in its disk
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(&proc)
182
- @entry_set.each(&proc)
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
- return cdir
197
+ cdir
195
198
  rescue Error
196
- return nil
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
@@ -60,4 +60,56 @@ module Zip
60
60
  FSTYPE_MAC_OSX => 'Mac OS/X (Darwin)'.freeze,
61
61
  FSTYPE_ATHEOS => 'AtheOS'.freeze
62
62
  }.freeze
63
+
64
+ COMPRESSION_METHOD_STORE = 0
65
+ COMPRESSION_METHOD_SHRINK = 1
66
+ COMPRESSION_METHOD_REDUCE_1 = 2
67
+ COMPRESSION_METHOD_REDUCE_2 = 3
68
+ COMPRESSION_METHOD_REDUCE_3 = 4
69
+ COMPRESSION_METHOD_REDUCE_4 = 5
70
+ COMPRESSION_METHOD_IMPLODE = 6
71
+ # RESERVED = 7
72
+ COMPRESSION_METHOD_DEFLATE = 8
73
+ COMPRESSION_METHOD_DEFLATE_64 = 9
74
+ COMPRESSION_METHOD_PKWARE_DCLI = 10
75
+ # RESERVED = 11
76
+ COMPRESSION_METHOD_BZIP2 = 12
77
+ # RESERVED = 13
78
+ COMPRESSION_METHOD_LZMA = 14
79
+ # RESERVED = 15
80
+ COMPRESSION_METHOD_IBM_CMPSC = 16
81
+ # RESERVED = 17
82
+ COMPRESSION_METHOD_IBM_TERSE = 18
83
+ COMPRESSION_METHOD_IBM_LZ77 = 19
84
+ COMPRESSION_METHOD_JPEG = 96
85
+ COMPRESSION_METHOD_WAVPACK = 97
86
+ COMPRESSION_METHOD_PPMD = 98
87
+ COMPRESSION_METHOD_AES = 99
88
+
89
+ COMPRESSION_METHODS = {
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
+ # RESERVED = 7
98
+ COMPRESSION_METHOD_DEFLATE => 'Deflate',
99
+ COMPRESSION_METHOD_DEFLATE_64 => 'Deflate64(tm)',
100
+ COMPRESSION_METHOD_PKWARE_DCLI => 'PKWARE Data Compression Library Imploding (old IBM TERSE)',
101
+ # RESERVED = 11
102
+ COMPRESSION_METHOD_BZIP2 => 'BZIP2',
103
+ # RESERVED = 13
104
+ COMPRESSION_METHOD_LZMA => 'LZMA',
105
+ # RESERVED = 15
106
+ COMPRESSION_METHOD_IBM_CMPSC => 'IBM z/OS CMPSC Compression',
107
+ # RESERVED = 17
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
+ }.freeze
63
115
  end
@@ -0,0 +1,40 @@
1
+ module Zip
2
+ class DecryptedIo #:nodoc:all
3
+ CHUNK_SIZE = 32_768
4
+
5
+ def initialize(io, decrypter)
6
+ @io = io
7
+ @decrypter = decrypter
8
+ end
9
+
10
+ def read(length = nil, outbuf = +'')
11
+ return (length.nil? || length.zero? ? '' : nil) if eof
12
+
13
+ while length.nil? || (buffer.bytesize < length)
14
+ break if input_finished?
15
+
16
+ buffer << produce_input
17
+ end
18
+
19
+ outbuf.replace(buffer.slice!(0...(length || output_buffer.bytesize)))
20
+ end
21
+
22
+ private
23
+
24
+ def eof
25
+ buffer.empty? && input_finished?
26
+ end
27
+
28
+ def buffer
29
+ @buffer ||= +''
30
+ end
31
+
32
+ def input_finished?
33
+ @io.eof
34
+ end
35
+
36
+ def produce_input
37
+ @decrypter.decrypt(@io.read(CHUNK_SIZE))
38
+ end
39
+ end
40
+ end
@@ -24,8 +24,8 @@ module Zip
24
24
  end
25
25
  end
26
26
 
27
- def update_keys(n)
28
- @key0 = ~Zlib.crc32(n, ~@key0)
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(n)
66
+ def encode(num)
67
67
  t = decrypt_byte
68
- update_keys(n.chr)
69
- t ^ n
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(n)
90
- n ^= decrypt_byte
91
- update_keys(n.chr)
92
- n
89
+ def decode(num)
90
+ num ^= decrypt_byte
91
+ update_keys(num.chr)
92
+ num
93
93
  end
94
94
  end
95
95
  end
@@ -1,9 +1,27 @@
1
1
  module Zip
2
2
  class Decompressor #:nodoc:all
3
3
  CHUNK_SIZE = 32_768
4
- def initialize(input_stream)
4
+
5
+ def self.decompressor_classes
6
+ @decompressor_classes ||= {}
7
+ end
8
+
9
+ def self.register(compression_method, decompressor_class)
10
+ decompressor_classes[compression_method] = decompressor_class
11
+ end
12
+
13
+ def self.find_by_compression_method(compression_method)
14
+ decompressor_classes[compression_method]
15
+ end
16
+
17
+ attr_reader :input_stream
18
+ attr_reader :decompressed_size
19
+
20
+ def initialize(input_stream, decompressed_size = nil)
5
21
  super()
22
+
6
23
  @input_stream = input_stream
24
+ @decompressed_size = decompressed_size
7
25
  end
8
26
  end
9
27
  end
data/lib/zip/dos_time.rb CHANGED
@@ -29,13 +29,18 @@ module Zip
29
29
  to_i / 2 == other.to_i / 2
30
30
  end
31
31
 
32
- def self.parse_binary_dos_format(binaryDosDate, binaryDosTime)
33
- second = 2 * (0b11111 & binaryDosTime)
34
- minute = (0b11111100000 & binaryDosTime) >> 5
35
- hour = (0b1111100000000000 & binaryDosTime) >> 11
36
- day = (0b11111 & binaryDosDate)
37
- month = (0b111100000 & binaryDosDate) >> 5
38
- year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
32
+ # Create a DOSTime instance from a vanilla Time instance.
33
+ def self.from_time(time)
34
+ local(time.year, time.month, time.day, time.hour, time.min, time.sec)
35
+ end
36
+
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
39
44
  begin
40
45
  local(year, month, day, hour, minute, second)
41
46
  end
data/lib/zip/entry.rb CHANGED
@@ -34,7 +34,7 @@ module Zip
34
34
  end
35
35
  @follow_symlinks = false
36
36
 
37
- @restore_times = true
37
+ @restore_times = false
38
38
  @restore_permissions = false
39
39
  @restore_ownership = false
40
40
  # BUG: need an extra field to support uid/gid's
@@ -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,15 @@ 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.is_a?(::Zip::ExtraField)
73
+ @extra = ::Zip::ExtraField.new(@extra.to_s) unless @extra.kind_of?(::Zip::ExtraField)
74
+ end
75
+
76
+ def encrypted?
77
+ gp_flags & 1 == 1
78
+ end
79
+
80
+ def incomplete?
81
+ gp_flags & 8 == 8
73
82
  end
74
83
 
75
84
  def time
@@ -91,11 +100,12 @@ module Zip
91
100
  @extra.create('UniversalTime')
92
101
  end
93
102
  (@extra['UniversalTime'] || @extra['NTFS']).mtime = value
94
- @time = value
103
+ @time = value
95
104
  end
96
105
 
97
106
  def file_type_is?(type)
98
107
  raise InternalError, "current filetype is unknown: #{inspect}" unless @ftype
108
+
99
109
  @ftype == type
100
110
  end
101
111
 
@@ -116,6 +126,7 @@ module Zip
116
126
  def name_safe?
117
127
  cleanpath = Pathname.new(@name).cleanpath
118
128
  return false unless cleanpath.relative?
129
+
119
130
  root = ::File::SEPARATOR
120
131
  naive_expanded_path = ::File.join(root, cleanpath.to_s)
121
132
  ::File.absolute_path(cleanpath.to_s, root) == naive_expanded_path
@@ -145,6 +156,7 @@ module Zip
145
156
  # that we didn't change the header size (and thus clobber file data or something)
146
157
  def verify_local_header_size!
147
158
  return if @local_header_size.nil?
159
+
148
160
  new_size = calculate_local_header_size
149
161
  raise Error, "local header size changed (#{@local_header_size} -> #{new_size})" if @local_header_size != new_size
150
162
  end
@@ -163,19 +175,16 @@ module Zip
163
175
  # is passed.
164
176
  def extract(dest_path = nil, &block)
165
177
  if dest_path.nil? && !name_safe?
166
- puts "WARNING: skipped #{@name} as unsafe"
178
+ warn "WARNING: skipped '#{@name}' as unsafe."
167
179
  return self
168
180
  end
169
181
 
170
182
  dest_path ||= @name
171
183
  block ||= proc { ::Zip.on_exists_proc }
172
184
 
173
- if directory? || file? || symlink?
174
- __send__("create_#{@ftype}", dest_path, &block)
175
- else
176
- raise "unknown file type #{inspect}"
177
- end
185
+ raise "unknown file type #{inspect}" unless directory? || file? || symlink?
178
186
 
187
+ __send__("create_#{@ftype}", dest_path, &block)
179
188
  self
180
189
  end
181
190
 
@@ -185,15 +194,15 @@ module Zip
185
194
 
186
195
  class << self
187
196
  def read_zip_short(io) # :nodoc:
188
- io.read(2).unpack('v')[0]
197
+ io.read(2).unpack1('v')
189
198
  end
190
199
 
191
200
  def read_zip_long(io) # :nodoc:
192
- io.read(4).unpack('V')[0]
201
+ io.read(4).unpack1('V')
193
202
  end
194
203
 
195
204
  def read_zip_64_long(io) # :nodoc:
196
- io.read(8).unpack('Q<')[0]
205
+ io.read(8).unpack1('Q<')
197
206
  end
198
207
 
199
208
  def read_c_dir_entry(io) #:nodoc:all
@@ -218,8 +227,6 @@ module Zip
218
227
  end
219
228
  end
220
229
 
221
- public
222
-
223
230
  def unpack_local_entry(buf)
224
231
  @header_signature,
225
232
  @version,
@@ -249,6 +256,7 @@ module Zip
249
256
  unless @header_signature == ::Zip::LOCAL_ENTRY_SIGNATURE
250
257
  raise ::Zip::Error, "Zip local header magic not found at location '#{local_header_offset}'"
251
258
  end
259
+
252
260
  set_time(@last_mod_date, @last_mod_time)
253
261
 
254
262
  @name = io.read(@name_length)
@@ -261,13 +269,14 @@ module Zip
261
269
 
262
270
  if extra && extra.bytesize != @extra_length
263
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
264
276
  else
265
- if @extra.is_a?(::Zip::ExtraField)
266
- @extra.merge(extra) if extra
267
- else
268
- @extra = ::Zip::ExtraField.new(extra)
269
- end
277
+ @extra = ::Zip::ExtraField.new(extra)
270
278
  end
279
+
271
280
  parse_zip64_extra(true)
272
281
  @local_header_size = calculate_local_header_size
273
282
  end
@@ -354,21 +363,24 @@ module Zip
354
363
 
355
364
  def check_c_dir_entry_static_header_length(buf)
356
365
  return if buf.bytesize == ::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH
366
+
357
367
  raise Error, 'Premature end of file. Not enough data for zip cdir entry header'
358
368
  end
359
369
 
360
370
  def check_c_dir_entry_signature
361
371
  return if header_signature == ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
372
+
362
373
  raise Error, "Zip local header magic not found at location '#{local_header_offset}'"
363
374
  end
364
375
 
365
376
  def check_c_dir_entry_comment_size
366
377
  return if @comment && @comment.bytesize == @comment_length
378
+
367
379
  raise ::Zip::Error, 'Truncated cdir zip entry header'
368
380
  end
369
381
 
370
382
  def read_c_dir_extra_field(io)
371
- if @extra.is_a?(::Zip::ExtraField)
383
+ if @extra.kind_of?(::Zip::ExtraField)
372
384
  @extra.merge(io.read(@extra_length))
373
385
  else
374
386
  @extra = ::Zip::ExtraField.new(io.read(@extra_length))
@@ -402,20 +414,25 @@ module Zip
402
414
 
403
415
  def get_extra_attributes_from_path(path) # :nodoc:
404
416
  return if Zip::RUNNING_ON_WINDOWS
417
+
405
418
  stat = file_stat(path)
406
419
  @unix_uid = stat.uid
407
420
  @unix_gid = stat.gid
408
421
  @unix_perms = stat.mode & 0o7777
422
+ @time = ::Zip::DOSTime.from_time(stat.mtime)
409
423
  end
410
424
 
411
- def set_unix_permissions_on_path(dest_path)
412
- # BUG: does not update timestamps into account
425
+ def set_unix_attributes_on_path(dest_path)
413
426
  # ignore setuid/setgid bits by default. honor if @restore_ownership
414
427
  unix_perms_mask = 0o1777
415
428
  unix_perms_mask = 0o7777 if @restore_ownership
416
429
  ::FileUtils.chmod(@unix_perms & unix_perms_mask, dest_path) if @restore_permissions && @unix_perms
417
430
  ::FileUtils.chown(@unix_uid, @unix_gid, dest_path) if @restore_ownership && @unix_uid && @unix_gid && ::Process.egid == 0
418
- # File::utimes()
431
+
432
+ # Restore the timestamp on a file. This will either have come from the
433
+ # original source file that was copied into the archive, or from the
434
+ # creation date of the archive if there was no original source file.
435
+ ::FileUtils.touch(dest_path, mtime: time) if @restore_times
419
436
  end
420
437
 
421
438
  def set_extra_attributes_on_path(dest_path) # :nodoc:
@@ -423,7 +440,7 @@ module Zip
423
440
 
424
441
  case @fstype
425
442
  when ::Zip::FSTYPE_UNIX
426
- set_unix_permissions_on_path(dest_path)
443
+ set_unix_attributes_on_path(dest_path)
427
444
  end
428
445
  end
429
446
 
@@ -484,6 +501,7 @@ module Zip
484
501
 
485
502
  def ==(other)
486
503
  return false unless other.class == self.class
504
+
487
505
  # Compares contents of local entry and exposed fields
488
506
  keys_equal = %w[compression_method crc compressed_size size name extra filepath].all? do |k|
489
507
  other.__send__(k.to_sym) == __send__(k.to_sym)
@@ -591,7 +609,7 @@ module Zip
591
609
  def set_time(binary_dos_date, binary_dos_time)
592
610
  @time = ::Zip::DOSTime.parse_binary_dos_format(binary_dos_date, binary_dos_time)
593
611
  rescue ArgumentError
594
- warn 'Invalid date/time in zip entry' if ::Zip.warn_invalid_date
612
+ warn 'WARNING: invalid date/time in zip entry.' if ::Zip.warn_invalid_date
595
613
  end
596
614
 
597
615
  def create_file(dest_path, _continue_on_exists_proc = proc { Zip.continue_on_exists_proc })
@@ -601,30 +619,29 @@ module Zip
601
619
  end
602
620
  ::File.open(dest_path, 'wb') do |os|
603
621
  get_input_stream do |is|
604
- set_extra_attributes_on_path(dest_path)
605
-
606
622
  bytes_written = 0
607
623
  warned = false
608
- buf = ''.dup
624
+ buf = +''
609
625
  while (buf = is.sysread(::Zip::Decompressor::CHUNK_SIZE, buf))
610
626
  os << buf
611
627
  bytes_written += buf.bytesize
612
- if bytes_written > size && !warned
613
- message = "Entry #{name} should be #{size}B but is larger when inflated"
614
- if ::Zip.validate_entry_sizes
615
- raise ::Zip::EntrySizeError, message
616
- else
617
- puts "WARNING: #{message}"
618
- warned = true
619
- end
620
- 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
621
635
  end
622
636
  end
623
637
  end
638
+
639
+ set_extra_attributes_on_path(dest_path)
624
640
  end
625
641
 
626
642
  def create_directory(dest_path)
627
643
  return if ::File.directory?(dest_path)
644
+
628
645
  if ::File.exist?(dest_path)
629
646
  if block_given? && yield(self, dest_path)
630
647
  ::FileUtils.rm_f dest_path
@@ -642,13 +659,14 @@ module Zip
642
659
  def create_symlink(dest_path)
643
660
  # TODO: Symlinks pose security challenges. Symlink support temporarily
644
661
  # removed in view of https://github.com/rubyzip/rubyzip/issues/369 .
645
- puts "WARNING: skipped symlink #{dest_path}"
662
+ warn "WARNING: skipped symlink '#{dest_path}'."
646
663
  end
647
664
 
648
665
  # apply missing data from the zip64 extra information field, if present
649
666
  # (required when file sizes exceed 2**32, but can be used for all files)
650
667
  def parse_zip64_extra(for_local_header) #:nodoc:all
651
668
  return if @extra['Zip64'].nil?
669
+
652
670
  if for_local_header
653
671
  @size, @compressed_size = @extra['Zip64'].parse(@size, @compressed_size)
654
672
  else
@@ -663,6 +681,7 @@ module Zip
663
681
  # create a zip64 extra information field if we need one
664
682
  def prep_zip64_extra(for_local_header) #:nodoc:all
665
683
  return unless ::Zip.write_zip64_support
684
+
666
685
  need_zip64 = @size >= 0xFFFFFFFF || @compressed_size >= 0xFFFFFFFF
667
686
  need_zip64 ||= @local_header_offset >= 0xFFFFFFFF unless for_local_header
668
687
  if need_zip64