summaryrefslogtreecommitdiffstats
path: root/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/test/java/libcore/java/util/zip/ZipFileTest.java')
-rw-r--r--luni/src/test/java/libcore/java/util/zip/ZipFileTest.java339
1 files changed, 285 insertions, 54 deletions
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index afceaba..49dc050 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Random;
+import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
@@ -35,7 +36,6 @@ import junit.framework.TestCase;
import libcore.io.IoUtils;
public final class ZipFileTest extends TestCase {
-
/**
* Exercise Inflater's ability to refill the zlib's input buffer. As of this
* writing, this buffer's max size is 64KiB compressed bytes. We'll write a
@@ -45,7 +45,7 @@ public final class ZipFileTest extends TestCase {
public void testInflatingFilesRequiringZipRefill() throws IOException {
int originalSize = 1024 * 1024;
byte[] readBuffer = new byte[8192];
- ZipFile zipFile = new ZipFile(createZipFile(originalSize));
+ ZipFile zipFile = new ZipFile(createZipFile(1, originalSize));
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
ZipEntry zipEntry = e.nextElement();
assertTrue("This test needs >64 KiB of compressed data to exercise Inflater",
@@ -121,72 +121,303 @@ public final class ZipFileTest extends TestCase {
public void testInflatingStreamsRequiringZipRefill() throws IOException {
int originalSize = 1024 * 1024;
byte[] readBuffer = new byte[8192];
- ZipInputStream in = new ZipInputStream(new FileInputStream(createZipFile(originalSize)));
+ ZipInputStream in = new ZipInputStream(new FileInputStream(createZipFile(1, originalSize)));
while (in.getNextEntry() != null) {
while (in.read(readBuffer, 0, readBuffer.length) != -1) {}
}
in.close();
}
+ public void testZipFileWithLotsOfEntries() throws IOException {
+ int expectedEntryCount = 64*1024 - 1;
+ File f = createZipFile(expectedEntryCount, 0);
+ ZipFile zipFile = new ZipFile(f);
+ int entryCount = 0;
+ for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
+ ZipEntry zipEntry = e.nextElement();
+ ++entryCount;
+ }
+ assertEquals(expectedEntryCount, entryCount);
+ zipFile.close();
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=36187
+ public void testZipFileLargerThan2GiB() throws IOException {
+ if (false) { // TODO: this test requires too much time and too much disk space!
+ File f = createZipFile(1024, 3*1024*1024);
+ ZipFile zipFile = new ZipFile(f);
+ int entryCount = 0;
+ for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
+ ZipEntry zipEntry = e.nextElement();
+ ++entryCount;
+ }
+ assertEquals(1024, entryCount);
+ zipFile.close();
+ }
+ }
+
+ public void testZip64Support() throws IOException {
+ try {
+ createZipFile(64*1024, 0);
+ fail(); // Make this test more like testHugeZipFile when we have Zip64 support.
+ } catch (ZipException expected) {
+ }
+ }
+
/**
- * Compresses a single random file into a .zip archive.
+ * Compresses the given number of files, each of the given size, into a .zip archive.
*/
- private File createZipFile(int uncompressedSize) throws IOException {
+ private File createZipFile(int entryCount, int entrySize) throws IOException {
+ File result = createTemporaryZipFile();
+
+ byte[] writeBuffer = new byte[8192];
+ Random random = new Random();
+
+ ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(result)));
+ for (int entry = 0; entry < entryCount; ++entry) {
+ ZipEntry ze = new ZipEntry(Integer.toHexString(entry));
+ out.putNextEntry(ze);
+
+ for (int i = 0; i < entrySize; i += writeBuffer.length) {
+ random.nextBytes(writeBuffer);
+ int byteCount = Math.min(writeBuffer.length, entrySize - i);
+ out.write(writeBuffer, 0, byteCount);
+ }
+
+ out.closeEntry();
+ }
+
+ out.close();
+ return result;
+ }
+
+ private File createTemporaryZipFile() throws IOException {
File result = File.createTempFile("ZipFileTest", "zip");
result.deleteOnExit();
+ return result;
+ }
- ZipOutputStream out = new ZipOutputStream(new FileOutputStream(result));
- ZipEntry entry = new ZipEntry("random");
- out.putNextEntry(entry);
+ private ZipOutputStream createZipOutputStream(File f) throws IOException {
+ return new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
+ }
- byte[] writeBuffer = new byte[8192];
- Random random = new Random();
- for (int i = 0; i < uncompressedSize; i += writeBuffer.length) {
- random.nextBytes(writeBuffer);
- out.write(writeBuffer, 0, Math.min(writeBuffer.length, uncompressedSize - i));
+ public void testSTORED() throws IOException {
+ ZipOutputStream out = createZipOutputStream(createTemporaryZipFile());
+ CRC32 crc = new CRC32();
+
+ // Missing CRC, size, and compressed size => failure.
+ try {
+ ZipEntry ze = new ZipEntry("a");
+ ze.setMethod(ZipEntry.STORED);
+ out.putNextEntry(ze);
+ fail();
+ } catch (ZipException expected) {
+ }
+
+ // Missing CRC and compressed size => failure.
+ try {
+ ZipEntry ze = new ZipEntry("a");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setSize(0);
+ out.putNextEntry(ze);
+ fail();
+ } catch (ZipException expected) {
}
+ // Missing CRC and size => failure.
+ try {
+ ZipEntry ze = new ZipEntry("a");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setSize(0);
+ ze.setCompressedSize(0);
+ out.putNextEntry(ze);
+ fail();
+ } catch (ZipException expected) {
+ }
+
+ // Missing size and compressed size => failure.
+ try {
+ ZipEntry ze = new ZipEntry("a");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setCrc(crc.getValue());
+ out.putNextEntry(ze);
+ fail();
+ } catch (ZipException expected) {
+ }
+
+ // Missing size is copied from compressed size.
+ {
+ ZipEntry ze = new ZipEntry("okay1");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setCrc(crc.getValue());
+
+ assertEquals(-1, ze.getSize());
+ assertEquals(-1, ze.getCompressedSize());
+
+ ze.setCompressedSize(0);
+
+ assertEquals(-1, ze.getSize());
+ assertEquals(0, ze.getCompressedSize());
+
+ out.putNextEntry(ze);
+
+ assertEquals(0, ze.getSize());
+ assertEquals(0, ze.getCompressedSize());
+ }
+
+ // Missing compressed size is copied from size.
+ {
+ ZipEntry ze = new ZipEntry("okay2");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setCrc(crc.getValue());
+
+ assertEquals(-1, ze.getSize());
+ assertEquals(-1, ze.getCompressedSize());
+
+ ze.setSize(0);
+
+ assertEquals(0, ze.getSize());
+ assertEquals(-1, ze.getCompressedSize());
+
+ out.putNextEntry(ze);
+
+ assertEquals(0, ze.getSize());
+ assertEquals(0, ze.getCompressedSize());
+ }
+
+ // Mismatched size and compressed size => failure.
+ try {
+ ZipEntry ze = new ZipEntry("a");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setCrc(crc.getValue());
+ ze.setCompressedSize(1);
+ ze.setSize(0);
+ out.putNextEntry(ze);
+ fail();
+ } catch (ZipException expected) {
+ }
+
+ // Everything present => success.
+ ZipEntry ze = new ZipEntry("okay");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setCrc(crc.getValue());
+ ze.setSize(0);
+ ze.setCompressedSize(0);
+ out.putNextEntry(ze);
+
+ out.close();
+ }
+
+ private String makeString(int count, String ch) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < count; ++i) {
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
+
+ public void testComment() throws Exception {
+ String expectedFileComment = "1 \u0666 2";
+ String expectedEntryComment = "a \u0666 b";
+
+ File file = createTemporaryZipFile();
+ ZipOutputStream out = createZipOutputStream(file);
+
+ // Is file comment length checking done on bytes or characters? (Should be bytes.)
+ out.setComment(null);
+ out.setComment(makeString(0xffff, "a"));
+ try {
+ out.setComment(makeString(0xffff + 1, "a"));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ out.setComment(makeString(0xffff, "\u0666"));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ ZipEntry ze = new ZipEntry("a");
+
+ // Is entry comment length checking done on bytes or characters? (Should be bytes.)
+ ze.setComment(null);
+ ze.setComment(makeString(0xffff, "a"));
+ try {
+ ze.setComment(makeString(0xffff + 1, "a"));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ ze.setComment(makeString(0xffff, "\u0666"));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ ze.setComment(expectedEntryComment);
+ out.putNextEntry(ze);
out.closeEntry();
+
+ out.setComment(expectedFileComment);
out.close();
- return result;
- }
-
- public void testHugeZipFile() throws IOException {
- int expectedEntryCount = 64*1024 - 1;
- File f = createHugeZipFile(expectedEntryCount);
- ZipFile zipFile = new ZipFile(f);
- int entryCount = 0;
- for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
- ZipEntry zipEntry = e.nextElement();
- ++entryCount;
- }
- assertEquals(expectedEntryCount, entryCount);
- zipFile.close();
- }
-
- public void testZip64Support() throws IOException {
- try {
- createHugeZipFile(64*1024);
- fail(); // Make this test more like testHugeZipFile when we have Zip64 support.
- } catch (ZipException expected) {
- }
- }
-
- /**
- * Compresses the given number of empty files into a .zip archive.
- */
- private File createHugeZipFile(int count) throws IOException {
- File result = File.createTempFile("ZipFileTest", "zip");
- result.deleteOnExit();
-
- ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(result)));
- for (int i = 0; i < count; ++i) {
- ZipEntry entry = new ZipEntry(Integer.toHexString(i));
- out.putNextEntry(entry);
- out.closeEntry();
- }
-
- out.close();
- return result;
- }
+
+ ZipFile zipFile = new ZipFile(file);
+ // TODO: there's currently no API for reading the file comment --- strings(1) the file?
+ assertEquals(expectedEntryComment, zipFile.getEntry("a").getComment());
+ zipFile.close();
+ }
+
+ public void testNameLengthChecks() throws IOException {
+ // Is entry name length checking done on bytes or characters?
+ // Really it should be bytes, but the RI only checks characters at construction time.
+ // Android does the same, because it's cheap...
+ try {
+ new ZipEntry((String) null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ new ZipEntry(makeString(0xffff, "a"));
+ try {
+ new ZipEntry(makeString(0xffff + 1, "a"));
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // ...but Android won't let you create a zip file with a truncated name.
+ ZipOutputStream out = createZipOutputStream(createTemporaryZipFile());
+ ZipEntry ze = new ZipEntry(makeString(0xffff, "\u0666"));
+ try {
+ out.putNextEntry(ze);
+ fail(); // The RI fails this test; it just checks the character count at construction time.
+ } catch (IllegalArgumentException expected) {
+ }
+ out.closeEntry();
+ out.putNextEntry(new ZipEntry("okay")); // ZipOutputStream.close throws if you add nothing!
+ out.close();
+ }
+
+ public void testCrc() throws IOException {
+ ZipEntry ze = new ZipEntry("test");
+ ze.setMethod(ZipEntry.STORED);
+ ze.setSize(4);
+
+ // setCrc takes a long, not an int, so -1 isn't a valid CRC32 (because it's 64 bits).
+ try {
+ ze.setCrc(-1);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // You can set the CRC32 to 0xffffffff if you're slightly more careful though...
+ ze.setCrc(0xffffffffL);
+ assertEquals(0xffffffffL, ze.getCrc());
+
+ // And it actually works, even though we use -1L to mean "no CRC set"...
+ ZipOutputStream out = createZipOutputStream(createTemporaryZipFile());
+ out.putNextEntry(ze);
+ out.write(-1);
+ out.write(-1);
+ out.write(-1);
+ out.write(-1);
+ out.closeEntry();
+ out.close();
+ }
}