rubyzip 1.0.0 → 1.2.0
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.
- checksums.yaml +6 -14
- data/README.md +173 -42
- data/Rakefile +10 -5
- data/TODO +0 -1
- data/lib/zip/central_directory.rb +55 -24
- data/lib/zip/compressor.rb +0 -0
- data/lib/zip/constants.rb +4 -2
- data/lib/zip/crypto/encryption.rb +11 -0
- data/lib/zip/crypto/null_encryption.rb +45 -0
- data/lib/zip/crypto/traditional_encryption.rb +99 -0
- data/lib/zip/decompressor.rb +2 -2
- data/lib/zip/deflater.rb +11 -6
- data/lib/zip/dos_time.rb +4 -5
- data/lib/zip/entry.rb +159 -97
- data/lib/zip/entry_set.rb +18 -18
- data/lib/zip/errors.rb +15 -6
- data/lib/zip/extra_field/generic.rb +8 -8
- data/lib/zip/extra_field/ntfs.rb +90 -0
- data/lib/zip/extra_field/old_unix.rb +44 -0
- data/lib/zip/extra_field/universal_time.rb +14 -14
- data/lib/zip/extra_field/unix.rb +8 -9
- data/lib/zip/extra_field/zip64.rb +44 -6
- data/lib/zip/extra_field/zip64_placeholder.rb +16 -0
- data/lib/zip/extra_field.rb +20 -8
- data/lib/zip/file.rb +126 -114
- data/lib/zip/filesystem.rb +140 -139
- data/lib/zip/inflater.rb +10 -9
- data/lib/zip/input_stream.rb +105 -80
- data/lib/zip/ioextras/abstract_input_stream.rb +15 -12
- data/lib/zip/ioextras/abstract_output_stream.rb +0 -2
- data/lib/zip/ioextras.rb +1 -3
- data/lib/zip/null_compressor.rb +2 -2
- data/lib/zip/null_decompressor.rb +4 -4
- data/lib/zip/null_input_stream.rb +2 -1
- data/lib/zip/output_stream.rb +57 -43
- data/lib/zip/pass_thru_compressor.rb +4 -4
- data/lib/zip/pass_thru_decompressor.rb +4 -5
- data/lib/zip/streamable_directory.rb +2 -2
- data/lib/zip/streamable_stream.rb +22 -13
- data/lib/zip/version.rb +1 -1
- data/lib/zip.rb +11 -2
- data/samples/example.rb +30 -40
- data/samples/example_filesystem.rb +16 -18
- data/samples/example_recursive.rb +35 -27
- data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +25 -27
- data/samples/qtzip.rb +19 -28
- data/samples/write_simple.rb +12 -13
- data/samples/zipfind.rb +29 -37
- data/test/basic_zip_file_test.rb +60 -0
- data/test/case_sensitivity_test.rb +69 -0
- data/test/central_directory_entry_test.rb +69 -0
- data/test/central_directory_test.rb +100 -0
- data/test/crypto/null_encryption_test.rb +53 -0
- data/test/crypto/traditional_encryption_test.rb +80 -0
- data/test/data/WarnInvalidDate.zip +0 -0
- data/test/data/file1.txt +46 -0
- data/test/data/file1.txt.deflatedData +0 -0
- data/test/data/file2.txt +1504 -0
- 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/mimetype +1 -0
- data/test/data/notzippedruby.rb +7 -0
- data/test/data/ntfs.zip +0 -0
- data/test/data/oddExtraField.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 +65 -0
- data/test/encryption_test.rb +42 -0
- data/test/entry_set_test.rb +152 -0
- data/test/entry_test.rb +163 -0
- data/test/errors_test.rb +34 -0
- data/test/extra_field_test.rb +76 -0
- data/test/file_extract_directory_test.rb +54 -0
- data/test/file_extract_test.rb +83 -0
- data/test/file_permissions_test.rb +69 -0
- data/test/file_split_test.rb +57 -0
- data/test/file_test.rb +563 -0
- data/test/filesystem/dir_iterator_test.rb +58 -0
- data/test/filesystem/directory_test.rb +121 -0
- data/test/filesystem/file_mutating_test.rb +88 -0
- data/test/filesystem/file_nonmutating_test.rb +508 -0
- data/test/filesystem/file_stat_test.rb +64 -0
- data/test/gentestfiles.rb +122 -0
- data/test/inflater_test.rb +14 -0
- data/test/input_stream_test.rb +182 -0
- data/test/ioextras/abstract_input_stream_test.rb +102 -0
- data/test/ioextras/abstract_output_stream_test.rb +106 -0
- data/test/ioextras/fake_io_test.rb +18 -0
- data/test/local_entry_test.rb +154 -0
- data/test/output_stream_test.rb +128 -0
- data/test/pass_thru_compressor_test.rb +30 -0
- data/test/pass_thru_decompressor_test.rb +14 -0
- data/test/samples/example_recursive_test.rb +37 -0
- data/test/settings_test.rb +95 -0
- data/test/test_helper.rb +221 -0
- data/test/unicode_file_names_and_comments_test.rb +50 -0
- data/test/zip64_full_test.rb +51 -0
- data/test/zip64_support_test.rb +14 -0
- metadata +198 -22
- data/NEWS +0 -182
@@ -0,0 +1,30 @@
|
|
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
|
@@ -0,0 +1,14 @@
|
|
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
|
@@ -0,0 +1,37 @@
|
|
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
|
@@ -0,0 +1,95 @@
|
|
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
ADDED
@@ -0,0 +1,221 @@
|
|
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_equal(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
|
@@ -0,0 +1,50 @@
|
|
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
|
+
::File.unlink(FILENAME)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_unicode_comment
|
40
|
+
str = '渠道升级'
|
41
|
+
::Zip::File.open(FILENAME, Zip::File::CREATE) do |z|
|
42
|
+
z.comment = str
|
43
|
+
end
|
44
|
+
|
45
|
+
::Zip::File.open(FILENAME) do |z|
|
46
|
+
assert(z.comment.force_encoding('UTF-8') == str)
|
47
|
+
end
|
48
|
+
::File.unlink(FILENAME)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,51 @@
|
|
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 -t #{test_filename}"), 'third-party zip validation failed'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,14 @@
|
|
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
|