diff options
author | Narayan Kamath <narayan@google.com> | 2015-01-27 16:25:36 +0000 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2015-02-27 11:25:51 +0000 |
commit | 12f5c69e074d6ef012706068416f0a61b70b4e52 (patch) | |
tree | 3174fa65e1815131e5e6a0a2b5c3d0cca685f6b5 /luni/src/test/java | |
parent | a378356955bcaf7be9434e8babed1b106f741a00 (diff) | |
download | libcore-12f5c69e074d6ef012706068416f0a61b70b4e52.zip libcore-12f5c69e074d6ef012706068416f0a61b70b4e52.tar.gz libcore-12f5c69e074d6ef012706068416f0a61b70b4e52.tar.bz2 |
Implement zip64 support for ZipFile/ZipInputStream/ZipOutputStream.
There are several open questions that I hope to resolve in future
changes :
- Our heuristics for detecting whether a zip outputstream should
switch over to zip64 or not are imprecise.
- Also, given that we now officially support zip64, we have to assume
new entries whose size is unknown need the zip64 header / footer.
This will make output files slightly larger and less compatible with
older tools. If we don't do this, we'll have to go back and rewrite &
compact parts of the stream we'd already flushed, which isn't always
possible. The other option is to assume zip32 for streams of unknown
length and throw if more than 4G of data is written to them.
Change-Id: Ibb4a97b5f83fd3ab850d7c407ecfda663968a6b9
Diffstat (limited to 'luni/src/test/java')
-rw-r--r-- | luni/src/test/java/libcore/java/util/zip/ZipEntryTest.java | 35 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/util/zip/ZipFileTest.java | 60 |
2 files changed, 86 insertions, 9 deletions
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipEntryTest.java b/luni/src/test/java/libcore/java/util/zip/ZipEntryTest.java index 550ddfb..9c3e870 100644 --- a/luni/src/test/java/libcore/java/util/zip/ZipEntryTest.java +++ b/luni/src/test/java/libcore/java/util/zip/ZipEntryTest.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.List; import java.util.jar.JarEntry; import java.util.zip.ZipEntry; +import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; @@ -132,6 +133,7 @@ public class ZipEntryTest extends junit.framework.TestCase { File f = createTemporaryZipFile(); ZipOutputStream out = createZipOutputStream(f); ZipEntry ze = new ZipEntry("x"); + ze.setSize(0); ze.setExtra(maxLengthExtra); out.putNextEntry(ze); out.closeEntry(); @@ -143,7 +145,25 @@ public class ZipEntryTest extends junit.framework.TestCase { zipFile.close(); } - public void testTooLongComment() throws Exception { + public void testMaxLengthExtra_zip64() throws Exception { + // Not quite the max length (65535), but large enough that there's no space + // for the zip64 extended info header. + byte[] maxLengthExtra = new byte[65530]; + + File f = createTemporaryZipFile(); + ZipOutputStream out = createZipOutputStream(f); + ZipEntry ze = new ZipEntry("x"); + + ze.setExtra(maxLengthExtra); + try { + out.putNextEntry(ze); + fail(); + } catch (ZipException expected) { + } + } + + + public void testTooLongComment() throws Exception { String tooLongComment = makeString(65536, "z"); ZipEntry ze = new ZipEntry("x"); try { @@ -176,7 +196,17 @@ public class ZipEntryTest extends junit.framework.TestCase { File f = createTemporaryZipFile(); ZipOutputStream out = createZipOutputStream(f); + + // Regular (non zip64) format. ZipEntry ze = new ZipEntry("x"); + ze.setSize(0); + ze.setExtra(extra); + ze.setComment(comment); + out.putNextEntry(ze); + out.closeEntry(); + + // An entry without a length is assumed to be zip64. + ze = new ZipEntry("y"); ze.setExtra(extra); ze.setComment(comment); out.putNextEntry(ze); @@ -188,6 +218,9 @@ public class ZipEntryTest extends junit.framework.TestCase { try { assertEquals(comment, zipFile.getEntry("x").getComment()); assertTrue(Arrays.equals(extra, zipFile.getEntry("x").getExtra())); + + assertEquals(comment, zipFile.getEntry("y").getComment()); + assertTrue(Arrays.equals(extra, zipFile.getEntry("y").getExtra())); } finally { zipFile.close(); } 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 1826140..bf18978 100644 --- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java +++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java @@ -196,7 +196,7 @@ public final class ZipFileTest extends TestCase { ZipFile zipFile = new ZipFile(f); int entryCount = 0; for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) { - ZipEntry zipEntry = e.nextElement(); + e.nextElement(); ++entryCount; } assertEquals(1024, entryCount); @@ -204,18 +204,62 @@ public final class ZipFileTest extends TestCase { } } - public void testZip64Support() throws IOException { + public void testZip64Support_largeNumberOfEntries() throws IOException { + File file = createZipFile(65550, 2); + ZipFile zf = null; try { - createZipFile(64*1024, 0); - fail(); // Make this test more like testHugeZipFile when we have Zip64 support. - } catch (ZipException expected) { + zf = new ZipFile(file); + assertEquals(65550, zf.size()); + + Enumeration<? extends ZipEntry> entries = zf.entries(); + assertTrue(entries.hasMoreElements()); + ZipEntry ze = entries.nextElement(); + assertEquals(2, ze.getSize()); + } finally { + if (zf != null) { + zf.close(); + } + } + } + + public void testZip64Support_totalLargerThan4G() throws IOException { + final File file = createZipFile(5, 1073741824L); + ZipFile zf = null; + try { + zf = new ZipFile(file); + assertEquals(5, zf.size()); + Enumeration<? extends ZipEntry> entries = zf.entries(); + assertTrue(entries.hasMoreElements()); + ZipEntry ze = entries.nextElement(); + assertEquals(1073741824L, ze.getSize()); + } finally { + if (zf != null) { + zf.close(); + } + } + } + + public void testZip64Support_hugeEntry() throws IOException { + final File file = createZipFile(1, 4294967410L); + ZipFile zf = null; + try { + zf = new ZipFile(file); + assertEquals(1, zf.size()); + Enumeration<? extends ZipEntry> entries = zf.entries(); + assertTrue(entries.hasMoreElements()); + ZipEntry ze = entries.nextElement(); + assertEquals(4294967410L, ze.getSize()); + } finally { + if (zf != null) { + zf.close(); + } } } /** * Compresses the given number of files, each of the given size, into a .zip archive. */ - private static File createZipFile(int entryCount, int entrySize) throws IOException { + private static File createZipFile(int entryCount, long entrySize) throws IOException { File result = createTemporaryZipFile(); byte[] writeBuffer = new byte[8192]; @@ -227,9 +271,9 @@ public final class ZipFileTest extends TestCase { ZipEntry ze = new ZipEntry(Integer.toHexString(entry)); out.putNextEntry(ze); - for (int i = 0; i < entrySize; i += writeBuffer.length) { + for (long i = 0; i < entrySize; i += writeBuffer.length) { random.nextBytes(writeBuffer); - int byteCount = Math.min(writeBuffer.length, entrySize - i); + int byteCount = (int) Math.min(writeBuffer.length, entrySize - i); out.write(writeBuffer, 0, byteCount); } |