rubyzip 1.2.0 → 1.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.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +95 -43
  3. data/lib/zip.rb +11 -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 +70 -54
  11. data/lib/zip/entry_set.rb +4 -4
  12. data/lib/zip/errors.rb +1 -0
  13. data/lib/zip/extra_field.rb +2 -2
  14. data/lib/zip/extra_field/generic.rb +1 -1
  15. data/lib/zip/extra_field/zip64_placeholder.rb +1 -2
  16. data/lib/zip/file.rb +62 -51
  17. data/lib/zip/filesystem.rb +17 -13
  18. data/lib/zip/inflater.rb +2 -2
  19. data/lib/zip/input_stream.rb +10 -7
  20. data/lib/zip/ioextras/abstract_input_stream.rb +1 -1
  21. data/lib/zip/ioextras/abstract_output_stream.rb +3 -3
  22. data/lib/zip/output_stream.rb +5 -5
  23. data/lib/zip/pass_thru_decompressor.rb +1 -1
  24. data/lib/zip/streamable_stream.rb +1 -1
  25. data/lib/zip/version.rb +1 -1
  26. data/samples/example_recursive.rb +15 -18
  27. data/samples/gtk_ruby_zip.rb +1 -1
  28. data/samples/qtzip.rb +1 -1
  29. data/samples/zipfind.rb +2 -2
  30. data/test/central_directory_entry_test.rb +2 -2
  31. data/test/crypto/null_encryption_test.rb +6 -2
  32. data/test/data/gpbit3stored.zip +0 -0
  33. data/test/data/path_traversal/Makefile +10 -0
  34. data/test/data/path_traversal/jwilk/README.md +5 -0
  35. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  36. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  37. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  38. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  39. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  40. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  41. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  42. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  43. data/test/data/path_traversal/relative1.zip +0 -0
  44. data/test/data/path_traversal/tilde.zip +0 -0
  45. data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
  46. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  47. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  48. data/test/data/rubycode.zip +0 -0
  49. data/test/entry_set_test.rb +13 -2
  50. data/test/entry_test.rb +3 -12
  51. data/test/errors_test.rb +1 -0
  52. data/test/file_extract_test.rb +62 -0
  53. data/test/file_permissions_test.rb +39 -43
  54. data/test/file_test.rb +115 -12
  55. data/test/filesystem/dir_iterator_test.rb +1 -1
  56. data/test/filesystem/directory_test.rb +29 -11
  57. data/test/filesystem/file_mutating_test.rb +3 -4
  58. data/test/filesystem/file_nonmutating_test.rb +34 -34
  59. data/test/filesystem/file_stat_test.rb +5 -5
  60. data/test/gentestfiles.rb +17 -13
  61. data/test/input_stream_test.rb +10 -10
  62. data/test/ioextras/abstract_input_stream_test.rb +1 -1
  63. data/test/ioextras/abstract_output_stream_test.rb +2 -2
  64. data/test/ioextras/fake_io_test.rb +1 -1
  65. data/test/local_entry_test.rb +1 -1
  66. data/test/path_traversal_test.rb +141 -0
  67. data/test/test_helper.rb +16 -3
  68. data/test/unicode_file_names_and_comments_test.rb +12 -0
  69. data/test/zip64_full_test.rb +2 -2
  70. metadata +103 -51
@@ -11,7 +11,7 @@ class ZipFsFileStatTest < MiniTest::Test
11
11
  end
12
12
 
13
13
  def test_blocks
14
- assert_equal(nil, @zip_file.file.stat('file1').blocks)
14
+ assert_nil(@zip_file.file.stat('file1').blocks)
15
15
  end
16
16
 
17
17
  def test_ino
@@ -32,10 +32,10 @@ class ZipFsFileStatTest < MiniTest::Test
32
32
  end
33
33
 
34
34
  def test_mode
35
- assert_equal(0600, @zip_file.file.stat('file1').mode & 0777)
36
- assert_equal(0600, @zip_file.file.stat('file1').mode & 0777)
37
- assert_equal(0755, @zip_file.file.stat('dir1').mode & 0777)
38
- assert_equal(0755, @zip_file.file.stat('dir1').mode & 0777)
35
+ assert_equal(0o600, @zip_file.file.stat('file1').mode & 0o777)
36
+ assert_equal(0o600, @zip_file.file.stat('file1').mode & 0o777)
37
+ assert_equal(0o755, @zip_file.file.stat('dir1').mode & 0o777)
38
+ assert_equal(0o755, @zip_file.file.stat('dir1').mode & 0o777)
39
39
  end
40
40
 
41
41
  def test_dev
@@ -9,6 +9,8 @@ class TestFiles
9
9
  RANDOM_BINARY_FILE1 = 'test/data/generated/randomBinary1.bin'
10
10
  RANDOM_BINARY_FILE2 = 'test/data/generated/randomBinary2.bin'
11
11
 
12
+ NULL_FILE = 'test/data/generated/null.zip' # Zero length, so not a zip file.
13
+
12
14
  EMPTY_TEST_DIR = 'test/data/generated/emptytestdir'
13
15
 
14
16
  ASCII_TEST_FILES = [RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3]
@@ -28,6 +30,8 @@ class TestFiles
28
30
  create_random_binary(filename, 1E4 * (index + 1))
29
31
  end
30
32
 
33
+ system("touch #{NULL_FILE}")
34
+
31
35
  ensure_dir(EMPTY_TEST_DIR)
32
36
  end
33
37
 
@@ -67,12 +71,12 @@ class TestZipFile
67
71
  end
68
72
 
69
73
  def self.create_test_zips
70
- raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP1.zip_name} test/data/file2.txt")
71
- raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP1.zip_name} -d test/data/file2.txt")
74
+ raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP1.zip_name} test/data/file2.txt")
75
+ raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP1.zip_name} -d test/data/file2.txt")
72
76
 
73
77
  File.open('test/data/generated/empty.txt', 'w') {}
74
78
  File.open('test/data/generated/empty_chmod640.txt', 'w') {}
75
- ::File.chmod(0640, 'test/data/generated/empty_chmod640.txt')
79
+ ::File.chmod(0o640, 'test/data/generated/empty_chmod640.txt')
76
80
 
77
81
  File.open('test/data/generated/short.txt', 'w') { |file| file << 'ABCDEF' }
78
82
  ziptestTxt = ''
@@ -89,34 +93,34 @@ class TestZipFile
89
93
  file << testBinaryPattern << rand << "\0" while file.tell < 6E5
90
94
  end
91
95
 
92
- raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")
96
+ raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")
93
97
 
94
98
  if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
95
- raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("echo #{TEST_ZIP2.comment}| /usr/bin/zip -z #{TEST_ZIP2.zip_name}\"")
99
+ raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("echo #{TEST_ZIP2.comment}| /usr/bin/zip -zq #{TEST_ZIP2.zip_name}\"")
96
100
  else
97
101
  # without bash system interprets everything after echo as parameters to
98
102
  # echo including | zip -z ...
99
- raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("bash -c \"echo #{TEST_ZIP2.comment} | /usr/bin/zip -z #{TEST_ZIP2.zip_name}\"")
103
+ raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("bash -c \"echo #{TEST_ZIP2.comment} | /usr/bin/zip -zq #{TEST_ZIP2.zip_name}\"")
100
104
  end
101
105
 
102
- raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")
106
+ raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")
103
107
 
104
- raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
108
+ raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
105
109
  rescue
106
110
  # If there are any Windows developers wanting to use a command line zip.exe
107
111
  # to help create the following files, there's a free one available from
108
112
  # http://stahlworks.com/dev/index.php?tool=zipunzip
109
113
  # that works with the above code
110
114
  raise $!.to_s +
111
- "\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" \
112
- "to create test data. If you don't have it you can download\n" \
113
- 'the necessary test files at http://sf.net/projects/rubyzip.'
115
+ "\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" \
116
+ "to create test data. If you don't have it you can download\n" \
117
+ 'the necessary test files at http://sf.net/projects/rubyzip.'
114
118
  end
115
119
 
116
120
  TEST_ZIP1 = TestZipFile.new('test/data/generated/empty.zip', [])
117
- TEST_ZIP2 = TestZipFile.new('test/data/generated/5entry.zip', %w(test/data/generated/longAscii.txt test/data/generated/empty.txt test/data/generated/empty_chmod640.txt test/data/generated/short.txt test/data/generated/longBinary.bin),
121
+ TEST_ZIP2 = TestZipFile.new('test/data/generated/5entry.zip', %w[test/data/generated/longAscii.txt test/data/generated/empty.txt test/data/generated/empty_chmod640.txt test/data/generated/short.txt test/data/generated/longBinary.bin],
118
122
  'my zip comment')
119
- TEST_ZIP3 = TestZipFile.new('test/data/generated/test1.zip', %w(test/data/file1.txt))
123
+ TEST_ZIP3 = TestZipFile.new('test/data/generated/test1.zip', %w[test/data/file1.txt])
120
124
  TEST_ZIP4 = TestZipFile.new('test/data/generated/zipWithDir.zip', ['test/data/file1.txt',
121
125
  TestFiles::EMPTY_TEST_DIR])
122
126
  end
@@ -70,24 +70,24 @@ 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)
77
77
  assert_equal(0, entry.size)
78
- assert_equal(nil, zis.gets)
78
+ assert_nil(zis.gets)
79
79
  assert_equal(true, zis.eof?)
80
80
  entry = zis.get_next_entry # empty_chmod640.txt
81
81
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
82
82
  assert_equal(0, entry.size)
83
- assert_equal(nil, zis.gets)
83
+ assert_nil(zis.gets)
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,24 +97,24 @@ 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)
104
104
  assert_equal(0, entry.size)
105
- assert_equal(nil, zis.gets)
105
+ assert_nil(zis.gets)
106
106
  assert_equal(true, zis.eof?)
107
107
  entry = zis.get_next_entry # empty_chmod640.txt
108
108
  assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
109
109
  assert_equal(0, entry.size)
110
- assert_equal(nil, zis.gets)
110
+ assert_nil(zis.gets)
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
 
@@ -44,7 +44,7 @@ class AbstractInputStreamTest < MiniTest::Test
44
44
  assert_equal(2, @io.lineno)
45
45
  assert_equal(TEST_LINES[2], @io.gets)
46
46
  assert_equal(3, @io.lineno)
47
- assert_equal(nil, @io.gets)
47
+ assert_nil(@io.gets)
48
48
  assert_equal(4, @io.lineno)
49
49
  end
50
50
 
@@ -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 = ''
@@ -12,7 +12,7 @@ class FakeIOTest < MiniTest::Test
12
12
  assert(obj.kind_of?(Object))
13
13
  assert(obj.kind_of?(FakeIOUsingClass))
14
14
  assert(obj.kind_of?(IO))
15
- assert(!obj.kind_of?(Fixnum))
15
+ assert(!obj.kind_of?(Integer))
16
16
  assert(!obj.kind_of?(String))
17
17
  end
18
18
  end
@@ -36,7 +36,7 @@ class ZipLocalEntryTest < MiniTest::Test
36
36
 
37
37
  def test_read_local_entry_from_non_zip_file
38
38
  ::File.open('test/data/file2.txt') do |file|
39
- assert_equal(nil, ::Zip::Entry.read_local_entry(file))
39
+ assert_nil(::Zip::Entry.read_local_entry(file))
40
40
  end
41
41
  end
42
42
 
@@ -0,0 +1,141 @@
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
+
135
+ def test_entry_name_with_tilde
136
+ in_tmpdir do
137
+ extract_path_traversal_zip 'tilde.zip'
138
+ assert File.exist?('~tilde~')
139
+ end
140
+ end
141
+ 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 }
@@ -134,7 +134,7 @@ module AssertEntry
134
134
  testZipFile.entry_names.each do |entryName|
135
135
  assert_next_entry(entryName, zis)
136
136
  end
137
- assert_equal(nil, zis.get_next_entry)
137
+ assert_nil(zis.get_next_entry)
138
138
  end
139
139
 
140
140
  def assert_test_zip_contents(testZipFile)
@@ -219,3 +219,16 @@ module ExtraAssertions
219
219
  anObject.instance_eval "undef #{method}; alias #{method} #{method}_org"
220
220
  end
221
221
  end
222
+
223
+ module ZipEntryData
224
+ TEST_ZIPFILE = 'someZipFile.zip'
225
+ TEST_COMMENT = 'a comment'
226
+ TEST_COMPRESSED_SIZE = 1234
227
+ TEST_CRC = 325_324
228
+ TEST_EXTRA = 'Some data here'
229
+ TEST_COMPRESSIONMETHOD = ::Zip::Entry::DEFLATED
230
+ TEST_NAME = 'entry name'
231
+ TEST_SIZE = 8432
232
+ TEST_ISDIRECTORY = false
233
+ TEST_TIME = Time.now
234
+ end
@@ -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.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Simonov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-19 00:00:00.000000000 Z
11
+ date: 2019-09-25 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,26 @@ 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/tilde.zip
168
+ - test/data/path_traversal/tuzovakaoff/README.md
169
+ - test/data/path_traversal/tuzovakaoff/absolutepath.zip
170
+ - test/data/path_traversal/tuzovakaoff/symlink.zip
141
171
  - test/data/rubycode.zip
142
172
  - test/data/rubycode2.zip
143
173
  - test/data/test.xls
@@ -171,6 +201,7 @@ files:
171
201
  - test/output_stream_test.rb
172
202
  - test/pass_thru_compressor_test.rb
173
203
  - test/pass_thru_decompressor_test.rb
204
+ - test/path_traversal_test.rb
174
205
  - test/samples/example_recursive_test.rb
175
206
  - test/settings_test.rb
176
207
  - test/test_helper.rb
@@ -180,7 +211,12 @@ files:
180
211
  homepage: http://github.com/rubyzip/rubyzip
181
212
  licenses:
182
213
  - BSD 2-Clause
183
- metadata: {}
214
+ metadata:
215
+ bug_tracker_uri: https://github.com/rubyzip/rubyzip/issues
216
+ changelog_uri: https://github.com/rubyzip/rubyzip/blob/v1.3.0/Changelog.md
217
+ documentation_uri: https://www.rubydoc.info/gems/rubyzip/1.3.0
218
+ source_code_uri: https://github.com/rubyzip/rubyzip/tree/v1.3.0
219
+ wiki_uri: https://github.com/rubyzip/rubyzip/wiki
184
220
  post_install_message:
185
221
  rdoc_options: []
186
222
  require_paths:
@@ -196,66 +232,82 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
232
  - !ruby/object:Gem::Version
197
233
  version: '0'
198
234
  requirements: []
199
- rubyforge_project:
200
- rubygems_version: 2.4.8
235
+ rubygems_version: 3.0.3
201
236
  signing_key:
202
237
  specification_version: 4
203
238
  summary: rubyzip is a ruby module for reading and writing zip files
204
239
  test_files:
205
- - test/basic_zip_file_test.rb
206
- - test/case_sensitivity_test.rb
207
- - test/central_directory_entry_test.rb
240
+ - test/file_permissions_test.rb
241
+ - test/path_traversal_test.rb
242
+ - test/ioextras/abstract_input_stream_test.rb
243
+ - test/ioextras/fake_io_test.rb
244
+ - test/ioextras/abstract_output_stream_test.rb
208
245
  - test/central_directory_test.rb
209
- - test/crypto/null_encryption_test.rb
246
+ - test/central_directory_entry_test.rb
210
247
  - 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
248
+ - test/crypto/null_encryption_test.rb
249
+ - test/input_stream_test.rb
236
250
  - test/file_extract_directory_test.rb
251
+ - test/basic_zip_file_test.rb
252
+ - test/inflater_test.rb
237
253
  - 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
254
+ - test/pass_thru_compressor_test.rb
244
255
  - test/filesystem/file_nonmutating_test.rb
245
256
  - 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
257
+ - test/filesystem/file_mutating_test.rb
258
+ - test/filesystem/dir_iterator_test.rb
259
+ - test/filesystem/directory_test.rb
260
+ - test/extra_field_test.rb
261
+ - test/zip64_support_test.rb
252
262
  - 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
263
  - test/samples/example_recursive_test.rb
264
+ - test/entry_test.rb
265
+ - test/case_sensitivity_test.rb
266
+ - test/zip64_full_test.rb
267
+ - test/pass_thru_decompressor_test.rb
257
268
  - test/settings_test.rb
269
+ - test/gentestfiles.rb
270
+ - test/encryption_test.rb
271
+ - test/file_test.rb
272
+ - test/deflater_test.rb
258
273
  - test/test_helper.rb
274
+ - test/errors_test.rb
275
+ - test/file_split_test.rb
276
+ - test/data/file2.txt
277
+ - test/data/testDirectory.bin
278
+ - test/data/globTest/foo.txt
279
+ - test/data/globTest/foo/bar/baz/foo.txt
280
+ - test/data/globTest/food.txt
281
+ - test/data/file1.txt
282
+ - test/data/rubycode.zip
283
+ - test/data/WarnInvalidDate.zip
284
+ - test/data/zipWithDirs.zip
285
+ - test/data/rubycode2.zip
286
+ - test/data/mimetype
287
+ - test/data/zipWithEncryption.zip
288
+ - test/data/path_traversal/tilde.zip
289
+ - test/data/path_traversal/Makefile
290
+ - test/data/path_traversal/relative1.zip
291
+ - test/data/path_traversal/jwilk/dirsymlink.zip
292
+ - test/data/path_traversal/jwilk/symlink.zip
293
+ - test/data/path_traversal/jwilk/README.md
294
+ - test/data/path_traversal/jwilk/relative2.zip
295
+ - test/data/path_traversal/jwilk/relative0.zip
296
+ - test/data/path_traversal/jwilk/absolute2.zip
297
+ - test/data/path_traversal/jwilk/dirsymlink2b.zip
298
+ - test/data/path_traversal/jwilk/absolute1.zip
299
+ - test/data/path_traversal/jwilk/dirsymlink2a.zip
300
+ - test/data/path_traversal/tuzovakaoff/symlink.zip
301
+ - test/data/path_traversal/tuzovakaoff/README.md
302
+ - test/data/path_traversal/tuzovakaoff/absolutepath.zip
303
+ - test/data/oddExtraField.zip
304
+ - test/data/gpbit3stored.zip
305
+ - test/data/ntfs.zip
306
+ - test/data/notzippedruby.rb
307
+ - test/data/globTest.zip
308
+ - test/data/file1.txt.deflatedData
309
+ - test/data/test.xls
310
+ - test/data/zip64-sample.zip
259
311
  - test/unicode_file_names_and_comments_test.rb
260
- - test/zip64_full_test.rb
261
- - test/zip64_support_test.rb
312
+ - test/entry_set_test.rb
313
+ - test/output_stream_test.rb