rubyzip 2.2.0 → 2.3.0

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 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