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.
- checksums.yaml +5 -5
- data/README.md +95 -43
- data/lib/zip.rb +11 -1
- data/lib/zip/central_directory.rb +3 -3
- data/lib/zip/compressor.rb +1 -2
- data/lib/zip/constants.rb +3 -3
- data/lib/zip/crypto/null_encryption.rb +2 -4
- data/lib/zip/decompressor.rb +1 -1
- data/lib/zip/dos_time.rb +1 -1
- data/lib/zip/entry.rb +70 -54
- data/lib/zip/entry_set.rb +4 -4
- data/lib/zip/errors.rb +1 -0
- data/lib/zip/extra_field.rb +2 -2
- data/lib/zip/extra_field/generic.rb +1 -1
- data/lib/zip/extra_field/zip64_placeholder.rb +1 -2
- data/lib/zip/file.rb +62 -51
- data/lib/zip/filesystem.rb +17 -13
- data/lib/zip/inflater.rb +2 -2
- data/lib/zip/input_stream.rb +10 -7
- data/lib/zip/ioextras/abstract_input_stream.rb +1 -1
- data/lib/zip/ioextras/abstract_output_stream.rb +3 -3
- data/lib/zip/output_stream.rb +5 -5
- data/lib/zip/pass_thru_decompressor.rb +1 -1
- data/lib/zip/streamable_stream.rb +1 -1
- data/lib/zip/version.rb +1 -1
- data/samples/example_recursive.rb +15 -18
- data/samples/gtk_ruby_zip.rb +1 -1
- data/samples/qtzip.rb +1 -1
- data/samples/zipfind.rb +2 -2
- data/test/central_directory_entry_test.rb +2 -2
- data/test/crypto/null_encryption_test.rb +6 -2
- data/test/data/gpbit3stored.zip +0 -0
- data/test/data/path_traversal/Makefile +10 -0
- data/test/data/path_traversal/jwilk/README.md +5 -0
- data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
- data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
- data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
- data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
- data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
- data/test/data/path_traversal/jwilk/relative0.zip +0 -0
- data/test/data/path_traversal/jwilk/relative2.zip +0 -0
- data/test/data/path_traversal/jwilk/symlink.zip +0 -0
- data/test/data/path_traversal/relative1.zip +0 -0
- data/test/data/path_traversal/tilde.zip +0 -0
- data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
- data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
- data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
- data/test/data/rubycode.zip +0 -0
- data/test/entry_set_test.rb +13 -2
- data/test/entry_test.rb +3 -12
- data/test/errors_test.rb +1 -0
- data/test/file_extract_test.rb +62 -0
- data/test/file_permissions_test.rb +39 -43
- data/test/file_test.rb +115 -12
- data/test/filesystem/dir_iterator_test.rb +1 -1
- data/test/filesystem/directory_test.rb +29 -11
- data/test/filesystem/file_mutating_test.rb +3 -4
- data/test/filesystem/file_nonmutating_test.rb +34 -34
- data/test/filesystem/file_stat_test.rb +5 -5
- data/test/gentestfiles.rb +17 -13
- data/test/input_stream_test.rb +10 -10
- data/test/ioextras/abstract_input_stream_test.rb +1 -1
- data/test/ioextras/abstract_output_stream_test.rb +2 -2
- data/test/ioextras/fake_io_test.rb +1 -1
- data/test/local_entry_test.rb +1 -1
- data/test/path_traversal_test.rb +141 -0
- data/test/test_helper.rb +16 -3
- data/test/unicode_file_names_and_comments_test.rb +12 -0
- data/test/zip64_full_test.rb +2 -2
- metadata +103 -51
@@ -11,7 +11,7 @@ class ZipFsFileStatTest < MiniTest::Test
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_blocks
|
14
|
-
|
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(
|
36
|
-
assert_equal(
|
37
|
-
assert_equal(
|
38
|
-
assert_equal(
|
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
|
data/test/gentestfiles.rb
CHANGED
@@ -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(
|
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 -
|
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 -
|
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
|
-
|
112
|
-
|
113
|
-
|
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
|
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
|
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
|
data/test/input_stream_test.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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([
|
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([
|
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 = ''
|
data/test/local_entry_test.rb
CHANGED
@@ -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
|
-
|
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
|
data/test/test_helper.rb
CHANGED
@@ -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
|
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
|
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
|
-
|
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
|
|
data/test/zip64_full_test.rb
CHANGED
@@ -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
|
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 -
|
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.
|
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:
|
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
|
-
|
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/
|
206
|
-
- test/
|
207
|
-
- test/
|
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/
|
246
|
+
- test/central_directory_entry_test.rb
|
210
247
|
- test/crypto/traditional_encryption_test.rb
|
211
|
-
- test/
|
212
|
-
- test/
|
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/
|
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/
|
247
|
-
- test/
|
248
|
-
- test/
|
249
|
-
- test/
|
250
|
-
- test/
|
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/
|
261
|
-
- test/
|
312
|
+
- test/entry_set_test.rb
|
313
|
+
- test/output_stream_test.rb
|