1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
require 'test_helper'
class ZipLocalEntryTest < MiniTest::Test
CEH_FILE = 'test/data/generated/centralEntryHeader.bin'
LEH_FILE = 'test/data/generated/localEntryHeader.bin'
def teardown
::Zip.write_zip64_support = false
end
def test_read_local_entry_header_of_first_test_zip_entry
::File.open(TestZipFile::TEST_ZIP3.zip_name, 'rb') do |file|
entry = ::Zip::Entry.read_local_entry(file)
assert_equal('', entry.comment)
# Differs from windows and unix because of CR LF
# assert_equal(480, entry.compressed_size)
# assert_equal(0x2a27930f, entry.crc)
# extra field is 21 bytes long
# probably contains some unix attrutes or something
# disabled: assert_equal(nil, entry.extra)
assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
assert_equal(TestZipFile::TEST_ZIP3.entry_names[0], entry.name)
assert_equal(::File.size(TestZipFile::TEST_ZIP3.entry_names[0]), entry.size)
assert(!entry.directory?)
end
end
def test_read_date_time
::File.open('test/data/rubycode.zip', 'rb') do |file|
entry = ::Zip::Entry.read_local_entry(file)
assert_equal('zippedruby1.rb', entry.name)
assert_equal(::Zip::DOSTime.at(1_019_261_638), entry.time)
end
end
def test_read_local_entry_from_non_zip_file
::File.open('test/data/file2.txt') do |file|
assert_equal(nil, ::Zip::Entry.read_local_entry(file))
end
end
def test_read_local_entry_from_truncated_zip_file
zipFragment = ''
::File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
zipFragment.extend(IOizeString).reset
entry = ::Zip::Entry.new
entry.read_local_entry(zipFragment)
fail 'ZipError expected'
rescue ::Zip::Error
end
def test_write_entry
entry = ::Zip::Entry.new('file.zip', 'entryName', 'my little comment',
'thisIsSomeExtraInformation', 100, 987_654,
::Zip::Entry::DEFLATED, 400)
write_to_file(LEH_FILE, CEH_FILE, entry)
entryReadLocal, entryReadCentral = read_from_file(LEH_FILE, CEH_FILE)
assert(entryReadCentral.extra['Zip64Placeholder'].nil?, 'zip64 placeholder should not be used in central directory')
compare_local_entry_headers(entry, entryReadLocal)
compare_c_dir_entry_headers(entry, entryReadCentral)
end
def test_write_entry_with_zip64
::Zip.write_zip64_support = true
entry = ::Zip::Entry.new('file.zip', 'entryName', 'my little comment',
'thisIsSomeExtraInformation', 100, 987_654,
::Zip::Entry::DEFLATED, 400)
write_to_file(LEH_FILE, CEH_FILE, entry)
entryReadLocal, entryReadCentral = read_from_file(LEH_FILE, CEH_FILE)
assert(entryReadLocal.extra['Zip64Placeholder'], 'zip64 placeholder should be used in local file header')
entryReadLocal.extra.delete('Zip64Placeholder') # it was removed when writing the c_dir_entry, so remove from compare
assert(entryReadCentral.extra['Zip64Placeholder'].nil?, 'zip64 placeholder should not be used in central directory')
compare_local_entry_headers(entry, entryReadLocal)
compare_c_dir_entry_headers(entry, entryReadCentral)
end
def test_write_64entry
::Zip.write_zip64_support = true
entry = ::Zip::Entry.new('bigfile.zip', 'entryName', 'my little equine',
'malformed extra field because why not',
0x7766554433221100, 0xDEADBEEF, ::Zip::Entry::DEFLATED,
0x9988776655443322)
write_to_file(LEH_FILE, CEH_FILE, entry)
entryReadLocal, entryReadCentral = read_from_file(LEH_FILE, CEH_FILE)
compare_local_entry_headers(entry, entryReadLocal)
compare_c_dir_entry_headers(entry, entryReadCentral)
end
def test_rewrite_local_header64
::Zip.write_zip64_support = true
buf1 = StringIO.new
entry = ::Zip::Entry.new('file.zip', 'entryName')
entry.write_local_entry(buf1)
assert(entry.extra['Zip64'].nil?, 'zip64 extra is unnecessarily present')
buf2 = StringIO.new
entry.size = 0x123456789ABCDEF0
entry.compressed_size = 0x0123456789ABCDEF
entry.write_local_entry(buf2, true)
refute_nil(entry.extra['Zip64'])
refute_equal(buf1.size, 0)
assert_equal(buf1.size, buf2.size) # it can't grow, or we'd clobber file data
end
def test_read_local_offset
entry = ::Zip::Entry.new('file.zip', 'entryName')
entry.local_header_offset = 12_345
::File.open(CEH_FILE, 'wb') { |f| entry.write_c_dir_entry(f) }
read_entry = nil
::File.open(CEH_FILE, 'rb') { |f| read_entry = ::Zip::Entry.read_c_dir_entry(f) }
compare_c_dir_entry_headers(entry, read_entry)
end
def test_read64_local_offset
::Zip.write_zip64_support = true
entry = ::Zip::Entry.new('file.zip', 'entryName')
entry.local_header_offset = 0x0123456789ABCDEF
::File.open(CEH_FILE, 'wb') { |f| entry.write_c_dir_entry(f) }
read_entry = nil
::File.open(CEH_FILE, 'rb') { |f| read_entry = ::Zip::Entry.read_c_dir_entry(f) }
compare_c_dir_entry_headers(entry, read_entry)
end
private
def compare_local_entry_headers(entry1, entry2)
assert_equal(entry1.compressed_size, entry2.compressed_size)
assert_equal(entry1.crc, entry2.crc)
assert_equal(entry1.extra, entry2.extra)
assert_equal(entry1.compression_method, entry2.compression_method)
assert_equal(entry1.name, entry2.name)
assert_equal(entry1.size, entry2.size)
assert_equal(entry1.local_header_offset, entry2.local_header_offset)
end
def compare_c_dir_entry_headers(entry1, entry2)
compare_local_entry_headers(entry1, entry2)
assert_equal(entry1.comment, entry2.comment)
end
def write_to_file(localFileName, centralFileName, entry)
::File.open(localFileName, 'wb') { |f| entry.write_local_entry(f) }
::File.open(centralFileName, 'wb') { |f| entry.write_c_dir_entry(f) }
end
def read_from_file(localFileName, centralFileName)
localEntry = nil
cdirEntry = nil
::File.open(localFileName, 'rb') { |f| localEntry = ::Zip::Entry.read_local_entry(f) }
::File.open(centralFileName, 'rb') { |f| cdirEntry = ::Zip::Entry.read_c_dir_entry(f) }
[localEntry, cdirEntry]
end
end
|