rubyzip 1.3.0 → 3.0.0.alpha
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 +4 -4
- data/Changelog.md +368 -0
- data/README.md +123 -46
- data/Rakefile +13 -6
- data/lib/zip/central_directory.rb +166 -116
- data/lib/zip/compressor.rb +3 -1
- data/lib/zip/constants.rb +77 -21
- data/lib/zip/crypto/decrypted_io.rb +42 -0
- data/lib/zip/crypto/encryption.rb +4 -2
- data/lib/zip/crypto/null_encryption.rb +5 -3
- data/lib/zip/crypto/traditional_encryption.rb +14 -12
- data/lib/zip/decompressor.rb +21 -2
- data/lib/zip/deflater.rb +10 -8
- data/lib/zip/dirtyable.rb +32 -0
- data/lib/zip/dos_time.rb +53 -12
- data/lib/zip/entry.rb +306 -184
- data/lib/zip/entry_set.rb +11 -7
- data/lib/zip/errors.rb +115 -15
- data/lib/zip/extra_field/generic.rb +11 -17
- data/lib/zip/extra_field/ntfs.rb +8 -2
- data/lib/zip/extra_field/old_unix.rb +6 -2
- data/lib/zip/extra_field/universal_time.rb +45 -13
- data/lib/zip/extra_field/unix.rb +7 -3
- data/lib/zip/extra_field/unknown.rb +33 -0
- data/lib/zip/extra_field/zip64.rb +16 -7
- data/lib/zip/extra_field.rb +22 -26
- data/lib/zip/file.rb +196 -240
- data/lib/zip/file_split.rb +97 -0
- data/lib/zip/filesystem/dir.rb +86 -0
- data/lib/zip/filesystem/directory_iterator.rb +48 -0
- data/lib/zip/filesystem/file.rb +262 -0
- data/lib/zip/filesystem/file_stat.rb +110 -0
- data/lib/zip/filesystem/zip_file_name_mapper.rb +81 -0
- data/lib/zip/filesystem.rb +31 -584
- data/lib/zip/inflater.rb +27 -37
- data/lib/zip/input_stream.rb +67 -42
- data/lib/zip/ioextras/abstract_input_stream.rb +32 -16
- data/lib/zip/ioextras/abstract_output_stream.rb +5 -3
- data/lib/zip/ioextras.rb +7 -7
- data/lib/zip/null_compressor.rb +3 -1
- data/lib/zip/null_decompressor.rb +4 -10
- data/lib/zip/null_input_stream.rb +3 -1
- data/lib/zip/output_stream.rb +58 -43
- data/lib/zip/pass_thru_compressor.rb +5 -3
- data/lib/zip/pass_thru_decompressor.rb +16 -23
- data/lib/zip/streamable_directory.rb +6 -4
- data/lib/zip/streamable_stream.rb +9 -10
- data/lib/zip/version.rb +3 -1
- data/lib/zip.rb +19 -4
- data/rubyzip.gemspec +38 -0
- data/samples/example.rb +9 -4
- data/samples/example_filesystem.rb +3 -2
- data/samples/example_recursive.rb +3 -1
- data/samples/gtk_ruby_zip.rb +22 -20
- data/samples/qtzip.rb +12 -11
- data/samples/write_simple.rb +3 -4
- data/samples/zipfind.rb +24 -22
- metadata +86 -179
- data/TODO +0 -15
- data/lib/zip/extra_field/zip64_placeholder.rb +0 -15
- data/test/basic_zip_file_test.rb +0 -60
- data/test/case_sensitivity_test.rb +0 -69
- data/test/central_directory_entry_test.rb +0 -69
- data/test/central_directory_test.rb +0 -100
- data/test/crypto/null_encryption_test.rb +0 -57
- data/test/crypto/traditional_encryption_test.rb +0 -80
- data/test/data/WarnInvalidDate.zip +0 -0
- data/test/data/file1.txt +0 -46
- data/test/data/file1.txt.deflatedData +0 -0
- data/test/data/file2.txt +0 -1504
- data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
- data/test/data/globTest/foo.txt +0 -0
- data/test/data/globTest/food.txt +0 -0
- data/test/data/globTest.zip +0 -0
- data/test/data/gpbit3stored.zip +0 -0
- data/test/data/mimetype +0 -1
- data/test/data/notzippedruby.rb +0 -7
- data/test/data/ntfs.zip +0 -0
- data/test/data/oddExtraField.zip +0 -0
- data/test/data/path_traversal/Makefile +0 -10
- data/test/data/path_traversal/jwilk/README.md +0 -5
- 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 +0 -3
- 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/data/rubycode2.zip +0 -0
- data/test/data/test.xls +0 -0
- data/test/data/testDirectory.bin +0 -0
- data/test/data/zip64-sample.zip +0 -0
- data/test/data/zipWithDirs.zip +0 -0
- data/test/data/zipWithEncryption.zip +0 -0
- data/test/deflater_test.rb +0 -65
- data/test/encryption_test.rb +0 -42
- data/test/entry_set_test.rb +0 -163
- data/test/entry_test.rb +0 -154
- data/test/errors_test.rb +0 -35
- data/test/extra_field_test.rb +0 -76
- data/test/file_extract_directory_test.rb +0 -54
- data/test/file_extract_test.rb +0 -145
- data/test/file_permissions_test.rb +0 -65
- data/test/file_split_test.rb +0 -57
- data/test/file_test.rb +0 -666
- data/test/filesystem/dir_iterator_test.rb +0 -58
- data/test/filesystem/directory_test.rb +0 -139
- data/test/filesystem/file_mutating_test.rb +0 -87
- data/test/filesystem/file_nonmutating_test.rb +0 -508
- data/test/filesystem/file_stat_test.rb +0 -64
- data/test/gentestfiles.rb +0 -126
- data/test/inflater_test.rb +0 -14
- data/test/input_stream_test.rb +0 -182
- data/test/ioextras/abstract_input_stream_test.rb +0 -102
- data/test/ioextras/abstract_output_stream_test.rb +0 -106
- data/test/ioextras/fake_io_test.rb +0 -18
- data/test/local_entry_test.rb +0 -154
- data/test/output_stream_test.rb +0 -128
- data/test/pass_thru_compressor_test.rb +0 -30
- data/test/pass_thru_decompressor_test.rb +0 -14
- data/test/path_traversal_test.rb +0 -141
- data/test/samples/example_recursive_test.rb +0 -37
- data/test/settings_test.rb +0 -95
- data/test/test_helper.rb +0 -234
- data/test/unicode_file_names_and_comments_test.rb +0 -62
- data/test/zip64_full_test.rb +0 -51
- data/test/zip64_support_test.rb +0 -14
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class PassThruCompressorTest < MiniTest::Test
|
4
|
-
include CrcTest
|
5
|
-
|
6
|
-
def test_size
|
7
|
-
File.open('test/data/generated/dummy.txt', 'wb') do |file|
|
8
|
-
compressor = ::Zip::PassThruCompressor.new(file)
|
9
|
-
|
10
|
-
assert_equal(0, compressor.size)
|
11
|
-
|
12
|
-
t1 = 'hello world'
|
13
|
-
t2 = ''
|
14
|
-
t3 = 'bingo'
|
15
|
-
|
16
|
-
compressor << t1
|
17
|
-
assert_equal(compressor.size, t1.size)
|
18
|
-
|
19
|
-
compressor << t2
|
20
|
-
assert_equal(compressor.size, t1.size + t2.size)
|
21
|
-
|
22
|
-
compressor << t3
|
23
|
-
assert_equal(compressor.size, t1.size + t2.size + t3.size)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_crc
|
28
|
-
run_crc_test(::Zip::PassThruCompressor)
|
29
|
-
end
|
30
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
class PassThruDecompressorTest < MiniTest::Test
|
3
|
-
include DecompressorTests
|
4
|
-
|
5
|
-
def setup
|
6
|
-
super
|
7
|
-
@file = File.new(TEST_FILE)
|
8
|
-
@decompressor = ::Zip::PassThruDecompressor.new(@file, File.size(TEST_FILE))
|
9
|
-
end
|
10
|
-
|
11
|
-
def teardown
|
12
|
-
@file.close
|
13
|
-
end
|
14
|
-
end
|
data/test/path_traversal_test.rb
DELETED
@@ -1,141 +0,0 @@
|
|
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
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'fileutils'
|
3
|
-
require_relative '../../samples/example_recursive'
|
4
|
-
|
5
|
-
class ExampleRecursiveTest < MiniTest::Test
|
6
|
-
DIRECTORY_TO_ZIP = 'test/data/globTest'
|
7
|
-
OUTPUT_DIRECTORY = 'test/data/example_recursive.zip'
|
8
|
-
TEMP_DIRECTORY = 'test/data/tmp'
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@generator = ::ZipFileGenerator.new(DIRECTORY_TO_ZIP, OUTPUT_DIRECTORY)
|
12
|
-
end
|
13
|
-
|
14
|
-
def teardown
|
15
|
-
FileUtils.rm_rf TEMP_DIRECTORY
|
16
|
-
FileUtils.rm_f OUTPUT_DIRECTORY
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_write
|
20
|
-
@generator.write
|
21
|
-
unzip
|
22
|
-
assert_equal Dir.entries(DIRECTORY_TO_ZIP).sort, Dir.entries(TEMP_DIRECTORY).sort
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def unzip(file = OUTPUT_DIRECTORY)
|
28
|
-
Zip::File.open(file) do |zip_file|
|
29
|
-
zip_file.each do |f|
|
30
|
-
file_path = File.join(TEMP_DIRECTORY, f.name)
|
31
|
-
FileUtils.mkdir_p(File.dirname(file_path))
|
32
|
-
|
33
|
-
zip_file.extract(f, file_path) unless File.exist?(file_path)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/test/settings_test.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ZipSettingsTest < MiniTest::Test
|
4
|
-
# TODO: Refactor out into common test module
|
5
|
-
include CommonZipFileFixture
|
6
|
-
|
7
|
-
TEST_OUT_NAME = 'test/data/generated/emptyOutDir'
|
8
|
-
|
9
|
-
def setup
|
10
|
-
super
|
11
|
-
|
12
|
-
Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
|
13
|
-
File.delete(TEST_OUT_NAME) if File.exist? TEST_OUT_NAME
|
14
|
-
end
|
15
|
-
|
16
|
-
def teardown
|
17
|
-
::Zip.reset!
|
18
|
-
end
|
19
|
-
|
20
|
-
def open_zip(&aProc)
|
21
|
-
assert(!aProc.nil?)
|
22
|
-
::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
|
23
|
-
end
|
24
|
-
|
25
|
-
def extract_test_dir(&aProc)
|
26
|
-
open_zip do |zf|
|
27
|
-
zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_true_on_exists_proc
|
32
|
-
Zip.on_exists_proc = true
|
33
|
-
File.open(TEST_OUT_NAME, 'w') { |f| f.puts 'something' }
|
34
|
-
extract_test_dir
|
35
|
-
assert(File.directory?(TEST_OUT_NAME))
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_false_on_exists_proc
|
39
|
-
Zip.on_exists_proc = false
|
40
|
-
File.open(TEST_OUT_NAME, 'w') { |f| f.puts 'something' }
|
41
|
-
assert_raises(Zip::DestinationFileExistsError) { extract_test_dir }
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_false_continue_on_exists_proc
|
45
|
-
Zip.continue_on_exists_proc = false
|
46
|
-
|
47
|
-
assert_raises(::Zip::EntryExistsError) do
|
48
|
-
::Zip::File.open(TEST_ZIP.zip_name) do |zf|
|
49
|
-
zf.add(zf.entries.first.name, 'test/data/file2.txt')
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_true_continue_on_exists_proc
|
55
|
-
Zip.continue_on_exists_proc = true
|
56
|
-
|
57
|
-
replacedEntry = nil
|
58
|
-
|
59
|
-
::Zip::File.open(TEST_ZIP.zip_name) do |zf|
|
60
|
-
replacedEntry = zf.entries.first.name
|
61
|
-
zf.add(replacedEntry, 'test/data/file2.txt')
|
62
|
-
end
|
63
|
-
|
64
|
-
::Zip::File.open(TEST_ZIP.zip_name) do |zf|
|
65
|
-
assert_contains(zf, replacedEntry, 'test/data/file2.txt')
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_false_warn_invalid_date
|
70
|
-
test_file = File.join(File.dirname(__FILE__), 'data', 'WarnInvalidDate.zip')
|
71
|
-
Zip.warn_invalid_date = false
|
72
|
-
|
73
|
-
assert_output('', '') do
|
74
|
-
::Zip::File.open(test_file) do |_zf|
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_true_warn_invalid_date
|
80
|
-
test_file = File.join(File.dirname(__FILE__), 'data', 'WarnInvalidDate.zip')
|
81
|
-
Zip.warn_invalid_date = true
|
82
|
-
|
83
|
-
assert_output('', /Invalid date\/time in zip entry/) do
|
84
|
-
::Zip::File.open(test_file) do |_zf|
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def assert_contains(zf, entryName, filename = entryName)
|
92
|
-
assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
|
93
|
-
assert_entry_contents(zf, entryName, filename) if File.exist?(filename)
|
94
|
-
end
|
95
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,234 +0,0 @@
|
|
1
|
-
require 'simplecov'
|
2
|
-
require 'minitest/autorun'
|
3
|
-
require 'minitest/unit'
|
4
|
-
require 'fileutils'
|
5
|
-
require 'digest/sha1'
|
6
|
-
require 'zip'
|
7
|
-
require 'gentestfiles'
|
8
|
-
|
9
|
-
TestFiles.create_test_files
|
10
|
-
TestZipFile.create_test_zips
|
11
|
-
|
12
|
-
if defined? JRUBY_VERSION
|
13
|
-
require 'jruby'
|
14
|
-
JRuby.objectspace = true
|
15
|
-
end
|
16
|
-
|
17
|
-
::MiniTest.after_run do
|
18
|
-
FileUtils.rm_rf('test/data/generated')
|
19
|
-
end
|
20
|
-
|
21
|
-
module IOizeString
|
22
|
-
attr_reader :tell
|
23
|
-
|
24
|
-
def read(count = nil)
|
25
|
-
@tell ||= 0
|
26
|
-
count = size unless count
|
27
|
-
retVal = slice(@tell, count)
|
28
|
-
@tell += count
|
29
|
-
retVal
|
30
|
-
end
|
31
|
-
|
32
|
-
def seek(index, offset)
|
33
|
-
@tell ||= 0
|
34
|
-
case offset
|
35
|
-
when IO::SEEK_END
|
36
|
-
newPos = size + index
|
37
|
-
when IO::SEEK_SET
|
38
|
-
newPos = index
|
39
|
-
when IO::SEEK_CUR
|
40
|
-
newPos = @tell + index
|
41
|
-
else
|
42
|
-
raise 'Error in test method IOizeString::seek'
|
43
|
-
end
|
44
|
-
if newPos < 0 || newPos >= size
|
45
|
-
raise Errno::EINVAL
|
46
|
-
else
|
47
|
-
@tell = newPos
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def reset
|
52
|
-
@tell = 0
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
module DecompressorTests
|
57
|
-
# expects @refText, @refLines and @decompressor
|
58
|
-
|
59
|
-
TEST_FILE = 'test/data/file1.txt'
|
60
|
-
|
61
|
-
def setup
|
62
|
-
@refText = ''
|
63
|
-
File.open(TEST_FILE) { |f| @refText = f.read }
|
64
|
-
@refLines = @refText.split($/)
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_read_everything
|
68
|
-
assert_equal(@refText, @decompressor.sysread)
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_read_in_chunks
|
72
|
-
chunkSize = 5
|
73
|
-
while (decompressedChunk = @decompressor.sysread(chunkSize))
|
74
|
-
assert_equal(@refText.slice!(0, chunkSize), decompressedChunk)
|
75
|
-
end
|
76
|
-
assert_equal(0, @refText.size)
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_mixing_reads_and_produce_input
|
80
|
-
# Just some preconditions to make sure we have enough data for this test
|
81
|
-
assert(@refText.length > 1000)
|
82
|
-
assert(@refLines.length > 40)
|
83
|
-
|
84
|
-
assert_equal(@refText[0...100], @decompressor.sysread(100))
|
85
|
-
|
86
|
-
assert(!@decompressor.input_finished?)
|
87
|
-
buf = @decompressor.produce_input
|
88
|
-
assert_equal(@refText[100...(100 + buf.length)], buf)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
module AssertEntry
|
93
|
-
def assert_next_entry(filename, zis)
|
94
|
-
assert_entry(filename, zis, zis.get_next_entry.name)
|
95
|
-
end
|
96
|
-
|
97
|
-
def assert_entry(filename, zis, entryName)
|
98
|
-
assert_equal(filename, entryName)
|
99
|
-
assert_entry_contents_for_stream(filename, zis, entryName)
|
100
|
-
end
|
101
|
-
|
102
|
-
def assert_entry_contents_for_stream(filename, zis, entryName)
|
103
|
-
File.open(filename, 'rb') do |file|
|
104
|
-
expected = file.read
|
105
|
-
actual = zis.read
|
106
|
-
if expected != actual
|
107
|
-
if (expected && actual) && (expected.length > 400 || actual.length > 400)
|
108
|
-
zipEntryFilename = entryName + '.zipEntry'
|
109
|
-
File.open(zipEntryFilename, 'wb') { |entryfile| entryfile << actual }
|
110
|
-
fail("File '#{filename}' is different from '#{zipEntryFilename}'")
|
111
|
-
else
|
112
|
-
assert_equal(expected, actual)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def self.assert_contents(filename, aString)
|
119
|
-
fileContents = ''
|
120
|
-
File.open(filename, 'rb') { |f| fileContents = f.read }
|
121
|
-
if fileContents != aString
|
122
|
-
if fileContents.length > 400 || aString.length > 400
|
123
|
-
stringFile = filename + '.other'
|
124
|
-
File.open(stringFile, 'wb') { |f| f << aString }
|
125
|
-
fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
|
126
|
-
else
|
127
|
-
assert_equal(fileContents, aString)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def assert_stream_contents(zis, testZipFile)
|
133
|
-
assert(!zis.nil?)
|
134
|
-
testZipFile.entry_names.each do |entryName|
|
135
|
-
assert_next_entry(entryName, zis)
|
136
|
-
end
|
137
|
-
assert_nil(zis.get_next_entry)
|
138
|
-
end
|
139
|
-
|
140
|
-
def assert_test_zip_contents(testZipFile)
|
141
|
-
::Zip::InputStream.open(testZipFile.zip_name) do |zis|
|
142
|
-
assert_stream_contents(zis, testZipFile)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def assert_entry_contents(zipFile, entryName, filename = entryName.to_s)
|
147
|
-
zis = zipFile.get_input_stream(entryName)
|
148
|
-
assert_entry_contents_for_stream(filename, zis, entryName)
|
149
|
-
ensure
|
150
|
-
zis.close if zis
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
module CrcTest
|
155
|
-
class TestOutputStream
|
156
|
-
include ::Zip::IOExtras::AbstractOutputStream
|
157
|
-
|
158
|
-
attr_accessor :buffer
|
159
|
-
|
160
|
-
def initialize
|
161
|
-
@buffer = ''
|
162
|
-
end
|
163
|
-
|
164
|
-
def <<(data)
|
165
|
-
@buffer << data
|
166
|
-
self
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def run_crc_test(compressorClass)
|
171
|
-
str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
|
172
|
-
fakeOut = TestOutputStream.new
|
173
|
-
|
174
|
-
deflater = compressorClass.new(fakeOut)
|
175
|
-
deflater << str
|
176
|
-
assert_equal(0x919920fc, deflater.crc)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
module Enumerable
|
181
|
-
def compare_enumerables(otherEnumerable)
|
182
|
-
otherAsArray = otherEnumerable.to_a
|
183
|
-
each_with_index do |element, index|
|
184
|
-
return false unless yield(element, otherAsArray[index])
|
185
|
-
end
|
186
|
-
size == otherAsArray.size
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
module CommonZipFileFixture
|
191
|
-
include AssertEntry
|
192
|
-
|
193
|
-
EMPTY_FILENAME = 'emptyZipFile.zip'
|
194
|
-
|
195
|
-
TEST_ZIP = TestZipFile::TEST_ZIP2.clone
|
196
|
-
TEST_ZIP.zip_name = 'test/data/generated/5entry_copy.zip'
|
197
|
-
|
198
|
-
def setup
|
199
|
-
File.delete(EMPTY_FILENAME) if File.exist?(EMPTY_FILENAME)
|
200
|
-
FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
module ExtraAssertions
|
205
|
-
def assert_forwarded(anObject, method, retVal, *expectedArgs)
|
206
|
-
callArgs = nil
|
207
|
-
setCallArgsProc = proc { |args| callArgs = args }
|
208
|
-
anObject.instance_eval <<-"end_eval"
|
209
|
-
alias #{method}_org #{method}
|
210
|
-
def #{method}(*args)
|
211
|
-
ObjectSpace._id2ref(#{setCallArgsProc.object_id}).call(args)
|
212
|
-
ObjectSpace._id2ref(#{retVal.object_id})
|
213
|
-
end
|
214
|
-
end_eval
|
215
|
-
|
216
|
-
assert_equal(retVal, yield) # Invoke test
|
217
|
-
assert_equal(expectedArgs, callArgs)
|
218
|
-
ensure
|
219
|
-
anObject.instance_eval "undef #{method}; alias #{method} #{method}_org"
|
220
|
-
end
|
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
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class ZipUnicodeFileNamesAndComments < MiniTest::Test
|
6
|
-
FILENAME = File.join(File.dirname(__FILE__), 'test1.zip')
|
7
|
-
|
8
|
-
def test_unicode_file_name
|
9
|
-
file_entrys = ['текстовыйфайл.txt', 'Résumé.txt', '슬레이어스휘.txt']
|
10
|
-
directory_entrys = ['папка/текстовыйфайл.txt', 'Résumé/Résumé.txt', '슬레이어스휘/슬레이어스휘.txt']
|
11
|
-
stream = ::Zip::OutputStream.open(FILENAME) do |io|
|
12
|
-
file_entrys.each do |filename|
|
13
|
-
io.put_next_entry(filename)
|
14
|
-
io.write(filename)
|
15
|
-
end
|
16
|
-
directory_entrys.each do |filepath|
|
17
|
-
io.put_next_entry(filepath)
|
18
|
-
io.write(filepath)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
assert(!stream.nil?)
|
22
|
-
::Zip::InputStream.open(FILENAME) do |io|
|
23
|
-
file_entrys.each do |filename|
|
24
|
-
entry = io.get_next_entry
|
25
|
-
entry_name = entry.name
|
26
|
-
entry_name = entry_name.force_encoding('UTF-8')
|
27
|
-
assert(filename == entry_name)
|
28
|
-
end
|
29
|
-
directory_entrys.each do |filepath|
|
30
|
-
entry = io.get_next_entry
|
31
|
-
entry_name = entry.name
|
32
|
-
entry_name = entry_name.force_encoding('UTF-8')
|
33
|
-
assert(filepath == entry_name)
|
34
|
-
end
|
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
|
-
|
48
|
-
::File.unlink(FILENAME)
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_unicode_comment
|
52
|
-
str = '渠道升级'
|
53
|
-
::Zip::File.open(FILENAME, Zip::File::CREATE) do |z|
|
54
|
-
z.comment = str
|
55
|
-
end
|
56
|
-
|
57
|
-
::Zip::File.open(FILENAME) do |z|
|
58
|
-
assert(z.comment.force_encoding('UTF-8') == str)
|
59
|
-
end
|
60
|
-
::File.unlink(FILENAME)
|
61
|
-
end
|
62
|
-
end
|
data/test/zip64_full_test.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
if ENV['FULL_ZIP64_TEST']
|
2
|
-
require 'minitest/autorun'
|
3
|
-
require 'minitest/unit'
|
4
|
-
require 'fileutils'
|
5
|
-
require 'zip'
|
6
|
-
|
7
|
-
# test zip64 support for real, by actually exceeding the 32-bit size/offset limits
|
8
|
-
# this test does not, of course, run with the normal unit tests! ;)
|
9
|
-
|
10
|
-
class Zip64FullTest < MiniTest::Test
|
11
|
-
def teardown
|
12
|
-
::Zip.reset!
|
13
|
-
end
|
14
|
-
|
15
|
-
def prepare_test_file(test_filename)
|
16
|
-
::File.delete(test_filename) if ::File.exist?(test_filename)
|
17
|
-
test_filename
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_large_zip_file
|
21
|
-
::Zip.write_zip64_support = true
|
22
|
-
first_text = 'starting out small'
|
23
|
-
last_text = 'this tests files starting after 4GB in the archive'
|
24
|
-
test_filename = prepare_test_file('huge.zip')
|
25
|
-
::Zip::OutputStream.open(test_filename) do |io|
|
26
|
-
io.put_next_entry('first_file.txt')
|
27
|
-
io.write(first_text)
|
28
|
-
|
29
|
-
# write just over 4GB (stored, so the zip file exceeds 4GB)
|
30
|
-
buf = 'blah' * 16_384
|
31
|
-
io.put_next_entry('huge_file', nil, nil, ::Zip::Entry::STORED)
|
32
|
-
65_537.times { io.write(buf) }
|
33
|
-
|
34
|
-
io.put_next_entry('last_file.txt')
|
35
|
-
io.write(last_text)
|
36
|
-
end
|
37
|
-
|
38
|
-
::Zip::File.open(test_filename) do |zf|
|
39
|
-
assert_equal %w[first_file.txt huge_file last_file.txt], zf.entries.map(&:name)
|
40
|
-
assert_equal first_text, zf.read('first_file.txt')
|
41
|
-
assert_equal last_text, zf.read('last_file.txt')
|
42
|
-
end
|
43
|
-
|
44
|
-
# note: if this fails, be sure you have UnZip version 6.0 or newer
|
45
|
-
# as this is the first version to support zip64 extensions
|
46
|
-
# but some OSes (*cough* OSX) still bundle a 5.xx release
|
47
|
-
assert system("unzip -tqq #{test_filename}"), 'third-party zip validation failed'
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
data/test/zip64_support_test.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class Zip64SupportTest < MiniTest::Test
|
4
|
-
TEST_FILE = File.join(File.dirname(__FILE__), 'data', 'zip64-sample.zip')
|
5
|
-
|
6
|
-
def test_open_zip64_file
|
7
|
-
zip_file = ::Zip::File.open(TEST_FILE)
|
8
|
-
assert(!zip_file.nil?)
|
9
|
-
assert(zip_file.entries.count == 2)
|
10
|
-
test_rb = zip_file.entries.find { |x| x.name == 'test.rb' }
|
11
|
-
assert(test_rb.size == 482)
|
12
|
-
assert(test_rb.compressed_size == 229)
|
13
|
-
end
|
14
|
-
end
|