rubyzip 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubyzip might be problematic. Click here for more details.

Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -17
  3. data/lib/zip.rb +9 -1
  4. data/lib/zip/central_directory.rb +3 -3
  5. data/lib/zip/compressor.rb +1 -2
  6. data/lib/zip/constants.rb +3 -3
  7. data/lib/zip/crypto/null_encryption.rb +2 -4
  8. data/lib/zip/decompressor.rb +1 -1
  9. data/lib/zip/dos_time.rb +1 -1
  10. data/lib/zip/entry.rb +46 -49
  11. data/lib/zip/entry_set.rb +3 -3
  12. data/lib/zip/extra_field.rb +1 -1
  13. data/lib/zip/extra_field/generic.rb +1 -1
  14. data/lib/zip/extra_field/zip64_placeholder.rb +1 -2
  15. data/lib/zip/file.rb +12 -12
  16. data/lib/zip/filesystem.rb +17 -13
  17. data/lib/zip/inflater.rb +1 -1
  18. data/lib/zip/input_stream.rb +10 -7
  19. data/lib/zip/ioextras/abstract_input_stream.rb +1 -1
  20. data/lib/zip/ioextras/abstract_output_stream.rb +1 -1
  21. data/lib/zip/output_stream.rb +5 -5
  22. data/lib/zip/pass_thru_decompressor.rb +1 -1
  23. data/lib/zip/streamable_stream.rb +1 -1
  24. data/lib/zip/version.rb +1 -1
  25. data/samples/example_recursive.rb +14 -15
  26. data/samples/gtk_ruby_zip.rb +1 -1
  27. data/samples/qtzip.rb +1 -1
  28. data/samples/zipfind.rb +2 -2
  29. data/test/central_directory_entry_test.rb +1 -1
  30. data/test/data/gpbit3stored.zip +0 -0
  31. data/test/data/path_traversal/Makefile +10 -0
  32. data/test/data/path_traversal/jwilk/README.md +5 -0
  33. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  34. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  35. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  36. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  37. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  38. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  39. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  40. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  41. data/test/data/path_traversal/relative1.zip +0 -0
  42. data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
  43. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  44. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  45. data/test/data/rubycode.zip +0 -0
  46. data/test/errors_test.rb +1 -0
  47. data/test/file_permissions_test.rb +11 -15
  48. data/test/file_test.rb +27 -9
  49. data/test/filesystem/dir_iterator_test.rb +1 -1
  50. data/test/filesystem/directory_test.rb +29 -11
  51. data/test/filesystem/file_mutating_test.rb +3 -4
  52. data/test/filesystem/file_nonmutating_test.rb +31 -31
  53. data/test/filesystem/file_stat_test.rb +4 -4
  54. data/test/gentestfiles.rb +13 -13
  55. data/test/input_stream_test.rb +6 -6
  56. data/test/ioextras/abstract_output_stream_test.rb +2 -2
  57. data/test/path_traversal_test.rb +134 -0
  58. data/test/test_helper.rb +2 -2
  59. data/test/unicode_file_names_and_comments_test.rb +12 -0
  60. data/test/zip64_full_test.rb +2 -2
  61. metadata +95 -49
@@ -70,7 +70,7 @@ class ZipInputStreamTest < MiniTest::Test
70
70
  entry = zis.get_next_entry # longAscii.txt
71
71
  assert_equal(false, zis.eof?)
72
72
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
73
- assert zis.gets.length > 0
73
+ assert !zis.gets.empty?
74
74
  assert_equal(false, zis.eof?)
75
75
  entry = zis.get_next_entry # empty.txt
76
76
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
@@ -84,10 +84,10 @@ class ZipInputStreamTest < MiniTest::Test
84
84
  assert_equal(true, zis.eof?)
85
85
  entry = zis.get_next_entry # short.txt
86
86
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
87
- assert zis.gets.length > 0
87
+ assert !zis.gets.empty?
88
88
  entry = zis.get_next_entry # longBinary.bin
89
89
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
90
- assert zis.gets.length > 0
90
+ assert !zis.gets.empty?
91
91
  end
92
92
  end
93
93
 
@@ -97,7 +97,7 @@ class ZipInputStreamTest < MiniTest::Test
97
97
  entry = zis.get_next_entry # longAscii.txt
98
98
  assert_equal(false, zis.eof?)
99
99
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
100
- assert zis.gets.length > 0
100
+ assert !zis.gets.empty?
101
101
  assert_equal(false, zis.eof?)
102
102
  entry = zis.get_next_entry # empty.txt
103
103
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
@@ -111,10 +111,10 @@ class ZipInputStreamTest < MiniTest::Test
111
111
  assert_equal(true, zis.eof?)
112
112
  entry = zis.get_next_entry # short.txt
113
113
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
114
- assert zis.gets.length > 0
114
+ assert !zis.gets.empty?
115
115
  entry = zis.get_next_entry # longBinary.bin
116
116
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
117
- assert zis.gets.length > 0
117
+ assert !zis.gets.empty?
118
118
  end
119
119
  end
120
120
 
@@ -92,11 +92,11 @@ class AbstractOutputStreamTest < MiniTest::Test
92
92
  assert_equal("hello\nworld\n", @output_stream.buffer)
93
93
 
94
94
  @output_stream.buffer = ''
95
- @output_stream.puts(["hello\n", "world\n"])
95
+ @output_stream.puts(%W[hello\n world\n])
96
96
  assert_equal("hello\nworld\n", @output_stream.buffer)
97
97
 
98
98
  @output_stream.buffer = ''
99
- @output_stream.puts(["hello\n", "world\n"], 'bingo')
99
+ @output_stream.puts(%W[hello\n world\n], 'bingo')
100
100
  assert_equal("hello\nworld\nbingo\n", @output_stream.buffer)
101
101
 
102
102
  @output_stream.buffer = ''
@@ -0,0 +1,134 @@
1
+ class PathTraversalTest < MiniTest::Test
2
+ TEST_FILE_ROOT = File.absolute_path('test/data/path_traversal')
3
+
4
+ def setup
5
+ # With apologies to anyone using these files... but they are the files in
6
+ # the sample zips, so we don't have much choice here.
7
+ FileUtils.rm_f '/tmp/moo'
8
+ FileUtils.rm_f '/tmp/file.txt'
9
+ end
10
+
11
+ def extract_path_traversal_zip(name)
12
+ Zip::File.open(File.join(TEST_FILE_ROOT, name)) do |zip_file|
13
+ zip_file.each do |entry|
14
+ entry.extract
15
+ end
16
+ end
17
+ end
18
+
19
+ def in_tmpdir
20
+ Dir.mktmpdir do |tmp|
21
+ test_path = File.join(tmp, 'test')
22
+ Dir.mkdir test_path
23
+ Dir.chdir test_path do
24
+ yield test_path
25
+ end
26
+ end
27
+ end
28
+
29
+ def test_leading_slash
30
+ in_tmpdir do
31
+ extract_path_traversal_zip 'jwilk/absolute1.zip'
32
+ refute File.exist?('/tmp/moo')
33
+ end
34
+ end
35
+
36
+ def test_multiple_leading_slashes
37
+ in_tmpdir do
38
+ extract_path_traversal_zip 'jwilk/absolute2.zip'
39
+ refute File.exist?('/tmp/moo')
40
+ end
41
+ end
42
+
43
+ def test_leading_dot_dot
44
+ in_tmpdir do
45
+ extract_path_traversal_zip 'jwilk/relative0.zip'
46
+ refute File.exist?('../moo')
47
+ end
48
+ end
49
+
50
+ def test_non_leading_dot_dot_with_existing_folder
51
+ in_tmpdir do
52
+ extract_path_traversal_zip 'relative1.zip'
53
+ assert Dir.exist?('tmp')
54
+ refute File.exist?('../moo')
55
+ end
56
+ end
57
+
58
+ def test_non_leading_dot_dot_without_existing_folder
59
+ in_tmpdir do
60
+ extract_path_traversal_zip 'jwilk/relative2.zip'
61
+ refute File.exist?('../moo')
62
+ end
63
+ end
64
+
65
+ def test_file_symlink
66
+ in_tmpdir do
67
+ extract_path_traversal_zip 'jwilk/symlink.zip'
68
+ assert File.exist?('moo')
69
+ refute File.exist?('/tmp/moo')
70
+ end
71
+ end
72
+
73
+ def test_directory_symlink
74
+ in_tmpdir do
75
+ # Can't create tmp/moo, because the tmp symlink is skipped.
76
+ assert_raises Errno::ENOENT do
77
+ extract_path_traversal_zip 'jwilk/dirsymlink.zip'
78
+ end
79
+ refute File.exist?('/tmp/moo')
80
+ end
81
+ end
82
+
83
+ def test_two_directory_symlinks_a
84
+ in_tmpdir do
85
+ # Can't create par/moo because the symlinks are skipped.
86
+ assert_raises Errno::ENOENT do
87
+ extract_path_traversal_zip 'jwilk/dirsymlink2a.zip'
88
+ end
89
+ refute File.exist?('cur')
90
+ refute File.exist?('par')
91
+ refute File.exist?('par/moo')
92
+ end
93
+ end
94
+
95
+ def test_two_directory_symlinks_b
96
+ in_tmpdir do
97
+ # Can't create par/moo, because the symlinks are skipped.
98
+ assert_raises Errno::ENOENT do
99
+ extract_path_traversal_zip 'jwilk/dirsymlink2b.zip'
100
+ end
101
+ refute File.exist?('cur')
102
+ refute File.exist?('../moo')
103
+ end
104
+ end
105
+
106
+ def test_entry_name_with_absolute_path_does_not_extract
107
+ in_tmpdir do
108
+ extract_path_traversal_zip 'tuzovakaoff/absolutepath.zip'
109
+ refute File.exist?('/tmp/file.txt')
110
+ end
111
+ end
112
+
113
+ def test_entry_name_with_absolute_path_extract_when_given_different_path
114
+ in_tmpdir do |test_path|
115
+ zip_path = File.join(TEST_FILE_ROOT, 'tuzovakaoff/absolutepath.zip')
116
+ Zip::File.open(zip_path) do |zip_file|
117
+ zip_file.each do |entry|
118
+ entry.extract(File.join(test_path, entry.name))
119
+ end
120
+ end
121
+ refute File.exist?('/tmp/file.txt')
122
+ end
123
+ end
124
+
125
+ def test_entry_name_with_relative_symlink
126
+ in_tmpdir do
127
+ # Doesn't create the symlink path, so can't create path/file.txt.
128
+ assert_raises Errno::ENOENT do
129
+ extract_path_traversal_zip 'tuzovakaoff/symlink.zip'
130
+ end
131
+ refute File.exist?('/tmp/file.txt')
132
+ end
133
+ end
134
+ end
@@ -103,7 +103,7 @@ module AssertEntry
103
103
  File.open(filename, 'rb') do |file|
104
104
  expected = file.read
105
105
  actual = zis.read
106
- if (expected != actual)
106
+ if expected != actual
107
107
  if (expected && actual) && (expected.length > 400 || actual.length > 400)
108
108
  zipEntryFilename = entryName + '.zipEntry'
109
109
  File.open(zipEntryFilename, 'wb') { |entryfile| entryfile << actual }
@@ -118,7 +118,7 @@ module AssertEntry
118
118
  def self.assert_contents(filename, aString)
119
119
  fileContents = ''
120
120
  File.open(filename, 'rb') { |f| fileContents = f.read }
121
- if (fileContents != aString)
121
+ if fileContents != aString
122
122
  if fileContents.length > 400 || aString.length > 400
123
123
  stringFile = filename + '.other'
124
124
  File.open(stringFile, 'wb') { |f| f << aString }
@@ -33,6 +33,18 @@ class ZipUnicodeFileNamesAndComments < MiniTest::Test
33
33
  assert(filepath == entry_name)
34
34
  end
35
35
  end
36
+
37
+ ::Zip.force_entry_names_encoding = 'UTF-8'
38
+ ::Zip::File.open(FILENAME) do |zip|
39
+ file_entrys.each do |filename|
40
+ refute_nil(zip.find_entry(filename))
41
+ end
42
+ directory_entrys.each do |filepath|
43
+ refute_nil(zip.find_entry(filepath))
44
+ end
45
+ end
46
+ ::Zip.force_entry_names_encoding = nil
47
+
36
48
  ::File.unlink(FILENAME)
37
49
  end
38
50
 
@@ -36,7 +36,7 @@ if ENV['FULL_ZIP64_TEST']
36
36
  end
37
37
 
38
38
  ::Zip::File.open(test_filename) do |zf|
39
- assert_equal %w(first_file.txt huge_file last_file.txt), zf.entries.map(&:name)
39
+ assert_equal %w[first_file.txt huge_file last_file.txt], zf.entries.map(&:name)
40
40
  assert_equal first_text, zf.read('first_file.txt')
41
41
  assert_equal last_text, zf.read('last_file.txt')
42
42
  end
@@ -44,7 +44,7 @@ if ENV['FULL_ZIP64_TEST']
44
44
  # note: if this fails, be sure you have UnZip version 6.0 or newer
45
45
  # as this is the first version to support zip64 extensions
46
46
  # but some OSes (*cough* OSX) still bundle a 5.xx release
47
- assert system("unzip -t #{test_filename}"), 'third-party zip validation failed'
47
+ assert system("unzip -tqq #{test_filename}"), 'third-party zip validation failed'
48
48
  end
49
49
  end
50
50
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyzip
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Simonov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-08 00:00:00.000000000 Z
11
+ date: 2018-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.49.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.49.1
69
83
  description:
70
84
  email:
71
85
  - alex@simonov.me
@@ -134,10 +148,25 @@ files:
134
148
  - test/data/globTest/foo.txt
135
149
  - test/data/globTest/foo/bar/baz/foo.txt
136
150
  - test/data/globTest/food.txt
151
+ - test/data/gpbit3stored.zip
137
152
  - test/data/mimetype
138
153
  - test/data/notzippedruby.rb
139
154
  - test/data/ntfs.zip
140
155
  - test/data/oddExtraField.zip
156
+ - test/data/path_traversal/Makefile
157
+ - test/data/path_traversal/jwilk/README.md
158
+ - test/data/path_traversal/jwilk/absolute1.zip
159
+ - test/data/path_traversal/jwilk/absolute2.zip
160
+ - test/data/path_traversal/jwilk/dirsymlink.zip
161
+ - test/data/path_traversal/jwilk/dirsymlink2a.zip
162
+ - test/data/path_traversal/jwilk/dirsymlink2b.zip
163
+ - test/data/path_traversal/jwilk/relative0.zip
164
+ - test/data/path_traversal/jwilk/relative2.zip
165
+ - test/data/path_traversal/jwilk/symlink.zip
166
+ - test/data/path_traversal/relative1.zip
167
+ - test/data/path_traversal/tuzovakaoff/README.md
168
+ - test/data/path_traversal/tuzovakaoff/absolutepath.zip
169
+ - test/data/path_traversal/tuzovakaoff/symlink.zip
141
170
  - test/data/rubycode.zip
142
171
  - test/data/rubycode2.zip
143
172
  - test/data/test.xls
@@ -171,6 +200,7 @@ files:
171
200
  - test/output_stream_test.rb
172
201
  - test/pass_thru_compressor_test.rb
173
202
  - test/pass_thru_decompressor_test.rb
203
+ - test/path_traversal_test.rb
174
204
  - test/samples/example_recursive_test.rb
175
205
  - test/settings_test.rb
176
206
  - test/test_helper.rb
@@ -197,65 +227,81 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
227
  version: '0'
198
228
  requirements: []
199
229
  rubyforge_project:
200
- rubygems_version: 2.5.1
230
+ rubygems_version: 2.6.13
201
231
  signing_key:
202
232
  specification_version: 4
203
233
  summary: rubyzip is a ruby module for reading and writing zip files
204
234
  test_files:
205
- - test/basic_zip_file_test.rb
206
- - test/case_sensitivity_test.rb
207
- - test/central_directory_entry_test.rb
235
+ - test/file_permissions_test.rb
236
+ - test/path_traversal_test.rb
237
+ - test/ioextras/abstract_input_stream_test.rb
238
+ - test/ioextras/fake_io_test.rb
239
+ - test/ioextras/abstract_output_stream_test.rb
208
240
  - test/central_directory_test.rb
209
- - test/crypto/null_encryption_test.rb
241
+ - test/central_directory_entry_test.rb
210
242
  - test/crypto/traditional_encryption_test.rb
211
- - test/data/file1.txt
212
- - test/data/file1.txt.deflatedData
213
- - test/data/file2.txt
214
- - test/data/globTest/foo/bar/baz/foo.txt
215
- - test/data/globTest/foo.txt
216
- - test/data/globTest/food.txt
217
- - test/data/globTest.zip
218
- - test/data/mimetype
219
- - test/data/notzippedruby.rb
220
- - test/data/ntfs.zip
221
- - test/data/oddExtraField.zip
222
- - test/data/rubycode.zip
223
- - test/data/rubycode2.zip
224
- - test/data/test.xls
225
- - test/data/testDirectory.bin
226
- - test/data/WarnInvalidDate.zip
227
- - test/data/zip64-sample.zip
228
- - test/data/zipWithDirs.zip
229
- - test/data/zipWithEncryption.zip
230
- - test/deflater_test.rb
231
- - test/encryption_test.rb
232
- - test/entry_set_test.rb
233
- - test/entry_test.rb
234
- - test/errors_test.rb
235
- - test/extra_field_test.rb
243
+ - test/crypto/null_encryption_test.rb
244
+ - test/input_stream_test.rb
236
245
  - test/file_extract_directory_test.rb
246
+ - test/basic_zip_file_test.rb
247
+ - test/inflater_test.rb
237
248
  - test/file_extract_test.rb
238
- - test/file_permissions_test.rb
239
- - test/file_split_test.rb
240
- - test/file_test.rb
241
- - test/filesystem/dir_iterator_test.rb
242
- - test/filesystem/directory_test.rb
243
- - test/filesystem/file_mutating_test.rb
249
+ - test/pass_thru_compressor_test.rb
244
250
  - test/filesystem/file_nonmutating_test.rb
245
251
  - test/filesystem/file_stat_test.rb
246
- - test/gentestfiles.rb
247
- - test/inflater_test.rb
248
- - test/input_stream_test.rb
249
- - test/ioextras/abstract_input_stream_test.rb
250
- - test/ioextras/abstract_output_stream_test.rb
251
- - test/ioextras/fake_io_test.rb
252
+ - test/filesystem/file_mutating_test.rb
253
+ - test/filesystem/dir_iterator_test.rb
254
+ - test/filesystem/directory_test.rb
255
+ - test/extra_field_test.rb
256
+ - test/zip64_support_test.rb
252
257
  - test/local_entry_test.rb
253
- - test/output_stream_test.rb
254
- - test/pass_thru_compressor_test.rb
255
- - test/pass_thru_decompressor_test.rb
256
258
  - test/samples/example_recursive_test.rb
259
+ - test/entry_test.rb
260
+ - test/case_sensitivity_test.rb
261
+ - test/zip64_full_test.rb
262
+ - test/pass_thru_decompressor_test.rb
257
263
  - test/settings_test.rb
264
+ - test/gentestfiles.rb
265
+ - test/encryption_test.rb
266
+ - test/file_test.rb
267
+ - test/deflater_test.rb
258
268
  - test/test_helper.rb
269
+ - test/errors_test.rb
270
+ - test/file_split_test.rb
271
+ - test/data/file2.txt
272
+ - test/data/testDirectory.bin
273
+ - test/data/globTest/foo.txt
274
+ - test/data/globTest/foo/bar/baz/foo.txt
275
+ - test/data/globTest/food.txt
276
+ - test/data/file1.txt
277
+ - test/data/rubycode.zip
278
+ - test/data/WarnInvalidDate.zip
279
+ - test/data/zipWithDirs.zip
280
+ - test/data/rubycode2.zip
281
+ - test/data/mimetype
282
+ - test/data/zipWithEncryption.zip
283
+ - test/data/path_traversal/Makefile
284
+ - test/data/path_traversal/relative1.zip
285
+ - test/data/path_traversal/jwilk/dirsymlink.zip
286
+ - test/data/path_traversal/jwilk/symlink.zip
287
+ - test/data/path_traversal/jwilk/README.md
288
+ - test/data/path_traversal/jwilk/relative2.zip
289
+ - test/data/path_traversal/jwilk/relative0.zip
290
+ - test/data/path_traversal/jwilk/absolute2.zip
291
+ - test/data/path_traversal/jwilk/dirsymlink2b.zip
292
+ - test/data/path_traversal/jwilk/absolute1.zip
293
+ - test/data/path_traversal/jwilk/dirsymlink2a.zip
294
+ - test/data/path_traversal/tuzovakaoff/symlink.zip
295
+ - test/data/path_traversal/tuzovakaoff/README.md
296
+ - test/data/path_traversal/tuzovakaoff/absolutepath.zip
297
+ - test/data/oddExtraField.zip
298
+ - test/data/gpbit3stored.zip
299
+ - test/data/ntfs.zip
300
+ - test/data/notzippedruby.rb
301
+ - test/data/globTest.zip
302
+ - test/data/file1.txt.deflatedData
303
+ - test/data/test.xls
304
+ - test/data/zip64-sample.zip
259
305
  - test/unicode_file_names_and_comments_test.rb
260
- - test/zip64_full_test.rb
261
- - test/zip64_support_test.rb
306
+ - test/entry_set_test.rb
307
+ - test/output_stream_test.rb