diff --git a/platform/util/src/com/intellij/util/io/Decompressor.java b/platform/util/src/com/intellij/util/io/Decompressor.java index 83a8f52b7aa9..e6702935e765 100644 --- a/platform/util/src/com/intellij/util/io/Decompressor.java +++ b/platform/util/src/com/intellij/util/io/Decompressor.java @@ -11,8 +11,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; +import java.util.Enumeration; import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +import java.util.zip.ZipFile; public abstract class Decompressor { public static class Tar extends Decompressor { @@ -57,37 +58,42 @@ public abstract class Decompressor { // } - public static class Zip extends Decompressor { + public static class Zip extends Decompressor { public Zip(@NotNull File file) { mySource = file; } // private final File mySource; + private Enumeration myEntries; + private ZipEntry myEntry; @Override - protected ZipInputStream openStream() throws IOException { - return new ZipInputStream(new FileInputStream(mySource)); + protected ZipFile openStream() throws IOException { + return new ZipFile(mySource); } @Override - protected Entry nextEntry(ZipInputStream zip) throws IOException { - ZipEntry zipEntry = zip.getNextEntry(); - return zipEntry == null ? null : new Entry(zipEntry.getName(), zipEntry.isDirectory()); + protected Entry nextEntry(ZipFile zip) { + if (myEntries == null) myEntries = zip.entries(); + myEntry = myEntries.hasMoreElements() ? myEntries.nextElement() : null; + return myEntry == null ? null : new Entry(myEntry.getName(), myEntry.isDirectory()); } @Override - protected InputStream openEntryStream(ZipInputStream stream, Entry entry) { - return stream; + protected InputStream openEntryStream(ZipFile zip, Entry entry) throws IOException { + return zip.getInputStream(myEntry); } @Override - protected void closeEntryStream(InputStream stream) { } - - @Override - protected void closeStream(ZipInputStream stream) throws IOException { + protected void closeEntryStream(InputStream stream) throws IOException { stream.close(); } + + @Override + protected void closeStream(ZipFile zip) throws IOException { + zip.close(); + } // } diff --git a/platform/util/testSrc/com/intellij/util/io/DecompressorTest.kt b/platform/util/testSrc/com/intellij/util/io/DecompressorTest.kt index f4f8c09142b0..a6837f0044ac 100644 --- a/platform/util/testSrc/com/intellij/util/io/DecompressorTest.kt +++ b/platform/util/testSrc/com/intellij/util/io/DecompressorTest.kt @@ -13,6 +13,7 @@ import java.io.FileOutputStream import java.io.IOException import java.util.* import java.util.zip.ZipEntry +import java.util.zip.ZipException import java.util.zip.ZipOutputStream class DecompressorTest { @@ -62,6 +63,14 @@ class DecompressorTest { assertThat(File(dir, "root.txt")).exists() } + @Test(expected = ZipException::class) + fun failsOnCorruptedZip() { + val zip = tempDir.newFile("test.zip") + zip.writeText("whatever") + val dir = tempDir.newFolder("unpacked") + Decompressor.Zip(zip).extract(dir) + } + private fun writeEntry(zip: ZipOutputStream, name: String) { val entry = ZipEntry(name) entry.time = System.currentTimeMillis()