diff options
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.java | 116 |
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++; |