rubyzip 2.0.0 → 2.4.1

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -9
  3. data/Rakefile +3 -0
  4. data/lib/zip/central_directory.rb +9 -5
  5. data/lib/zip/constants.rb +52 -0
  6. data/lib/zip/crypto/decrypted_io.rb +40 -0
  7. data/lib/zip/crypto/traditional_encryption.rb +9 -9
  8. data/lib/zip/decompressor.rb +19 -1
  9. data/lib/zip/dos_time.rb +24 -12
  10. data/lib/zip/entry.rb +107 -49
  11. data/lib/zip/entry_set.rb +2 -0
  12. data/lib/zip/errors.rb +1 -0
  13. data/lib/zip/extra_field/generic.rb +10 -9
  14. data/lib/zip/extra_field/ntfs.rb +5 -1
  15. data/lib/zip/extra_field/old_unix.rb +3 -1
  16. data/lib/zip/extra_field/universal_time.rb +42 -12
  17. data/lib/zip/extra_field/unix.rb +3 -1
  18. data/lib/zip/extra_field/zip64.rb +5 -3
  19. data/lib/zip/extra_field.rb +11 -9
  20. data/lib/zip/file.rb +142 -65
  21. data/lib/zip/filesystem.rb +193 -177
  22. data/lib/zip/inflater.rb +24 -36
  23. data/lib/zip/input_stream.rb +50 -30
  24. data/lib/zip/ioextras/abstract_input_stream.rb +23 -12
  25. data/lib/zip/ioextras/abstract_output_stream.rb +1 -1
  26. data/lib/zip/ioextras.rb +3 -3
  27. data/lib/zip/null_decompressor.rb +1 -9
  28. data/lib/zip/output_stream.rb +28 -12
  29. data/lib/zip/pass_thru_compressor.rb +2 -2
  30. data/lib/zip/pass_thru_decompressor.rb +13 -22
  31. data/lib/zip/streamable_directory.rb +3 -3
  32. data/lib/zip/streamable_stream.rb +6 -10
  33. data/lib/zip/version.rb +1 -1
  34. data/lib/zip.rb +22 -2
  35. data/samples/example.rb +2 -2
  36. data/samples/example_filesystem.rb +1 -1
  37. data/samples/gtk_ruby_zip.rb +19 -19
  38. data/samples/qtzip.rb +6 -6
  39. data/samples/write_simple.rb +2 -4
  40. data/samples/zipfind.rb +23 -22
  41. metadata +52 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e2be8aa3dea85f1e99fa26b5b2530ede874228f35379181d5219eb3864a0e33
4
- data.tar.gz: '0985b8cd0b421a0bdf83953ba907ddad52d236948a81a242f322f0f5fa2145a6'
3
+ metadata.gz: 2d59784cc9a5e884c6537a896b30b1a18206c7a97a0f74e37bd58769f0700497
4
+ data.tar.gz: 7e4bf8643b179bb0e5415b0f6aa7e92ce4786ed734cf23b902ea9739d5c46bb9
5
5
  SHA512:
6
- metadata.gz: c870bef8352ddb4e706a847f66da596fe556938d1b1422c3541f8ab24aa10bbdb6be577cd031853459101e24a4290aa816436834d1cae66dd26238b451f41d15
7
- data.tar.gz: bb5c8ca7d286346bfad64a6e1bd637cb8a40a99974bc62fbd76ea1a5ee139d16dcf52a8480cc219e48e311d84046feafab2c497cfbeb0721940a06a5c7a163a2
6
+ metadata.gz: c65346fc54aa6e931f8975a8e98212323a597583523a251d2d88184971a9469a549e9cd967c2d6015002f07fe8c19b13d96261781131b9bd7a0b099da1c04fe2
7
+ data.tar.gz: b397b12e1bef39a1cd4ade2698756f3194ed75504fb15ea5494dc26189be4a8d66af1a2411e827b660f67044ef4ee207c3d951d190886912079ce8ffcbf19bac
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # rubyzip
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/rubyzip.svg)](http://badge.fury.io/rb/rubyzip)
4
- [![Build Status](https://secure.travis-ci.org/rubyzip/rubyzip.svg)](http://travis-ci.org/rubyzip/rubyzip)
4
+ [![Tests](https://github.com/rubyzip/rubyzip/actions/workflows/tests.yml/badge.svg)](https://github.com/rubyzip/rubyzip/actions/workflows/tests.yml)
5
5
  [![Code Climate](https://codeclimate.com/github/rubyzip/rubyzip.svg)](https://codeclimate.com/github/rubyzip/rubyzip)
6
6
  [![Coverage Status](https://img.shields.io/coveralls/rubyzip/rubyzip.svg)](https://coveralls.io/r/rubyzip/rubyzip?branch=master)
7
7
 
@@ -9,18 +9,26 @@ Rubyzip is a ruby library for reading and writing zip files.
9
9
 
10
10
  ## Important note
11
11
 
12
- The Rubyzip interface has changed!!! No need to do `require "zip/zip"` and `Zip` prefix in class names removed.
12
+ Rubyzip 2.4 is intended to be the last release in the 2.x series. Please get ready for version 3.0.
13
13
 
14
- If you have issues with any third-party gems that require an old version of rubyzip, you can use this workaround:
14
+ ### Updating to version 3.0
15
15
 
16
- ```ruby
17
- gem 'rubyzip', '>= 1.0.0' # will load new rubyzip version
18
- gem 'zip-zip' # will load compatibility for old rubyzip API.
19
- ```
16
+ The public API of some classes has been modernized to use named parameters for optional arguments. Also some methods have been changed or removed. Please check your usage of the following Rubyzip classes:
17
+ * `File`
18
+ * `Entry`
19
+ * `InputStream`
20
+ * `OutputStream`
21
+ * `DOSTime`
22
+
23
+ **Please see [Updating to version 3.x](https://github.com/rubyzip/rubyzip/wiki/Updating-to-version-3.x) in the wiki for details.**
20
24
 
21
25
  ## Requirements
22
26
 
23
- - Ruby 2.4 or greater (for rubyzip 2.0; use 1.x for older rubies)
27
+ Version 3.x requires at least Ruby 3.0.
28
+
29
+ Version 2.x requires at least Ruby 2.4, and is known to work on Ruby 3.x.
30
+
31
+ It is not recommended to use any versions of Rubyzip earlier than 2.3 due to security issues.
24
32
 
25
33
  ## Installation
26
34
 
@@ -188,7 +196,7 @@ If `::Zip::InputStream` finds such entry in the zip archive it will raise an exc
188
196
  Rubyzip supports reading/writing zip files with traditional zip encryption (a.k.a. "ZipCrypto"). AES encryption is not yet supported. It can be used with buffer streams, e.g.:
189
197
 
190
198
  ```ruby
191
- Zip::OutputStream.write_buffer(::StringIO.new(''), Zip::TraditionalEncrypter.new('password')) do |out|
199
+ Zip::OutputStream.write_buffer(::StringIO.new, Zip::TraditionalEncrypter.new('password')) do |out|
192
200
  out.put_next_entry("my_file.txt")
193
201
  out.write my_data
194
202
  end.string
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')
@@ -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
@@ -24,21 +24,33 @@ module Zip
24
24
  ((year - 1980) << 9)
25
25
  end
26
26
 
27
- # Dos time is only stored with two seconds accuracy
28
27
  def dos_equals(other)
29
- to_i / 2 == other.to_i / 2
28
+ Zip.warn_about_v3_api('DOSTime#dos_equals')
29
+
30
+ self == other
31
+ end
32
+
33
+ # Dos time is only stored with two seconds accuracy.
34
+ def <=>(other)
35
+ return unless other.kind_of?(Time)
36
+
37
+ (to_i / 2) <=> (other.to_i / 2)
30
38
  end
31
39
 
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
39
- begin
40
- local(year, month, day, hour, minute, second)
41
- end
40
+ # Create a DOSTime instance from a vanilla Time instance.
41
+ def self.from_time(time)
42
+ local(time.year, time.month, time.day, time.hour, time.min, time.sec)
43
+ end
44
+
45
+ def self.parse_binary_dos_format(bin_dos_date, bin_dos_time)
46
+ second = 2 * (0b11111 & bin_dos_time)
47
+ minute = (0b11111100000 & bin_dos_time) >> 5
48
+ hour = (0b1111100000000000 & bin_dos_time) >> 11
49
+ day = (0b11111 & bin_dos_date)
50
+ month = (0b111100000 & bin_dos_date) >> 5
51
+ year = ((0b1111111000000000 & bin_dos_date) >> 9) + 1980
52
+
53
+ local(year, month, day, hour, minute, second)
42
54
  end
43
55
  end
44
56
  end