COMPRESS-64: finish() does not close archive entries by default any longer
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/compress/trunk@767386 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java
index 2cad89d..1d6e78e 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java
@@ -74,6 +74,9 @@
/**
* Finishes the addition of entries to this stream, without closing it.
* Additional data can be written, if the format supports it.
+ *
+ * The finish() method throws an Exception if the user forgets to close the entry
+ * .
* @throws IOException
*/
public abstract void finish() throws IOException;
diff --git a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
index 8a48da5..de1a87c 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java
@@ -153,7 +153,6 @@
}
public void close() throws IOException {
- closeArchiveEntry();
out.close();
prevEntry = null;
}
@@ -167,6 +166,8 @@
* @see org.apache.commons.compress.archivers.ArchiveOutputStream#finish()
*/
public void finish() throws IOException {
- // Nothing to do
+ if(haveUnclosedEntry) {
+ throw new IOException("This archives contains unclosed entries.");
+ }
}
}
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
index b9b1ead..3641ab6 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
@@ -315,7 +315,7 @@
return;
}
if (this.entry != null) {
- closeArchiveEntry();
+ throw new IOException("This archives contains unclosed entries.");
}
this.entry = new CpioArchiveEntry(this.entryFormat);
this.entry.setName(CPIO_TRAILER);
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
index 1d9e5c5..2dc3b26 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
@@ -51,6 +51,9 @@
private boolean closed = false;
+ /* Indicates if putArchiveEntry has been called without closeArchiveEntry */
+ private boolean haveUnclosedEntry = false;
+
private final OutputStream out;
/**
@@ -107,6 +110,9 @@
* @throws IOException on error
*/
public void finish() throws IOException {
+ if(haveUnclosedEntry) {
+ throw new IOException("This archives contains unclosed entries.");
+ }
writeEOFRecord();
writeEOFRecord();
}
@@ -182,6 +188,7 @@
currSize = entry.getSize();
}
currName = entry.getName();
+ haveUnclosedEntry = true;
}
/**
@@ -212,6 +219,7 @@
+ "' before the '" + currSize
+ "' bytes specified in the header were written");
}
+ haveUnclosedEntry = false;
}
/**
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
index cb8a203..645d3af 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
@@ -328,13 +328,14 @@
fallbackToUTF8 = b;
}
- /**
- * Finishs writing the contents and closes this as well as the
- * underlying stream.
- * @throws IOException on error
+ /* (non-Javadoc)
+ * @see org.apache.commons.compress.archivers.ArchiveOutputStream#finish()
*/
public void finish() throws IOException {
- closeArchiveEntry();
+ if(entry != null) {
+ throw new IOException("This archives contains unclosed entries.");
+ }
+
cdOffset = written;
for (Iterator i = entries.iterator(); i.hasNext(); ) {
writeCentralFileHeader((ZipArchiveEntry) i.next());
diff --git a/src/test/java/org/apache/commons/compress/IOMethodsTest.java b/src/test/java/org/apache/commons/compress/IOMethodsTest.java
index 2dce20f..eabf80d 100644
--- a/src/test/java/org/apache/commons/compress/IOMethodsTest.java
+++ b/src/test/java/org/apache/commons/compress/IOMethodsTest.java
@@ -104,14 +104,20 @@
for (int i=0; i<byteTest.length; i++){
aos1.write(byteTest[i]);
}
+ aos1.closeArchiveEntry();
aos1.close();
+
aos2.write(byteTest);
+ aos2.closeArchiveEntry();
aos2.close();
+
aos3.write(byteTest, 0, byteTest.length);
+ aos3.closeArchiveEntry();
aos3.close();
assertEquals("out1!=out2",out1.toString(),out2.toString());
assertEquals("out1!=out3",out1.toString(),out3.toString());
}
+
private void compareReads(String archiverName) throws Exception {
OutputStream out1 = new ByteArrayOutputStream();
OutputStream out2 = new ByteArrayOutputStream();
diff --git a/src/test/java/org/apache/commons/compress/archivers/ArchiveOutputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/ArchiveOutputStreamTest.java
new file mode 100644
index 0000000..7a273ba
--- /dev/null
+++ b/src/test/java/org/apache/commons/compress/archivers/ArchiveOutputStreamTest.java
@@ -0,0 +1,73 @@
+package org.apache.commons.compress.archivers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.compress.AbstractTestCase;
+import org.apache.commons.compress.archivers.ar.ArArchiveEntry;
+import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;
+import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+
+public class ArchiveOutputStreamTest extends AbstractTestCase {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testFinish() throws Exception {
+ OutputStream out1 = new ByteArrayOutputStream();
+
+ ArchiveOutputStream aos1 = factory.createArchiveOutputStream("zip", out1);
+ aos1.putArchiveEntry(new ZipArchiveEntry("dummy"));
+ try {
+ aos1.finish();
+ fail("After putArchive should follow closeArchive");
+ } catch (IOException io) {
+ // Exception expected
+ }
+
+ aos1 = factory.createArchiveOutputStream("jar", out1);
+ aos1.putArchiveEntry(new JarArchiveEntry("dummy"));
+ try {
+ aos1.finish();
+ fail("After putArchive should follow closeArchive");
+ } catch (IOException io) {
+ // Exception expected
+ }
+
+ aos1 = factory.createArchiveOutputStream("ar", out1);
+ aos1.putArchiveEntry(new ArArchiveEntry("dummy", 100));
+ try {
+ aos1.finish();
+ fail("After putArchive should follow closeArchive");
+ } catch (IOException io) {
+ // Exception expected
+ }
+
+ aos1 = factory.createArchiveOutputStream("cpio", out1);
+ aos1.putArchiveEntry(new CpioArchiveEntry("dummy"));
+ try {
+ aos1.finish();
+ fail("After putArchive should follow closeArchive");
+ } catch (IOException io) {
+ // Exception expected
+ }
+
+ aos1 = factory.createArchiveOutputStream("tar", out1);
+ aos1.putArchiveEntry(new TarArchiveEntry("dummy"));
+ try {
+ aos1.finish();
+ fail("After putArchive should follow closeArchive");
+ } catch (IOException io) {
+ // Exception expected
+ }
+ }
+
+}