blob: 80f0dc694b512f363a182ecc3a3a751d9c072765 [file] [log] [blame]
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.zip;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.fail;
import com.google.common.io.ByteStreams;
import com.google.devtools.build.zip.ZipFileEntry.Compression;
import com.google.devtools.build.zip.ZipFileEntry.Feature;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class ZipReaderTest {
@Rule public TemporaryFolder tmp = new TemporaryFolder();
@Rule public ExpectedException thrown = ExpectedException.none();
private File test;
private void assertDateWithin(Date testDate, Date start, Date end) {
if (testDate.before(start) || testDate.after(end)) {
fail();
}
}
private void assertDateAboutNow(Date testDate) {
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
cal.add(Calendar.MINUTE, -30);
Date start = cal.getTime();
cal.add(Calendar.HOUR, 1);
Date end = cal.getTime();
assertDateWithin(testDate, start, end);
}
@Before public void setup() throws IOException {
test = tmp.newFile("test.zip");
}
@Test public void testMalformed_Empty() throws IOException {
try (FileOutputStream out = new FileOutputStream(test)) {
}
thrown.expect(ZipException.class);
thrown.expectMessage("is malformed. It does not contain an end of central directory record.");
new ZipReader(test, UTF_8).close();
}
@Test public void testMalformed_ShorterThanSignature() throws IOException {
try (FileOutputStream out = new FileOutputStream(test)) {
out.write(new byte[] { 1, 2, 3 });
}
thrown.expect(ZipException.class);
thrown.expectMessage("is malformed. It does not contain an end of central directory record.");
new ZipReader(test, UTF_8).close();
}
@Test public void testMalformed_SignatureLength() throws IOException {
try (FileOutputStream out = new FileOutputStream(test)) {
out.write(new byte[] { 1, 2, 3, 4 });
}
thrown.expect(ZipException.class);
thrown.expectMessage("is malformed. It does not contain an end of central directory record.");
new ZipReader(test, UTF_8).close();
}
@Test public void testEmpty() throws IOException {
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
assertThat(reader.entries()).isEmpty();
}
}
@Test public void testFileComment() throws IOException {
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
zout.setComment("test comment");
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
assertThat(reader.entries()).isEmpty();
assertThat(reader.getComment()).isEqualTo("test comment");
}
}
@Test public void testFileCommentWithSignature() throws IOException {
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
zout.setComment("test comment\u0050\u004b\u0005\u0006abcdefghijklmnopqrstuvwxyz");
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
assertThat(reader.entries()).isEmpty();
assertThat(reader.getComment())
.isEqualTo("test comment\u0050\u004b\u0005\u0006abcdefghijklmnopqrstuvwxyz");
}
}
@Test public void testSingleEntry() throws IOException {
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
zout.putNextEntry(new ZipEntry("test"));
zout.write("foo".getBytes(UTF_8));
zout.closeEntry();
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
assertThat(reader.entries()).hasSize(1);
}
}
@Test public void testMultipleEntries() throws IOException {
String[] names = new String[] { "test", "foo", "bar", "baz" };
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
for (String name : names) {
zout.putNextEntry(new ZipEntry(name));
zout.write(name.getBytes(UTF_8));
zout.closeEntry();
}
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
assertThat(reader.entries()).hasSize(names.length);
int i = 0;
for (ZipFileEntry entry : reader.entries()) {
assertThat(entry.getName()).isEqualTo(names[i++]);
}
assertThat(i).isEqualTo(names.length);
}
}
@Test public void testZipEntryFields() throws IOException {
CRC32 crc = new CRC32();
Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
long date = 791784306000L; // 2/3/1995 04:05:06
byte[] extra = new ExtraData((short) 0xaa, new byte[] { (byte) 0xbb, (byte) 0xcd }).getBytes();
byte[] tmp = new byte[128];
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
ZipEntry foo = new ZipEntry("foo");
foo.setComment("foo comment.");
foo.setMethod(ZipEntry.DEFLATED);
foo.setTime(date);
foo.setExtra(extra);
zout.putNextEntry(foo);
zout.write("foo".getBytes(UTF_8));
zout.closeEntry();
ZipEntry bar = new ZipEntry("bar");
bar.setComment("bar comment.");
bar.setMethod(ZipEntry.STORED);
bar.setSize("bar".length());
bar.setCompressedSize("bar".length());
crc.reset();
crc.update("bar".getBytes(UTF_8));
bar.setCrc(crc.getValue());
zout.putNextEntry(bar);
zout.write("bar".getBytes(UTF_8));
zout.closeEntry();
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
ZipFileEntry fooEntry = reader.getEntry("foo");
assertThat(fooEntry.getName()).isEqualTo("foo");
assertThat(fooEntry.getComment()).isEqualTo("foo comment.");
assertThat(fooEntry.getMethod()).isEqualTo(Compression.DEFLATED);
assertThat(fooEntry.getVersion()).isEqualTo(Compression.DEFLATED.getMinVersion());
assertThat(fooEntry.getTime()).isEqualTo(date);
assertThat(fooEntry.getSize()).isEqualTo("foo".length());
deflater.reset();
deflater.setInput("foo".getBytes(UTF_8));
deflater.finish();
assertThat(fooEntry.getCompressedSize()).isEqualTo(deflater.deflate(tmp));
crc.reset();
crc.update("foo".getBytes(UTF_8));
assertThat(fooEntry.getCrc()).isEqualTo(crc.getValue());
assertThat(fooEntry.getExtra().getBytes()).isEqualTo(extra);
ZipFileEntry barEntry = reader.getEntry("bar");
assertThat(barEntry.getName()).isEqualTo("bar");
assertThat(barEntry.getComment()).isEqualTo("bar comment.");
assertThat(barEntry.getMethod()).isEqualTo(Compression.STORED);
assertThat(barEntry.getVersion()).isEqualTo(Compression.STORED.getMinVersion());
assertDateAboutNow(new Date(barEntry.getTime()));
assertThat(barEntry.getSize()).isEqualTo("bar".length());
assertThat(barEntry.getCompressedSize()).isEqualTo("bar".length());
crc.reset();
crc.update("bar".getBytes(UTF_8));
assertThat(barEntry.getCrc()).isEqualTo(crc.getValue());
assertThat(barEntry.getExtra().getBytes()).isEqualTo(new byte[] {});
}
}
@Test public void testZipEntryInvalidTime() throws IOException {
long date = 312796800000L; // 11/30/1979 00:00:00, which is also 0 in DOS format
byte[] extra = new ExtraData((short) 0xaa, new byte[] { (byte) 0xbb, (byte) 0xcd }).getBytes();
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
ZipEntry foo = new ZipEntry("foo");
foo.setComment("foo comment.");
foo.setMethod(ZipEntry.DEFLATED);
foo.setTime(date);
foo.setExtra(extra);
zout.putNextEntry(foo);
zout.write("foo".getBytes(UTF_8));
zout.closeEntry();
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
ZipFileEntry fooEntry = reader.getEntry("foo");
assertThat(fooEntry.getTime()).isEqualTo(ZipUtil.DOS_EPOCH);
}
}
@Test public void testRawFileData() throws IOException {
CRC32 crc = new CRC32();
Deflater deflator = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
ZipEntry foo = new ZipEntry("foo");
foo.setComment("foo comment.");
foo.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(foo);
zout.write("foo".getBytes(UTF_8));
zout.closeEntry();
ZipEntry bar = new ZipEntry("bar");
bar.setComment("bar comment.");
bar.setMethod(ZipEntry.STORED);
bar.setSize("bar".length());
bar.setCompressedSize("bar".length());
crc.reset();
crc.update("bar".getBytes(UTF_8));
bar.setCrc(crc.getValue());
zout.putNextEntry(bar);
zout.write("bar".getBytes(UTF_8));
zout.closeEntry();
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
ZipFileEntry fooEntry = reader.getEntry("foo");
InputStream fooIn = reader.getRawInputStream(fooEntry);
byte[] fooData = new byte[10];
fooIn.read(fooData);
byte[] expectedFooData = new byte[10];
deflator.reset();
deflator.setInput("foo".getBytes(UTF_8));
deflator.finish();
deflator.deflate(expectedFooData);
assertThat(fooData).isEqualTo(expectedFooData);
ZipFileEntry barEntry = reader.getEntry("bar");
InputStream barIn = reader.getRawInputStream(barEntry);
byte[] barData = new byte[3];
barIn.read(barData);
byte[] expectedBarData = "bar".getBytes(UTF_8);
assertThat(barData).isEqualTo(expectedBarData);
assertThat(barIn.read()).isEqualTo(-1);
assertThat(barIn.read(barData)).isEqualTo(-1);
assertThat(barIn.read(barData, 0, 3)).isEqualTo(-1);
thrown.expect(IOException.class);
thrown.expectMessage("Reset is not supported on this type of stream.");
barIn.reset();
}
}
@Test public void testFileData() throws IOException {
CRC32 crc = new CRC32();
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
ZipEntry foo = new ZipEntry("foo");
foo.setComment("foo comment.");
foo.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(foo);
zout.write("foo".getBytes(UTF_8));
zout.closeEntry();
ZipEntry bar = new ZipEntry("bar");
bar.setComment("bar comment.");
bar.setMethod(ZipEntry.STORED);
bar.setSize("bar".length());
bar.setCompressedSize("bar".length());
crc.reset();
crc.update("bar".getBytes(UTF_8));
bar.setCrc(crc.getValue());
zout.putNextEntry(bar);
zout.write("bar".getBytes(UTF_8));
zout.closeEntry();
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
ZipFileEntry fooEntry = reader.getEntry("foo");
InputStream fooIn = reader.getInputStream(fooEntry);
byte[] fooData = new byte[3];
fooIn.read(fooData);
byte[] expectedFooData = "foo".getBytes(UTF_8);
assertThat(fooData).isEqualTo(expectedFooData);
assertThat(fooIn.read()).isEqualTo(-1);
assertThat(fooIn.read(fooData)).isEqualTo(-1);
assertThat(fooIn.read(fooData, 0, 3)).isEqualTo(-1);
ZipFileEntry barEntry = reader.getEntry("bar");
InputStream barIn = reader.getInputStream(barEntry);
byte[] barData = new byte[3];
barIn.read(barData);
byte[] expectedBarData = "bar".getBytes(UTF_8);
assertThat(barData).isEqualTo(expectedBarData);
assertThat(barIn.read()).isEqualTo(-1);
assertThat(barIn.read(barData)).isEqualTo(-1);
assertThat(barIn.read(barData, 0, 3)).isEqualTo(-1);
thrown.expect(IOException.class);
thrown.expectMessage("Reset is not supported on this type of stream.");
barIn.reset();
}
}
@Test public void testSimultaneousReads() throws IOException {
byte[] expectedFooData = "This is file foo. It contains a foo.".getBytes(UTF_8);
byte[] expectedBarData = "This is a different file bar. It contains only a bar."
.getBytes(UTF_8);
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
ZipEntry foo = new ZipEntry("foo");
foo.setComment("foo comment.");
foo.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(foo);
zout.write(expectedFooData);
zout.closeEntry();
ZipEntry bar = new ZipEntry("bar");
bar.setComment("bar comment.");
bar.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(bar);
zout.write(expectedBarData);
zout.closeEntry();
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
ZipFileEntry fooEntry = reader.getEntry("foo");
ZipFileEntry barEntry = reader.getEntry("bar");
InputStream fooIn = reader.getInputStream(fooEntry);
InputStream barIn = reader.getInputStream(barEntry);
byte[] fooData = new byte[expectedFooData.length];
byte[] barData = new byte[expectedBarData.length];
fooIn.read(fooData, 0, 10);
barIn.read(barData, 0, 10);
fooIn.read(fooData, 10, 10);
barIn.read(barData, 10, 10);
fooIn.read(fooData, 20, fooData.length - 20);
barIn.read(barData, 20, barData.length - 20);
assertThat(fooData).isEqualTo(expectedFooData);
assertThat(barData).isEqualTo(expectedBarData);
}
}
@Test public void testSlowRead() throws IOException {
byte[] expectedFooData = "This is file foo. It contains a foo.".getBytes(UTF_8);
byte[] expectedBarData = "This is a different file bar. It contains only a bar."
.getBytes(UTF_8);
try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(test))) {
ZipEntry foo = new ZipEntry("foo");
foo.setComment("foo comment.");
foo.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(foo);
zout.write(expectedFooData);
zout.closeEntry();
ZipEntry bar = new ZipEntry("bar");
bar.setComment("bar comment.");
bar.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(bar);
zout.write(expectedBarData);
zout.closeEntry();
}
try (ZipReader reader = new SlowZipReader(test, UTF_8)) {
ZipFileEntry fooEntry = reader.getEntry("foo");
ZipFileEntry barEntry = reader.getEntry("bar");
InputStream fooIn = reader.getInputStream(fooEntry);
InputStream barIn = reader.getInputStream(barEntry);
byte[] fooData = new byte[expectedFooData.length];
byte[] barData = new byte[expectedBarData.length];
ZipUtil.readFully(fooIn, fooData, 0, 10);
ZipUtil.readFully(barIn, barData, 0, 10);
ZipUtil.readFully(fooIn, fooData, 10, 10);
ZipUtil.readFully(barIn, barData, 10, 10);
ZipUtil.readFully(fooIn, fooData, 20, fooData.length - 20);
ZipUtil.readFully(barIn, barData, 20, barData.length - 20);
assertThat(fooData).isEqualTo(expectedFooData);
assertThat(barData).isEqualTo(expectedBarData);
}
}
@Test public void testZip64() throws IOException {
// Generated with: 'echo "foo" > entry; zip -fz -q out.zip entry'
byte[] data = new byte[] {
0x50, 0x4b, 0x03, 0x04, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, (byte) 0x86, (byte) 0xa6,
0x46, (byte) 0xa8, 0x65, 0x32, 0x7e, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x05, 0x00, 0x30, 0x00, 0x65, 0x6e,
0x74, 0x72, 0x79, 0x55, 0x54, 0x09, 0x00, 0x03, (byte) 0xb2, 0x7e, 0x4a, 0x55, (byte) 0xb2,
0x7e, 0x4a, 0x55, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x46, 0x3a, 0x04, 0x00, 0x04,
(byte) 0x88, 0x13, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50,
0x4b, 0x01, 0x02, 0x1e, 0x03, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, (byte) 0x86,
(byte) 0xa6, 0x46, (byte) 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, (byte) 0xff,
(byte) 0xff, (byte) 0xff, (byte) 0xff, 0x05, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, (byte) 0xa0, (byte) 0x81, 0x00, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x74, 0x72,
0x79, 0x55, 0x54, 0x05, 0x00, 0x03, (byte) 0xb2, 0x7e, 0x4a, 0x55, 0x75, 0x78, 0x0b, 0x00,
0x01, 0x04, 0x46, 0x3a, 0x04, 0x00, 0x04, (byte) 0x88, 0x13, 0x00, 0x00, 0x01, 0x00, 0x08,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x06, 0x2c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, (byte) 0xae,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x57, 0x00, 0x00, 0x00, (byte) 0xff,
(byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x00
};
try (FileOutputStream out = new FileOutputStream(test)) {
out.write(data);
}
String foo = "foo\n";
byte[] expectedFooData = foo.getBytes(UTF_8);
ExtraDataList extras = new ExtraDataList();
extras.add(new ExtraData((short) 0x0001, ZipUtil.longToLittleEndian(expectedFooData.length)));
byte[] extra = extras.getBytes();
CRC32 crc = new CRC32();
crc.reset();
crc.update(expectedFooData);
try (ZipReader reader = new ZipReader(test, UTF_8)) {
ZipFileEntry fooEntry = reader.getEntry("entry");
InputStream fooIn = reader.getInputStream(fooEntry);
byte[] fooData = new byte[expectedFooData.length];
fooIn.read(fooData);
assertThat(fooData).isEqualTo(expectedFooData);
assertThat(fooEntry.getName()).isEqualTo("entry");
assertThat(fooEntry.getComment()).isEmpty();
assertThat(fooEntry.getMethod()).isEqualTo(Compression.STORED);
assertThat(fooEntry.getVersionNeeded()).isEqualTo(Feature.ZIP64_SIZE.getMinVersion());
assertThat(fooEntry.getSize()).isEqualTo(expectedFooData.length);
assertThat(fooEntry.getCompressedSize()).isEqualTo(expectedFooData.length);
assertThat(fooEntry.getCrc()).isEqualTo(crc.getValue());
assertThat(fooEntry.getExtra().get((short) 0x0001).getBytes()).isEqualTo(extra);
}
}
@Test public void testZip64_Potential() throws IOException {
try (ZipWriter writer = new ZipWriter(new FileOutputStream(test), UTF_8, true)) {
ZipFileEntry template = new ZipFileEntry("template");
template.setSize(0);
template.setCompressedSize(0);
template.setCrc(0);
template.setTime(ZipUtil.DOS_EPOCH);
for (int i = 0; i < 0xffff; i++) {
ZipFileEntry entry = new ZipFileEntry(template);
entry.setName("entry" + i);
writer.putNextEntry(entry);
}
}
try (ZipReader reader = new ZipReader(test, UTF_8, true)) {
Collection<ZipFileEntry> entries = reader.entries();
assertThat(entries).hasSize(0xffff);
}
}
@Test public void testZip64_NumFiles() throws IOException {
try (ZipWriter writer = new ZipWriter(new FileOutputStream(test), UTF_8, true)) {
ZipFileEntry template = new ZipFileEntry("template");
template.setSize(0);
template.setCompressedSize(0);
template.setCrc(0);
template.setTime(ZipUtil.DOS_EPOCH);
for (int i = 0; i < 0x100ff; i++) {
ZipFileEntry entry = new ZipFileEntry(template);
entry.setName("entry" + i);
writer.putNextEntry(entry);
}
}
try (ZipReader reader = new ZipReader(test, UTF_8, true)) {
Collection<ZipFileEntry> entries = reader.entries();
assertThat(entries).hasSize(0x100ff);
}
}
@Test public void testZip64_Max32BitSizeFile() throws IOException {
File bigFile = tmp.newFile("big");
try (RandomAccessFile bigOut = new RandomAccessFile(bigFile, "rw")) {
bigOut.setLength(0xffffffffL);
}
try (ZipWriter writer = new ZipWriter(new FileOutputStream(test), UTF_8, true)) {
ZipFileEntry bigEntry = new ZipFileEntry(bigFile.getName());
bigEntry.setSize(0xffffffffL);
bigEntry.setCompressedSize(0xffffffffL);
bigEntry.setCrc(0);
bigEntry.setTime(ZipUtil.DOS_EPOCH);
writer.putNextEntry(bigEntry);
ByteStreams.copy(new BufferedInputStream(new FileInputStream(bigFile)), writer);
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
Collection<ZipFileEntry> entries = reader.entries();
assertThat(entries).hasSize(1);
ZipFileEntry bigEntry = reader.getEntry(bigFile.getName());
assertThat(bigEntry.getSize()).isEqualTo(0xffffffffL);
}
}
@Test public void testZip64_Zip64SizeFile() throws IOException {
File biggerFile = tmp.newFile("big");
try (RandomAccessFile biggerOut = new RandomAccessFile(biggerFile, "rw")) {
biggerOut.setLength(0x1000000ffL);
}
try (ZipWriter writer = new ZipWriter(new FileOutputStream(test), UTF_8, true)) {
ZipFileEntry bigEntry = new ZipFileEntry(biggerFile.getName());
bigEntry.setSize(0x1000000ffL);
bigEntry.setCompressedSize(0x1000000ffL);
bigEntry.setCrc(0);
bigEntry.setTime(ZipUtil.DOS_EPOCH);
writer.putNextEntry(bigEntry);
ByteStreams.copy(new BufferedInputStream(new FileInputStream(biggerFile)), writer);
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
Collection<ZipFileEntry> entries = reader.entries();
assertThat(entries).hasSize(1);
ZipFileEntry bigEntry = reader.getEntry(biggerFile.getName());
assertThat(bigEntry.getSize()).isEqualTo(0x1000000ffL);
}
}
@Test public void testZip64_FileCount_Zip64Range_ForceZip32() throws IOException {
try (ZipWriter writer = new ZipWriter(new FileOutputStream(test), UTF_8, false)) {
ZipFileEntry template = new ZipFileEntry("template");
template.setSize(0);
template.setCompressedSize(0);
template.setCrc(0);
template.setTime(ZipUtil.DOS_EPOCH);
for (int i = 0; i < 0x100ff; i++) {
ZipFileEntry entry = new ZipFileEntry(template);
entry.setName("entry" + i);
writer.putNextEntry(entry);
}
}
try (ZipReader reader = new ZipReader(test, UTF_8)) {
assertThat(reader.size()).isEqualTo(0x100ff);
}
try (ZipReader reader = new ZipReader(test, UTF_8, true)) {
assertThat(reader.size()).isEqualTo(0x00ff);
}
}
}