aboutsummaryrefslogtreecommitdiffstats
path: root/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java')
-rw-r--r--src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java116
1 files changed, 82 insertions, 34 deletions
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
index fe4d6f1ed8..8f7efa02c5 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
@@ -19,6 +19,7 @@ package org.apache.poi.openxml4j.opc;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -88,9 +89,18 @@ public final class ZipPackage extends OPCPackage {
*/
ZipPackage(InputStream in, PackageAccess access) throws IOException {
super(access);
- @SuppressWarnings("resource")
ThresholdInputStream zis = ZipHelper.openZipStream(in);
- this.zipArchive = new ZipInputStreamZipEntrySource(zis);
+ try {
+ this.zipArchive = new ZipInputStreamZipEntrySource(zis);
+ } catch (final IOException e) {
+ try {
+ zis.close();
+ } catch (final IOException e2) {
+ e2.addSuppressed(e);
+ throw new IOException("Failed to close zip input stream while cleaning up", e2);
+ }
+ throw new IOException("Failed to read zip entry source", e);
+ }
}
/**
@@ -100,8 +110,9 @@ public final class ZipPackage extends OPCPackage {
* The path of the file to open or create.
* @param access
* The package access mode.
+ * @throws InvalidOperationException
*/
- ZipPackage(String path, PackageAccess access) {
+ ZipPackage(String path, PackageAccess access) throws InvalidOperationException {
this(new File(path), access);
}
@@ -112,9 +123,9 @@ public final class ZipPackage extends OPCPackage {
* The file to open or create.
* @param access
* The package access mode.
+ * @throws InvalidOperationException
*/
- @SuppressWarnings("resource")
- ZipPackage(File file, PackageAccess access) {
+ ZipPackage(File file, PackageAccess access) throws InvalidOperationException {
super(access);
ZipEntrySource ze;
@@ -127,35 +138,71 @@ public final class ZipPackage extends OPCPackage {
throw new InvalidOperationException("Can't open the specified file: '" + file + "'", e);
}
logger.log(POILogger.ERROR, "Error in zip file "+file+" - falling back to stream processing (i.e. ignoring zip central directory)");
- // some zips can't be opened via ZipFile in JDK6, as the central directory
- // contains either non-latin entries or the compression type can't be handled
- // the workaround is to iterate over the stream and not the directory
- FileInputStream fis = null;
- ThresholdInputStream zis = null;
+ ze = openZipEntrySourceStream(file);
+ }
+ this.zipArchive = ze;
+ }
+
+ private static ZipEntrySource openZipEntrySourceStream(File file) throws InvalidOperationException {
+ final FileInputStream fis;
+ // Acquire a resource that is needed to read the next level of openZipEntrySourceStream
+ try {
+ // open the file input stream
+ fis = new FileInputStream(file);
+ } catch (final FileNotFoundException e) {
+ // If the source cannot be acquired, abort (no resources to free at this level)
+ throw new InvalidOperationException("Can't open the specified file input stream from file: '" + file + "'", e);
+ }
+
+ // If an error occurs while reading the next level of openZipEntrySourceStream, free the acquired resource
+ try {
+ // read from the file input stream
+ return openZipEntrySourceStream(fis);
+ } catch (final Exception e) {
try {
- fis = new FileInputStream(file);
- zis = ZipHelper.openZipStream(fis);
- ze = new ZipInputStreamZipEntrySource(zis);
- } catch (IOException e2) {
- if (zis != null) {
- try {
- zis.close();
- } catch (IOException e3) {
- throw new InvalidOperationException("Can't open the specified file: '" + file + "'"+
- " and couldn't close the file input stream", e);
- }
- } else if (fis != null) {
- try {
- fis.close();
- } catch (IOException e3) {
- throw new InvalidOperationException("Can't open the specified file: '" + file + "'"+
- " and couldn't close the file input stream", e);
- }
- }
- throw new InvalidOperationException("Can't open the specified file: '" + file + "'", e);
+ // abort: close the file input stream
+ fis.close();
+ } catch (final IOException e2) {
+ throw new InvalidOperationException("Could not close the specified file input stream from file: '" + file + "'", e2);
}
+ throw new InvalidOperationException("Failed to read the file input stream from file: '" + file + "'", e);
+ }
+ }
+
+ private static ZipEntrySource openZipEntrySourceStream(FileInputStream fis) throws InvalidOperationException {
+ final ThresholdInputStream zis;
+ // Acquire a resource that is needed to read the next level of openZipEntrySourceStream
+ try {
+ // open the zip input stream
+ zis = ZipHelper.openZipStream(fis);
+ } catch (final IOException e) {
+ // If the source cannot be acquired, abort (no resources to free at this level)
+ throw new InvalidOperationException("Could not open the file input stream", e);
+ }
+
+ // If an error occurs while reading the next level of openZipEntrySourceStream, free the acquired resource
+ try {
+ // read from the zip input stream
+ return openZipEntrySourceStream(zis);
+ } catch (final Exception e) {
+ try {
+ // abort: close the zip input stream
+ zis.close();
+ } catch (final IOException e2) {
+ throw new InvalidOperationException("Failed to read the zip entry source stream and could not close the zip input stream", e2);
+ }
+ throw new InvalidOperationException("Failed to read the zip entry source stream");
+ }
+ }
+
+ private static ZipEntrySource openZipEntrySourceStream(ThresholdInputStream zis) throws InvalidOperationException {
+ // Acquire the final level resource. If this is acquired successfully, the zip package was read successfully from the input stream
+ try {
+ // open the zip entry source stream
+ return new ZipInputStreamZipEntrySource(zis);
+ } catch (IOException e) {
+ throw new InvalidOperationException("Could not open the specified zip entry source stream", e);
}
- this.zipArchive = ze;
}
/**
@@ -220,11 +267,12 @@ public final class ZipPackage extends OPCPackage {
boolean hasSettingsXML = false;
entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) {
- ZipEntry entry = entries.nextElement();
- if (entry.getName().equals("mimetype")) {
+ final ZipEntry entry = entries.nextElement();
+ final String name = entry.getName();
+ if ("mimetype".equals(name)) {
hasMimetype = true;
}
- if (entry.getName().equals("settings.xml")) {
+ if ("settings.xml".equals(name)) {
hasSettingsXML = true;
}
numEntries++;