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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cba65b486ec6325e6623957990539a225398a2b9b665b5814a5c06ba70ea1744
4
- data.tar.gz: 37dc716e5d98048e1b0c72165c16deb6a6bfef02556890f783cdc62ff5021f4e
3
+ metadata.gz: 8ffab0e42187d7bbd5b732ff0b9395a6215587a18ce5dd9d64da46d1c628a69c
4
+ data.tar.gz: 3032ae5d4f62644c1a19d5de25d515844ecb8da0f59c774fcaa6b16904f496b7
5
5
  SHA512:
6
- metadata.gz: 45de19fa6e2c549c07830243686d622adb937509a942eeb1412a05ea6d1f4a1bde5d60429446ff64f607f3a55400a38c9ccd2d30380825fb4b6e55618702d802
7
- data.tar.gz: 8d22f9bc464d950e9ede9cfc1da1056ba664ede954b93ae12d0af68e1d859600d8cd63ba5768553f3d810a693d38ce912c0c2d0f3b3d130da973c8bd833fb3bc
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
@@ -1,3 +1,4 @@
1
+ require 'English'
1
2
  require 'delegate'
2
3
  require 'singleton'
3
4
  require 'tempfile'
@@ -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
@@ -87,29 +87,29 @@ module Zip
87
87
  COMPRESSION_METHOD_AES = 99
88
88
 
89
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',
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 => 'Deflate',
99
- COMPRESSION_METHOD_DEFLATE_64 => 'Deflate64(tm)',
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 => 'BZIP2',
102
+ COMPRESSION_METHOD_BZIP2 => 'BZIP2',
103
103
  # RESERVED = 13
104
- COMPRESSION_METHOD_LZMA => 'LZMA',
104
+ COMPRESSION_METHOD_LZMA => 'LZMA',
105
105
  # RESERVED = 15
106
- COMPRESSION_METHOD_IBM_CMPSC => 'IBM z/OS CMPSC Compression',
106
+ COMPRESSION_METHOD_IBM_CMPSC => 'IBM z/OS CMPSC Compression',
107
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',
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 ((length.nil? || length.zero?) ? "" : nil) if eof
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 ||= ''.dup
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(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
@@ -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(binaryDosDate, binaryDosTime)
38
- second = 2 * (0b11111 & binaryDosTime)
39
- minute = (0b11111100000 & binaryDosTime) >> 5
40
- hour = (0b1111100000000000 & binaryDosTime) >> 11
41
- day = (0b11111 & binaryDosDate)
42
- month = (0b111100000 & binaryDosDate) >> 5
43
- year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
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
@@ -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.is_a?(::Zip::ExtraField)
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 = value
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
- if directory? || file? || symlink?
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).unpack('v')[0]
197
+ io.read(2).unpack1('v')
197
198
  end
198
199
 
199
200
  def read_zip_long(io) # :nodoc:
200
- io.read(4).unpack('V')[0]
201
+ io.read(4).unpack1('V')
201
202
  end
202
203
 
203
204
  def read_zip_64_long(io) # :nodoc:
204
- io.read(8).unpack('Q<')[0]
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
- if @extra.is_a?(::Zip::ExtraField)
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.is_a?(::Zip::ExtraField)
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 = ''.dup
624
+ buf = +''
619
625
  while (buf = is.sysread(::Zip::Decompressor::CHUNK_SIZE, buf))
620
626
  os << buf
621
627
  bytes_written += buf.bytesize
622
- if bytes_written > size && !warned
623
- message = "entry '#{name}' should be #{size}B, but is larger when inflated."
624
- if ::Zip.validate_entry_sizes
625
- raise ::Zip::EntrySizeError, message
626
- else
627
- warn "WARNING: #{message}"
628
- warned = true
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
@@ -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
@@ -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, i)
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[i, len + 4])
12
+ self[field_name].merge(binstr[index, len + 4])
13
13
  else
14
- field_obj = ID_MAP[id].new(binstr[i, len + 4])
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, i)
19
+ def extra_field_type_unknown(binstr, len, index)
20
20
  create_unknown_item unless self['Unknown']
21
- if !len || len + 4 > binstr[i..-1].bytesize
22
- self['Unknown'] << binstr[i..-1]
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[i, len + 4]
25
+ self['Unknown'] << binstr[index, len + 4]
26
26
  end
27
27
 
28
28
  def create_unknown_item
29
- s = ''.dup
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.unpack('v').first
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