diff --git a/src/java/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java b/src/java/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java index 927fd94f79..ac2404b72a 100644 --- a/src/java/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java +++ b/src/java/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java @@ -17,12 +17,14 @@ package org.apache.poi.poifs.filesystem; +import org.apache.poi.UnsupportedFileFormatException; + /** * This exception is thrown when we try to open a file that's actually * an Office 2007+ XML file, rather than an OLE2 file (which is what * POIFS works with) */ -public class OfficeXmlFileException extends IllegalArgumentException { +public class OfficeXmlFileException extends UnsupportedFileFormatException { public OfficeXmlFileException(String s) { super(s); } diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/NotOfficeXmlFileException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/NotOfficeXmlFileException.java new file mode 100644 index 0000000000..901967e202 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/NotOfficeXmlFileException.java @@ -0,0 +1,29 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.openxml4j.exceptions; + +import org.apache.poi.UnsupportedFileFormatException; + +/** + * This exception is thrown when we try to open a file that doesn't + * seem to actually be an OOXML (Office Open XML) file after all + */ +public class NotOfficeXmlFileException extends UnsupportedFileFormatException { + public NotOfficeXmlFileException(String message) { + super(message); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/ODFNotOfficeXmlFileException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/ODFNotOfficeXmlFileException.java new file mode 100644 index 0000000000..61d8c8cd95 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/ODFNotOfficeXmlFileException.java @@ -0,0 +1,27 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.openxml4j.exceptions; + +/** + * This exception is thrown when we are given an ODF-based file + * (eg OpenOffice .ods) instead of an actually OOXML (Office Open XML) file + */ +public class ODFNotOfficeXmlFileException extends NotOfficeXmlFileException { + public ODFNotOfficeXmlFileException(String message) { + super(message); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OLE2NotOfficeXmlFileException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OLE2NotOfficeXmlFileException.java new file mode 100644 index 0000000000..2f82d1100a --- /dev/null +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OLE2NotOfficeXmlFileException.java @@ -0,0 +1,27 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.openxml4j.exceptions; + +/** + * This exception is thrown when we are given an OLE2-based file + * (eg Excel .xls) instead of an actually OOXML (Office Open XML) file + */ +public class OLE2NotOfficeXmlFileException extends NotOfficeXmlFileException { + public OLE2NotOfficeXmlFileException(String message) { + super(message); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java index ce08aafc88..4c7430df5b 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java @@ -21,9 +21,6 @@ package org.apache.poi.openxml4j.exceptions; * Global exception throws when a critical error occurs. (this exception is not * set as Runtime in order to force user to manage the exception in a * try/catch). - * - * @author CDubettier, Julien Chable - * @version 1.0 */ @SuppressWarnings("serial") public class OpenXML4JException extends Exception { 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 6fa83e9398..e40f4ef3a6 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -29,6 +29,7 @@ import java.util.zip.ZipOutputStream; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException; +import org.apache.poi.openxml4j.exceptions.ODFNotOfficeXmlFileException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; @@ -176,6 +177,7 @@ public final class ZipPackage extends Package { return this.partList.values().toArray( new PackagePart[this.partList.values().size()]); } + // First we need to parse the content type part Enumeration entries = this.zipArchive.getEntries(); while (entries.hasMoreElements()) { @@ -194,6 +196,26 @@ public final class ZipPackage extends Package { // At this point, we should have loaded the content type part if (this.contentTypeManager == null) { + // Is it a different Zip-based format? + boolean hasMimetype = false; + boolean hasSettingsXML = false; + entries = this.zipArchive.getEntries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + if (entry.getName().equals("mimetype")) { + hasMimetype = true; + } + if (entry.getName().equals("settings.xml")) { + hasSettingsXML = true; + } + } + if (hasMimetype && hasSettingsXML) { + throw new ODFNotOfficeXmlFileException( + "The supplied data appears to be in ODF (Open Document) Format. " + + "Formats like these (eg ODS, ODP) are not supported, try Apache ODFToolkit"); + } + + // Fallback exception throw new InvalidFormatException( "Package should contain a content type part [M1.13]"); } diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java index 7d72212cdd..36b69ac25b 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream; diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java index 35209dfada..7a113d7286 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java @@ -45,11 +45,14 @@ import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import org.apache.poi.EncryptedDocumentException; +import org.apache.poi.POIDataSamples; import org.apache.poi.POITestCase; import org.apache.poi.POIXMLException; import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException; +import org.apache.poi.openxml4j.exceptions.ODFNotOfficeXmlFileException; +import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException; import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; import org.apache.poi.openxml4j.opc.internal.FileHelper; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; @@ -665,6 +668,49 @@ public final class TestPackage { p.revert(); is.close(); } + + /** + * Verify we give helpful exceptions (or as best we can) when + * supplied with non-OOXML file types (eg OLE2, ODF) + */ + @Test + public void NonOOXMLFileTypes() throws Exception { + // Spreadsheet has a good mix of alternate file types + POIDataSamples files = POIDataSamples.getSpreadSheetInstance(); + + // OLE2 - Stream +// try { +// OPCPackage.open(files.openResourceAsStream("SampleSS.xls")); +// fail("Shouldn't be able to open OLE2"); +// } catch (OLE2NotOfficeXmlFileException e) { +// // TODO Check details +// } + + // OLE2 - File + + // ODF / ODS - Stream + try { + OPCPackage.open(files.openResourceAsStream("SampleSS.ods")); + fail("Shouldn't be able to open ODS"); + } catch (ODFNotOfficeXmlFileException e) { + assertTrue(e.toString().contains("The supplied data appears to be in ODF")); + assertTrue(e.toString().contains("Formats like these (eg ODS")); + } + // ODF / ODS - File + try { + OPCPackage.open(files.getFile("SampleSS.ods")); + fail("Shouldn't be able to open ODS"); + } catch (ODFNotOfficeXmlFileException e) { + assertTrue(e.toString().contains("The supplied data appears to be in ODF")); + assertTrue(e.toString().contains("Formats like these (eg ODS")); + } + + // Plain Text - Stream + // Plain Text - File + + // Raw XML - Stream + // Raw XML - File + } @Test(expected=IOException.class) public void zipBombCreateAndHandle()