From b9841b4007c5a4590262600b51ee863bb7678168 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 14 Aug 2020 20:26:21 +0000 Subject: [PATCH] also handle wrapped OOXML "Package" nodes inside of OLE2 containers git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1880861 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/extractor/ExtractorFactory.java | 9 ++++++++- .../poi/poifs/filesystem/DocumentFactoryHelper.java | 13 ++++++++++--- .../apache/poi/sl/usermodel/SlideShowFactory.java | 6 ++++-- .../apache/poi/ss/usermodel/WorkbookFactory.java | 6 ++++-- .../poi/ooxml/extractor/POIXMLExtractorFactory.java | 6 ++++-- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/java/org/apache/poi/extractor/ExtractorFactory.java b/src/java/org/apache/poi/extractor/ExtractorFactory.java index fa57be7a8c..bdeb740e20 100644 --- a/src/java/org/apache/poi/extractor/ExtractorFactory.java +++ b/src/java/org/apache/poi/extractor/ExtractorFactory.java @@ -53,6 +53,13 @@ import org.apache.poi.util.POILogger; */ @SuppressWarnings({"WeakerAccess", "JavadocReference"}) public final class ExtractorFactory { + /** + * Some OPCPackages are packed in side an OLE2 container. + * If encrypted, the {@link DirectoryNode} is called {@link Decryptor#DEFAULT_POIFS_ENTRY "EncryptedPackage"}, + * otherwise the node is called "Packge" + */ + public static final String OOXML_PACKAGE = "Package"; + private static final POILogger LOGGER = POILogFactory.getLogger(ExtractorFactory.class); /** Should this thread prefer event based over usermodel based extractors? */ @@ -215,7 +222,7 @@ public final class ExtractorFactory { public static POITextExtractor createExtractor(final DirectoryNode root, String password) throws IOException { // Encrypted OOXML files go inside OLE2 containers, is this one? - if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry("Package")) { + if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE)) { return wp(FileMagic.OOXML, w -> w.create(root, password)); } else { return wp(FileMagic.OLE2, w -> w.create(root, password)); diff --git a/src/java/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.java b/src/java/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.java index 9ac5e94018..088b549283 100644 --- a/src/java/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.java +++ b/src/java/org/apache/poi/poifs/filesystem/DocumentFactoryHelper.java @@ -17,6 +17,8 @@ package org.apache.poi.poifs.filesystem; +import static org.apache.poi.extractor.ExtractorFactory.OOXML_PACKAGE; + import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; @@ -69,7 +71,12 @@ public final class DocumentFactoryHelper { * @throws IOException If an error occurs while decrypting or if the password does not match */ public static InputStream getDecryptedStream(final DirectoryNode root, String password) - throws IOException { + throws IOException { + // first check if the node contains an plain package + if (root.hasEntry(OOXML_PACKAGE)) { + return root.createDocumentInputStream(OOXML_PACKAGE); + } + EncryptionInfo info = new EncryptionInfo(root); Decryptor d = Decryptor.getInstance(info); @@ -97,11 +104,11 @@ public final class DocumentFactoryHelper { /** * Checks that the supplied InputStream (which MUST * support mark and reset) has a OOXML (zip) header at the start of it.

- * + * * If unsure if your InputStream does support mark / reset, * use {@link FileMagic#prepareToCheckMagic(InputStream)} to wrap it and make * sure to always use that, and not the original! - * + * * @param inp An InputStream which supports either mark/reset * * @deprecated in 3.17-beta2, use {@link FileMagic#valueOf(InputStream)} == FileMagic.OOXML instead diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java b/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java index 1424a70608..200120b211 100644 --- a/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java +++ b/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java @@ -16,6 +16,7 @@ ==================================================================== */ package org.apache.poi.sl.usermodel; +import static org.apache.poi.extractor.ExtractorFactory.OOXML_PACKAGE; import static org.apache.poi.poifs.crypt.EncryptionInfo.ENCRYPTION_INFO_ENTRY; import java.io.BufferedInputStream; @@ -123,7 +124,7 @@ public final class SlideShowFactory { */ public static SlideShow create(final DirectoryNode root, String password) throws IOException { // Encrypted OOXML files go inside OLE2 containers, is this one? - if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { + if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE)) { return wp(FileMagic.OOXML, w -> w.create(root, password)); } else { return wp(FileMagic.OLE2, w -> w.create(root, password)); @@ -269,7 +270,8 @@ public final class SlideShowFactory { } else if (fm == FileMagic.OLE2) { final boolean ooxmlEnc; try (POIFSFileSystem fs = new POIFSFileSystem(file, true)) { - ooxmlEnc = fs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY); + DirectoryNode root = fs.getRoot(); + ooxmlEnc = root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE); } return wp(ooxmlEnc ? FileMagic.OOXML : fm, w -> w.create(file, password, readOnly)); } diff --git a/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java b/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java index d9504fe63a..e755b09f5e 100644 --- a/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java +++ b/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java @@ -16,6 +16,7 @@ ==================================================================== */ package org.apache.poi.ss.usermodel; +import static org.apache.poi.extractor.ExtractorFactory.OOXML_PACKAGE; import static org.apache.poi.poifs.crypt.EncryptionInfo.ENCRYPTION_INFO_ENTRY; import java.io.BufferedInputStream; @@ -130,7 +131,7 @@ public final class WorkbookFactory { */ public static Workbook create(final DirectoryNode root, String password) throws IOException { // Encrypted OOXML files go inside OLE2 containers, is this one? - if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { + if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE)) { return wp(FileMagic.OOXML, w -> w.create(root, password)); } else { return wp(FileMagic.OLE2, w -> w.create(root, password)); @@ -276,7 +277,8 @@ public final class WorkbookFactory { } else if (fm == FileMagic.OLE2) { final boolean ooxmlEnc; try (POIFSFileSystem fs = new POIFSFileSystem(file, true)) { - ooxmlEnc = fs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY); + DirectoryNode root = fs.getRoot(); + ooxmlEnc = root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE); } return wp(ooxmlEnc ? FileMagic.OOXML : fm, w -> w.create(file, password, readOnly)); } diff --git a/src/ooxml/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java b/src/ooxml/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java index ed3067869f..088e09c3fe 100644 --- a/src/ooxml/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java +++ b/src/ooxml/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java @@ -16,6 +16,8 @@ ==================================================================== */ package org.apache.poi.ooxml.extractor; +import static org.apache.poi.extractor.ExtractorFactory.OOXML_PACKAGE; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -253,8 +255,8 @@ public final class POIXMLExtractorFactory implements ExtractorProvider { @Override public POITextExtractor create(DirectoryNode poifsDir, String password) throws IOException { // First, check for plain OOXML package - if (poifsDir.hasEntry("Package")) { - try (InputStream is = poifsDir.createDocumentInputStream("Package")) { + if (poifsDir.hasEntry(OOXML_PACKAGE)) { + try (InputStream is = poifsDir.createDocumentInputStream(OOXML_PACKAGE)) { return create(is, password); } } -- 2.39.5