diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index c378bc5a4..0b0d34ea7 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + 41711 - Base class for "old version" exceptions, and new HSLF detection + use of old versions exception 47179 - Fix string encoding issues with HSMF chunks on non-windows platforms 47183 - Attachment support for HSMF 47154 - Handle the cell format @ as the same as General diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 1a00c9ee0..380b622ce 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 41711 - Base class for "old version" exceptions, and new HSLF detection + use of old versions exception 47179 - Fix string encoding issues with HSMF chunks on non-windows platforms 47183 - Attachment support for HSMF 47154 - Handle the cell format @ as the same as General diff --git a/src/java/org/apache/poi/OldFileFormatException.java b/src/java/org/apache/poi/OldFileFormatException.java new file mode 100644 index 000000000..abcdc9710 --- /dev/null +++ b/src/java/org/apache/poi/OldFileFormatException.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; + +/** + * Base class of all the exceptions that POI throws in the event + * that it's given a file that's older than currently supported. + */ +public abstract class OldFileFormatException extends IllegalArgumentException { + public OldFileFormatException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/OldExcelFormatException.java b/src/java/org/apache/poi/hssf/OldExcelFormatException.java index 5b8e5e4c4..e42e613d8 100644 --- a/src/java/org/apache/poi/hssf/OldExcelFormatException.java +++ b/src/java/org/apache/poi/hssf/OldExcelFormatException.java @@ -16,7 +16,9 @@ ==================================================================== */ package org.apache.poi.hssf; -public class OldExcelFormatException extends IllegalArgumentException { +import org.apache.poi.OldFileFormatException; + +public class OldExcelFormatException extends OldFileFormatException { public OldExcelFormatException(String s) { super(s); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/exceptions/OldPowerPointFormatException.java b/src/scratchpad/src/org/apache/poi/hslf/exceptions/OldPowerPointFormatException.java new file mode 100644 index 000000000..fbb2f6d5f --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/exceptions/OldPowerPointFormatException.java @@ -0,0 +1,30 @@ + +/* ==================================================================== + 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.hslf.exceptions; + +import org.apache.poi.OldFileFormatException; + +/** + * This exception is thrown when we try to open a PowerPoint file, and + * it's too old for us. + */ +public class OldPowerPointFormatException extends OldFileFormatException { + public OldPowerPointFormatException(String s) { + super(s); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java index fb669b38e..1c7ad9f7f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java @@ -26,6 +26,7 @@ import org.apache.poi.util.LittleEndian; import org.apache.poi.util.StringUtil; import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException; +import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; /** @@ -110,18 +111,31 @@ public class CurrentUserAtom // Decide how big it is DocumentEntry docProps = (DocumentEntry)dir.getEntry("Current User"); - _contents = new byte[docProps.getSize()]; - - // Check it's big enough - if it's not at least 28 bytes long, then - // the record is corrupt - if(_contents.length < 28) { - throw new CorruptPowerPointFileException("The Current User stream must be at least 28 bytes long, but was only " + _contents.length); + + // If it's clearly junk, bail out + if(docProps.getSize() > 131072) { + throw new CorruptPowerPointFileException("The Current User stream is implausably long. It's normally 28-200 bytes long, but was " + docProps.getSize() + " bytes"); } - + // Grab the contents + _contents = new byte[docProps.getSize()]; InputStream in = dir.createDocumentInputStream("Current User"); in.read(_contents); + // See how long it is. If it's under 28 bytes long, we can't + // read it + if(_contents.length < 28) { + if(_contents.length >= 4) { + // PPT95 has 4 byte size, then data + int size = LittleEndian.getInt(_contents); + System.err.println(size); + if(size + 4 == _contents.length) { + throw new OldPowerPointFormatException("Based on the Current User stream, you seem to have supplied a PowerPoint95 file, which isn't supported"); + } + } + throw new CorruptPowerPointFileException("The Current User stream must be at least 28 bytes long, but was only " + _contents.length); + } + // Set everything up init(); } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/data/PPT95.ppt b/src/scratchpad/testcases/org/apache/poi/hslf/data/PPT95.ppt new file mode 100644 index 000000000..3f338d433 Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hslf/data/PPT95.ppt differ diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java index be22db0d5..1fe9ada7f 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java @@ -43,6 +43,8 @@ public class TestSheet extends TestCase{ File[] files = home.listFiles(); for (int i = 0; i < files.length; i++) { if(!files[i].getName().endsWith(".ppt")) continue; + if(files[i].getName().endsWith("PPT95.ppt")) continue; + try { FileInputStream is = new FileInputStream(files[i]); HSLFSlideShow hslf = new HSLFSlideShow(is); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java index 6947ff9cf..820a5390a 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -19,6 +19,7 @@ package org.apache.poi.hslf.usermodel; import junit.framework.TestCase; import org.apache.poi.hslf.HSLFSlideShow; +import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; import org.apache.poi.hslf.model.*; import org.apache.poi.hslf.model.Shape; @@ -380,4 +381,23 @@ public class TestBugs extends TestCase { assertEquals(1, run.length); assertEquals("Fundera, planera och involvera.", run[0].getText()); } + + /** + * PowerPoint 95 files should throw a more helpful exception + * @throws Exception + */ + public void test41711() throws Exception { + // New file is fine + FileInputStream is = new FileInputStream(new File(cwd, "SampleShow.ppt")); + SlideShow ppt = new SlideShow(is); + + // PowerPoint 95 gives an old format exception + is = new FileInputStream(new File(cwd, "PPT95.ppt")); + try { + new SlideShow(is); + fail("OldPowerPointFormatException should've been thrown"); + } catch(OldPowerPointFormatException e) { + // Good + } + } }