rubyzip 1.1.7 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +137 -54
  3. data/Rakefile +6 -4
  4. data/lib/zip/central_directory.rb +17 -13
  5. data/lib/zip/compressor.rb +1 -2
  6. data/lib/zip/constants.rb +57 -5
  7. data/lib/zip/crypto/decrypted_io.rb +40 -0
  8. data/lib/zip/crypto/null_encryption.rb +4 -6
  9. data/lib/zip/crypto/traditional_encryption.rb +14 -14
  10. data/lib/zip/decompressor.rb +22 -4
  11. data/lib/zip/deflater.rb +8 -6
  12. data/lib/zip/dos_time.rb +17 -13
  13. data/lib/zip/entry.rb +171 -148
  14. data/lib/zip/entry_set.rb +16 -14
  15. data/lib/zip/errors.rb +3 -0
  16. data/lib/zip/extra_field/generic.rb +14 -13
  17. data/lib/zip/extra_field/ntfs.rb +18 -16
  18. data/lib/zip/extra_field/old_unix.rb +12 -11
  19. data/lib/zip/extra_field/universal_time.rb +46 -16
  20. data/lib/zip/extra_field/unix.rb +10 -9
  21. data/lib/zip/extra_field/zip64.rb +15 -12
  22. data/lib/zip/extra_field/zip64_placeholder.rb +1 -2
  23. data/lib/zip/extra_field.rb +18 -16
  24. data/lib/zip/file.rb +147 -115
  25. data/lib/zip/filesystem.rb +289 -272
  26. data/lib/zip/inflater.rb +24 -36
  27. data/lib/zip/input_stream.rb +44 -28
  28. data/lib/zip/ioextras/abstract_input_stream.rb +24 -17
  29. data/lib/zip/ioextras/abstract_output_stream.rb +4 -6
  30. data/lib/zip/ioextras.rb +2 -4
  31. data/lib/zip/null_compressor.rb +2 -2
  32. data/lib/zip/null_decompressor.rb +3 -11
  33. data/lib/zip/null_input_stream.rb +0 -0
  34. data/lib/zip/output_stream.rb +25 -17
  35. data/lib/zip/pass_thru_compressor.rb +6 -6
  36. data/lib/zip/pass_thru_decompressor.rb +14 -24
  37. data/lib/zip/streamable_directory.rb +3 -3
  38. data/lib/zip/streamable_stream.rb +7 -11
  39. data/lib/zip/version.rb +1 -1
  40. data/lib/zip.rb +15 -6
  41. data/samples/example.rb +29 -39
  42. data/samples/example_filesystem.rb +16 -18
  43. data/samples/example_recursive.rb +31 -25
  44. data/samples/gtk_ruby_zip.rb +84 -0
  45. data/samples/qtzip.rb +23 -32
  46. data/samples/write_simple.rb +10 -13
  47. data/samples/zipfind.rb +33 -40
  48. metadata +50 -141
  49. data/samples/gtkRubyzip.rb +0 -86
  50. data/test/basic_zip_file_test.rb +0 -64
  51. data/test/central_directory_entry_test.rb +0 -73
  52. data/test/central_directory_test.rb +0 -104
  53. data/test/crypto/null_encryption_test.rb +0 -53
  54. data/test/crypto/traditional_encryption_test.rb +0 -80
  55. data/test/data/WarnInvalidDate.zip +0 -0
  56. data/test/data/file1.txt +0 -46
  57. data/test/data/file1.txt.deflatedData +0 -0
  58. data/test/data/file2.txt +0 -1504
  59. data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
  60. data/test/data/globTest/foo.txt +0 -0
  61. data/test/data/globTest/food.txt +0 -0
  62. data/test/data/globTest.zip +0 -0
  63. data/test/data/mimetype +0 -1
  64. data/test/data/notzippedruby.rb +0 -7
  65. data/test/data/ntfs.zip +0 -0
  66. data/test/data/rubycode.zip +0 -0
  67. data/test/data/rubycode2.zip +0 -0
  68. data/test/data/testDirectory.bin +0 -0
  69. data/test/data/zip64-sample.zip +0 -0
  70. data/test/data/zipWithDirs.zip +0 -0
  71. data/test/data/zipWithEncryption.zip +0 -0
  72. data/test/deflater_test.rb +0 -67
  73. data/test/encryption_test.rb +0 -42
  74. data/test/entry_set_test.rb +0 -138
  75. data/test/entry_test.rb +0 -165
  76. data/test/errors_test.rb +0 -36
  77. data/test/extra_field_test.rb +0 -78
  78. data/test/file_extract_directory_test.rb +0 -56
  79. data/test/file_extract_test.rb +0 -90
  80. data/test/file_split_test.rb +0 -60
  81. data/test/file_test.rb +0 -559
  82. data/test/filesystem/dir_iterator_test.rb +0 -62
  83. data/test/filesystem/directory_test.rb +0 -131
  84. data/test/filesystem/file_mutating_test.rb +0 -100
  85. data/test/filesystem/file_nonmutating_test.rb +0 -514
  86. data/test/filesystem/file_stat_test.rb +0 -66
  87. data/test/gentestfiles.rb +0 -134
  88. data/test/inflater_test.rb +0 -14
  89. data/test/input_stream_test.rb +0 -170
  90. data/test/ioextras/abstract_input_stream_test.rb +0 -103
  91. data/test/ioextras/abstract_output_stream_test.rb +0 -106
  92. data/test/ioextras/fake_io_test.rb +0 -18
  93. data/test/local_entry_test.rb +0 -156
  94. data/test/output_stream_test.rb +0 -129
  95. data/test/pass_thru_compressor_test.rb +0 -31
  96. data/test/pass_thru_decompressor_test.rb +0 -15
  97. data/test/settings_test.rb +0 -92
  98. data/test/test_helper.rb +0 -228
  99. data/test/unicode_file_names_and_comments_test.rb +0 -52
  100. data/test/zip64_full_test.rb +0 -53
  101. data/test/zip64_support_test.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 21b11d72a619a00f577f3ac15a65d309d07ab57b
4
- data.tar.gz: d2c28c4157e692118e26478c34205094eb2ca055
2
+ SHA256:
3
+ metadata.gz: 35bd078119c42cd2250fadd127a0feae3299184b0bf90804c3ff0bc28d1c427f
4
+ data.tar.gz: 98e034b50a428ff970f25b28348993d938a88c5d5c93506561761f260062c059
5
5
  SHA512:
6
- metadata.gz: 935e9064b3fc98693e8e0eef68f147b9a62ba4dcf25c9f42cf9828a544665d749fd8ff5866b52183a569171fd3aecddb09613d526da1bc43bf34c0b556bcea02
7
- data.tar.gz: b9e36842ed0830befe3ca556b954757975291f8c523be419213c5974015742e41c4bb4a4b44c88a746ad22f7656f23162cf5e5d5e7591d917927ae9830ad8dae
6
+ metadata.gz: 421a8884fbfe6f720e2e0da35f34e4208b96f83529faf5cba03501aa2693d95d51b9c19e04e4567801de1822120a0e14faf1c4d0991a164b8f0d011eaa6c0f7b
7
+ data.tar.gz: 59f29c6b49a14c777605224b351d8d14f7fdfe88a2ffc75a5f2120f51152831ed9afa04d8daf1f971bad982c3bcdd86e17d5616c8c9d57ddff7509b7f59e58b1
data/README.md CHANGED
@@ -1,14 +1,15 @@
1
1
  # rubyzip
2
+
2
3
  [![Gem Version](https://badge.fury.io/rb/rubyzip.svg)](http://badge.fury.io/rb/rubyzip)
3
4
  [![Build Status](https://secure.travis-ci.org/rubyzip/rubyzip.svg)](http://travis-ci.org/rubyzip/rubyzip)
4
5
  [![Code Climate](https://codeclimate.com/github/rubyzip/rubyzip.svg)](https://codeclimate.com/github/rubyzip/rubyzip)
5
6
  [![Coverage Status](https://img.shields.io/coveralls/rubyzip/rubyzip.svg)](https://coveralls.io/r/rubyzip/rubyzip?branch=master)
6
7
 
7
- rubyzip is a ruby library for reading and writing zip files.
8
+ Rubyzip is a ruby library for reading and writing zip files.
8
9
 
9
10
  ## Important note
10
11
 
11
- Rubyzip interface changed!!! No need to do `require "zip/zip"` and `Zip` prefix in class names removed.
12
+ The Rubyzip interface has changed!!! No need to do `require "zip/zip"` and `Zip` prefix in class names removed.
12
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
15
 
@@ -19,10 +20,11 @@ gem 'zip-zip' # will load compatibility for old rubyzip API.
19
20
 
20
21
  ## Requirements
21
22
 
22
- * Ruby 1.9.2 or greater
23
+ - Ruby 2.4 or greater (for rubyzip 2.0; use 1.x for older rubies)
23
24
 
24
25
  ## Installation
25
- rubyzip is available on RubyGems, so:
26
+
27
+ Rubyzip is available on RubyGems:
26
28
 
27
29
  ```
28
30
  gem install rubyzip
@@ -52,65 +54,76 @@ Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
52
54
  # Two arguments:
53
55
  # - The name of the file as it will appear in the archive
54
56
  # - The original file, including the path to find it
55
- zipfile.add(filename, folder + '/' + filename)
57
+ zipfile.add(filename, File.join(folder, filename))
56
58
  end
57
- zipfile.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
59
+ zipfile.get_output_stream("myFile") { |f| f.write "myFile contains just this" }
58
60
  end
59
61
  ```
60
62
 
61
63
  ### Zipping a directory recursively
62
- Copy from [here](https://github.com/rubyzip/rubyzip/blob/05916bf89181e1955118fd3ea059f18acac28cc8/samples/example_recursive.rb )
64
+
65
+ Copy from [here](https://github.com/rubyzip/rubyzip/blob/9d891f7353e66052283562d3e252fe380bb4b199/samples/example_recursive.rb)
63
66
 
64
67
  ```ruby
65
- require 'rubygems'
66
68
  require 'zip'
69
+
67
70
  # This is a simple example which uses rubyzip to
68
71
  # recursively generate a zip file from the contents of
69
72
  # a specified directory. The directory itself is not
70
73
  # included in the archive, rather just its contents.
71
74
  #
72
75
  # Usage:
73
- # require /path/to/the/ZipFileGenerator/Class
74
- # directoryToZip = "/tmp/input"
75
- # outputFile = "/tmp/out.zip"
76
- # zf = ZipFileGenerator.new(directoryToZip, outputFile)
77
- # zf.write()
78
-
76
+ # directory_to_zip = "/tmp/input"
77
+ # output_file = "/tmp/out.zip"
78
+ # zf = ZipFileGenerator.new(directory_to_zip, output_file)
79
+ # zf.write()
79
80
  class ZipFileGenerator
80
81
  # Initialize with the directory to zip and the location of the output archive.
81
- def initialize(inputDir, outputFile)
82
- @inputDir = inputDir
83
- @outputFile = outputFile
82
+ def initialize(input_dir, output_file)
83
+ @input_dir = input_dir
84
+ @output_file = output_file
84
85
  end
86
+
85
87
  # Zip the input directory.
86
- def write()
87
- entries = Dir.entries(@inputDir); entries.delete("."); entries.delete("..")
88
- io = Zip::File.open(@outputFile, Zip::File::CREATE);
89
- writeEntries(entries, "", io)
90
- io.close();
88
+ def write
89
+ entries = Dir.entries(@input_dir) - %w[. ..]
90
+
91
+ ::Zip::File.open(@output_file, ::Zip::File::CREATE) do |zipfile|
92
+ write_entries entries, '', zipfile
93
+ end
91
94
  end
92
- # A helper method to make the recursion work.
95
+
93
96
  private
94
- def writeEntries(entries, path, io)
95
- entries.each { |e|
96
- zipFilePath = path == "" ? e : File.join(path, e)
97
- diskFilePath = File.join(@inputDir, zipFilePath)
98
- puts "Deflating " + diskFilePath
99
- if File.directory?(diskFilePath)
100
- io.mkdir(zipFilePath)
101
- subdir =Dir.entries(diskFilePath); subdir.delete("."); subdir.delete("..")
102
- writeEntries(subdir, zipFilePath, io)
97
+
98
+ # A helper method to make the recursion work.
99
+ def write_entries(entries, path, zipfile)
100
+ entries.each do |e|
101
+ zipfile_path = path == '' ? e : File.join(path, e)
102
+ disk_file_path = File.join(@input_dir, zipfile_path)
103
+
104
+ if File.directory? disk_file_path
105
+ recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
103
106
  else
104
- io.get_output_stream(zipFilePath) { |f| f.print(File.open(diskFilePath, "rb").read())}
107
+ put_into_archive(disk_file_path, zipfile, zipfile_path)
105
108
  end
106
- }
109
+ end
110
+ end
111
+
112
+ def recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
113
+ zipfile.mkdir zipfile_path
114
+ subdir = Dir.entries(disk_file_path) - %w[. ..]
115
+ write_entries subdir, zipfile_path, zipfile
116
+ end
117
+
118
+ def put_into_archive(disk_file_path, zipfile, zipfile_path)
119
+ zipfile.add(zipfile_path, disk_file_path)
107
120
  end
108
121
  end
109
122
  ```
110
123
 
111
124
  ### Save zip archive entries in sorted by name state
112
125
 
113
- To saving zip archives in sorted order like below you need to set `::Zip.sort_entries` to `true`
126
+ To save zip archives in sorted order like below, you need to set `::Zip.sort_entries` to `true`
114
127
 
115
128
  ```
116
129
  Vegetable/
@@ -124,17 +137,30 @@ fruit/mango
124
137
  fruit/orange
125
138
  ```
126
139
 
127
- After this entries in zip archive will be saved in ordered state.
140
+ After this, entries in the zip archive will be saved in ordered state.
141
+
142
+ ### Default permissions of zip archives
143
+
144
+ On Posix file systems the default file permissions applied to a new archive
145
+ are (0666 - umask), which mimics the behavior of standard tools such as `touch`.
146
+
147
+ On Windows the default file permissions are set to 0644 as suggested by the
148
+ [Ruby File documentation](http://ruby-doc.org/core-2.2.2/File.html).
149
+
150
+ When modifying a zip archive the file permissions of the archive are preserved.
128
151
 
129
152
  ### Reading a Zip file
130
153
 
131
154
  ```ruby
155
+ MAX_SIZE = 1024**2 # 1MiB (but of course you can increase this)
132
156
  Zip::File.open('foo.zip') do |zip_file|
133
157
  # Handle entries one by one
134
158
  zip_file.each do |entry|
135
- # Extract to file/directory/symlink
136
159
  puts "Extracting #{entry.name}"
137
- entry.extract(dest_file)
160
+ raise 'File too large when extracted' if entry.size > MAX_SIZE
161
+
162
+ # Extract to file or directory based on name in the archive
163
+ entry.extract
138
164
 
139
165
  # Read into memory
140
166
  content = entry.get_input_stream.read
@@ -142,13 +168,24 @@ Zip::File.open('foo.zip') do |zip_file|
142
168
 
143
169
  # Find specific entry
144
170
  entry = zip_file.glob('*.csv').first
171
+ raise 'File too large when extracted' if entry.size > MAX_SIZE
145
172
  puts entry.get_input_stream.read
146
173
  end
147
174
  ```
148
175
 
176
+ #### Notice about ::Zip::InputStream
177
+
178
+ `::Zip::InputStream` usable for fast reading zip file content because it not read Central directory.
179
+
180
+ But there is one exception when it is not working - General Purpose Flag Bit 3.
181
+
182
+ > If bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written. The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure (optionally preceded by a 4-byte signature) immediately after the compressed data
183
+
184
+ If `::Zip::InputStream` finds such entry in the zip archive it will raise an exception.
185
+
149
186
  ### Password Protection (Experimental)
150
187
 
151
- 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.:
188
+ 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.:
152
189
 
153
190
  ```ruby
154
191
  Zip::OutputStream.write_buffer(::StringIO.new(''), Zip::TraditionalEncrypter.new('password')) do |out|
@@ -181,12 +218,14 @@ buffer = Zip::OutputStream.write_buffer do |out|
181
218
  out.write rels.to_xml(:indent => 0).gsub("\n","")
182
219
  end
183
220
 
184
- File.open(new_path, "w") {|f| f.write(buffer.string) }
221
+ File.open(new_path, "wb") {|f| f.write(buffer.string) }
185
222
  ```
186
223
 
187
224
  ## Configuration
188
225
 
189
- By default, rubyzip will not overwrite files if they already exist inside of the extracted path. To change this behavior, you may specify a configuration option like so:
226
+ ### Existing Files
227
+
228
+ By default, rubyzip will not overwrite files if they already exist inside of the extracted path. To change this behavior, you may specify a configuration option like so:
190
229
 
191
230
  ```ruby
192
231
  Zip.on_exists_proc = true
@@ -200,26 +239,78 @@ Additionally, if you want to configure rubyzip to overwrite existing files while
200
239
  Zip.continue_on_exists_proc = true
201
240
  ```
202
241
 
203
- If you want to store non english names and want to open properly file on Windows(pre 7) you need to set next option:
242
+ ### Non-ASCII Names
243
+
244
+ If you want to store non-english names and want to open them on Windows(pre 7) you need to set this option:
204
245
 
205
246
  ```ruby
206
247
  Zip.unicode_names = true
207
248
  ```
208
249
 
209
- In some zip date of files stored in incorrect format. You can hide warning about it by using:
250
+ Sometimes file names inside zip contain non-ASCII characters. If you can assume which encoding was used for such names and want to be able to find such entries using `find_entry` then you can force assumed encoding like so:
251
+
252
+ ```ruby
253
+ Zip.force_entry_names_encoding = 'UTF-8'
254
+ ```
255
+
256
+ Allowed encoding names are the same as accepted by `String#force_encoding`
257
+
258
+ ### Date Validation
259
+
260
+ Some zip files might have an invalid date format, which will raise a warning. You can hide this warning with the following setting:
210
261
 
211
262
  ```ruby
212
263
  Zip.warn_invalid_date = false
213
264
  ```
214
265
 
266
+ ### Size Validation
267
+
268
+ By default (in rubyzip >= 2.0), rubyzip's `extract` method checks that an entry's reported uncompressed size is not (significantly) smaller than its actual size. This is to help you protect your application against [zip bombs](https://en.wikipedia.org/wiki/Zip_bomb). Before `extract`ing an entry, you should check that its size is in the range you expect. For example, if your application supports processing up to 100 files at once, each up to 10MiB, your zip extraction code might look like:
269
+
270
+ ```ruby
271
+ MAX_FILE_SIZE = 10 * 1024**2 # 10MiB
272
+ MAX_FILES = 100
273
+ Zip::File.open('foo.zip') do |zip_file|
274
+ num_files = 0
275
+ zip_file.each do |entry|
276
+ num_files += 1 if entry.file?
277
+ raise 'Too many extracted files' if num_files > MAX_FILES
278
+ raise 'File too large when extracted' if entry.size > MAX_FILE_SIZE
279
+ entry.extract
280
+ end
281
+ end
282
+ ```
283
+
284
+ If you need to extract zip files that report incorrect uncompressed sizes and you really trust them not too be too large, you can disable this setting with
285
+ ```ruby
286
+ Zip.validate_entry_sizes = false
287
+ ```
288
+
289
+ Note that if you use the lower level `Zip::InputStream` interface, `rubyzip` does *not* check the entry `size`s. In this case, the caller is responsible for making sure it does not read more data than expected from the input stream.
290
+
291
+ ### Default Compression
292
+
215
293
  You can set the default compression level like so:
216
294
 
217
295
  ```ruby
218
296
  Zip.default_compression = Zlib::DEFAULT_COMPRESSION
219
297
  ```
298
+
220
299
  It defaults to `Zlib::DEFAULT_COMPRESSION`. Possible values are `Zlib::BEST_COMPRESSION`, `Zlib::DEFAULT_COMPRESSION` and `Zlib::NO_COMPRESSION`
221
300
 
222
- All settings in same time
301
+ ### Zip64 Support
302
+
303
+ By default, Zip64 support is disabled for writing. To enable it do this:
304
+
305
+ ```ruby
306
+ Zip.write_zip64_support = true
307
+ ```
308
+
309
+ _NOTE_: If you will enable Zip64 writing then you will need zip extractor with Zip64 support to extract archive.
310
+
311
+ ### Block Form
312
+
313
+ You can set multiple settings at the same time by using a block:
223
314
 
224
315
  ```ruby
225
316
  Zip.setup do |c|
@@ -230,17 +321,9 @@ All settings in same time
230
321
  end
231
322
  ```
232
323
 
233
- By default Zip64 support is disabled for writing. To enable it do next:
234
-
235
- ```ruby
236
- Zip.write_zip64_support = true
237
- ```
238
-
239
- _NOTE_: If you will enable Zip64 writing then you will need zip extractor with Zip64 support to extract archive.
240
-
241
324
  ## Developing
242
325
 
243
- To run tests you need run next commands:
326
+ To run the test you need to do this:
244
327
 
245
328
  ```
246
329
  bundle install
@@ -267,5 +350,5 @@ extra-field support contributed by Tatsuki Sugiura (sugi at nemui.org)
267
350
 
268
351
  ## License
269
352
 
270
- rubyzip is distributed under the same license as ruby. See
353
+ Rubyzip is distributed under the same license as ruby. See
271
354
  http://www.ruby-lang.org/en/LICENSE.txt
data/Rakefile CHANGED
@@ -1,7 +1,8 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
+ require 'rubocop/rake_task'
3
4
 
4
- task :default => :test
5
+ task default: :test
5
6
 
6
7
  Rake::TestTask.new(:test) do |test|
7
8
  test.libs << 'lib'
@@ -10,10 +11,11 @@ Rake::TestTask.new(:test) do |test|
10
11
  test.verbose = true
11
12
  end
12
13
 
13
- #Rake::TestTask.new(:zip64_full_test) do |test|
14
+ RuboCop::RakeTask.new
15
+
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')
16
19
  # test.pattern = File.join(File.dirname(__FILE__), 'test/zip64_full_test.rb')
17
20
  # test.verbose = true
18
- #end
19
-
21
+ # end
@@ -5,7 +5,7 @@ module Zip
5
5
  END_OF_CDS = 0x06054b50
6
6
  ZIP64_END_OF_CDS = 0x06064b50
7
7
  ZIP64_EOCD_LOCATOR = 0x07064b50
8
- MAX_END_OF_CDS_SIZE = 65536 + 18
8
+ MAX_END_OF_CDS_SIZE = 65_536 + 18
9
9
  STATIC_EOCD_SIZE = 22
10
10
 
11
11
  attr_reader :comment
@@ -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
@@ -96,7 +96,7 @@ module Zip
96
96
  @size_in_bytes = Entry.read_zip_64_long(buf)
97
97
  @cdir_offset = Entry.read_zip_64_long(buf)
98
98
  @zip_64_extensible = buf.slice!(0, buf.bytesize)
99
- raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0
99
+ raise Error, 'Zip consistency problem while reading eocd structure' unless buf.empty?
100
100
  end
101
101
 
102
102
  def read_e_o_c_d(buf) #:nodoc:
@@ -113,14 +113,14 @@ module Zip
113
113
  else
114
114
  buf.read(comment_length)
115
115
  end
116
- raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0
116
+ raise Error, 'Zip consistency problem while reading eocd structure' unless buf.empty?
117
117
  end
118
118
 
119
119
  def read_central_directory_entries(io) #:nodoc:
120
120
  begin
121
121
  io.seek(@cdir_offset, IO::SEEK_SET)
122
122
  rescue Errno::EINVAL
123
- raise Error, "Zip consistency problem while reading central directory entry"
123
+ raise Error, 'Zip consistency problem while reading central directory entry'
124
124
  end
125
125
  @entry_set = EntrySet.new
126
126
  @size.times do
@@ -130,7 +130,7 @@ module Zip
130
130
 
131
131
  def read_from_stream(io) #:nodoc:
132
132
  buf = start_buf(io)
133
- if self.zip64_file?(buf)
133
+ if zip64_file?(buf)
134
134
  read_64_e_o_c_d(buf)
135
135
  else
136
136
  read_e_o_c_d(buf)
@@ -140,7 +140,8 @@ module Zip
140
140
 
141
141
  def get_e_o_c_d(buf) #:nodoc:
142
142
  sig_index = buf.rindex([END_OF_CDS].pack('V'))
143
- raise Error, "Zip end of central directory signature not found" unless sig_index
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)
@@ -165,9 +166,11 @@ module Zip
165
166
 
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
- raise Error, "Zip64 end of central directory signature not found" unless zip_64_start
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
- raise Error, "Zip64 end of central directory signature locator not found" unless zip_64_locator
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
@@ -1,7 +1,6 @@
1
1
  module Zip
2
2
  class Compressor #:nodoc:all
3
- def finish
4
- end
3
+ def finish; end
5
4
  end
6
5
  end
7
6
 
data/lib/zip/constants.rb CHANGED
@@ -6,14 +6,14 @@ module Zip
6
6
 
7
7
  LOCAL_ENTRY_SIGNATURE = 0x04034b50
8
8
  LOCAL_ENTRY_STATIC_HEADER_LENGTH = 30
9
- LOCAL_ENTRY_TRAILING_DESCRIPTOR_LENGTH = 4+4+4
9
+ LOCAL_ENTRY_TRAILING_DESCRIPTOR_LENGTH = 4 + 4 + 4
10
10
  VERSION_MADE_BY = 52 # this library's version
11
11
  VERSION_NEEDED_TO_EXTRACT = 20
12
12
  VERSION_NEEDED_TO_EXTRACT_ZIP64 = 45
13
13
 
14
- FILE_TYPE_FILE = 010
15
- FILE_TYPE_DIR = 004
16
- FILE_TYPE_SYMLINK = 012
14
+ FILE_TYPE_FILE = 0o10
15
+ FILE_TYPE_DIR = 0o04
16
+ FILE_TYPE_SYMLINK = 0o12
17
17
 
18
18
  FSTYPE_FAT = 0
19
19
  FSTYPE_AMIGA = 1
@@ -58,6 +58,58 @@ module Zip
58
58
  FSTYPE_TANDEM => 'Tandem NSK'.freeze,
59
59
  FSTYPE_THEOS => 'Theos'.freeze,
60
60
  FSTYPE_MAC_OSX => 'Mac OS/X (Darwin)'.freeze,
61
- FSTYPE_ATHEOS => 'AtheOS'.freeze,
61
+ FSTYPE_ATHEOS => 'AtheOS'.freeze
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'
62
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
@@ -12,7 +12,7 @@ module Zip
12
12
  class NullEncrypter < Encrypter
13
13
  include NullEncryption
14
14
 
15
- def header(mtime)
15
+ def header(_mtime)
16
16
  ''
17
17
  end
18
18
 
@@ -20,12 +20,11 @@ module Zip
20
20
  data
21
21
  end
22
22
 
23
- def data_descriptor(crc32, compressed_size, uncomprssed_size)
23
+ def data_descriptor(_crc32, _compressed_size, _uncomprssed_size)
24
24
  ''
25
25
  end
26
26
 
27
- def reset!
28
- end
27
+ def reset!; end
29
28
  end
30
29
 
31
30
  class NullDecrypter < Decrypter
@@ -35,8 +34,7 @@ module Zip
35
34
  data
36
35
  end
37
36
 
38
- def reset!(header)
39
- end
37
+ def reset!(_header); end
40
38
  end
41
39
  end
42
40