Start to give more helpful Exceptions from OPCPackage when non-OOXML files are passed to it

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1735060 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2016-03-15 11:50:57 +00:00
parent 246ff9c99a
commit 2115a45b05
8 changed files with 154 additions and 5 deletions

View File

@ -17,12 +17,14 @@
package org.apache.poi.poifs.filesystem; 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 * 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 * an Office 2007+ XML file, rather than an OLE2 file (which is what
* POIFS works with) * POIFS works with)
*/ */
public class OfficeXmlFileException extends IllegalArgumentException { public class OfficeXmlFileException extends UnsupportedFileFormatException {
public OfficeXmlFileException(String s) { public OfficeXmlFileException(String s) {
super(s); super(s);
} }

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -21,9 +21,6 @@ package org.apache.poi.openxml4j.exceptions;
* Global exception throws when a critical error occurs. (this exception is not * 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 * set as Runtime in order to force user to manage the exception in a
* try/catch). * try/catch).
*
* @author CDubettier, Julien Chable
* @version 1.0
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class OpenXML4JException extends Exception { public class OpenXML4JException extends Exception {

View File

@ -29,6 +29,7 @@ import java.util.zip.ZipOutputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException; 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.OpenXML4JException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
@ -176,6 +177,7 @@ public final class ZipPackage extends Package {
return this.partList.values().toArray( return this.partList.values().toArray(
new PackagePart[this.partList.values().size()]); new PackagePart[this.partList.values().size()]);
} }
// First we need to parse the content type part // First we need to parse the content type part
Enumeration<? extends ZipEntry> entries = this.zipArchive.getEntries(); Enumeration<? extends ZipEntry> entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
@ -194,6 +196,26 @@ public final class ZipPackage extends Package {
// At this point, we should have loaded the content type part // At this point, we should have loaded the content type part
if (this.contentTypeManager == null) { 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( throw new InvalidFormatException(
"Package should contain a content type part [M1.13]"); "Package should contain a content type part [M1.13]");
} }

View File

@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream; import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream;

View File

@ -45,11 +45,14 @@ import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import org.apache.poi.EncryptedDocumentException; import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.POIDataSamples;
import org.apache.poi.POITestCase; import org.apache.poi.POITestCase;
import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException; 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.ContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.FileHelper; import org.apache.poi.openxml4j.opc.internal.FileHelper;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
@ -665,6 +668,49 @@ public final class TestPackage {
p.revert(); p.revert();
is.close(); 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) @Test(expected=IOException.class)
public void zipBombCreateAndHandle() public void zipBombCreateAndHandle()