diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index c27545d3c..8ea8eb323 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 50118 - OLE2 does allow a directory with an empty name, so support this in POIFS 50119 - avoid NPE when XSSFReader comes across chart sheets diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java b/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java index 9617d6836..dc1539a93 100644 --- a/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java +++ b/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java @@ -21,6 +21,9 @@ package org.apache.poi.poifs.filesystem; import java.io.File; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; + /** * Class POIFSDocumentPath * @@ -30,6 +33,8 @@ import java.io.File; public class POIFSDocumentPath { + private static final POILogger log = POILogFactory.getLogger(POIFSDocumentPath.class); + private String[] components; private int hashcode = 0; @@ -125,12 +130,17 @@ public class POIFSDocumentPath { for (int j = 0; j < components.length; j++) { - if ((components[ j ] == null) - || (components[ j ].length() == 0)) + if (components[ j ] == null) { throw new IllegalArgumentException( - "components cannot contain null or empty strings"); + "components cannot contain null"); } + if (components[ j ].length() == 0) + { + log.log(POILogger.WARN, "Directory under " + path + " has an empty name, " + + "not all OLE2 readers will handle this file correctly!"); + } + this.components[ j + path.components.length ] = components[ j ]; } diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java index b09c46945..fef200fdc 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSDocumentPath.java @@ -165,24 +165,40 @@ public final class TestPOIFSDocumentPath extends TestCase { } } - // test weird variants + // Test weird variants + + // This one is allowed, even if it's really odd assertEquals(n, new POIFSDocumentPath(base, null).length()); + new POIFSDocumentPath(base, new String[] + { + "fu", "" + }); + + // This one is allowed too + new POIFSDocumentPath(base, new String[] + { + "", "fu" + }); + + // This one shouldn't be allowed try { new POIFSDocumentPath(base, new String[] { - "fu", "" + "fu", null }); fail("should have caught IllegalArgumentException"); } catch (IllegalArgumentException ignored) { } + + // Ditto try { new POIFSDocumentPath(base, new String[] { - "fu", null + null, "fu" }); fail("should have caught IllegalArgumentException"); } diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java index 5ebc16894..ae9ac644a 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Iterator; import junit.framework.TestCase; @@ -226,6 +227,43 @@ public final class TestPOIFSFileSystem extends TestCase { } } } + + /** + * Test that we can open files that come via Lotus notes. + * These have a top level directory without a name.... + */ + public void testNotesOLE2Files() throws Exception { + POIDataSamples _samples = POIDataSamples.getPOIFSInstance(); + + // Open the file up + POIFSFileSystem fs = new POIFSFileSystem( + _samples.openResourceAsStream("Notes.ole2") + ); + + // Check the contents + assertEquals(1, fs.getRoot().getEntryCount()); + + Entry entry = fs.getRoot().getEntries().next(); + assertTrue(entry.isDirectoryEntry()); + assertTrue(entry instanceof DirectoryEntry); + + // The directory lacks a name! + DirectoryEntry dir = (DirectoryEntry)entry; + assertEquals("", dir.getName()); + + // Has two children + assertEquals(2, dir.getEntryCount()); + + // Check them + Iterator it = dir.getEntries(); + entry = it.next(); + assertEquals(true, entry.isDocumentEntry()); + assertEquals("\u0001Ole10Native", entry.getName()); + + entry = it.next(); + assertEquals(true, entry.isDocumentEntry()); + assertEquals("\u0001CompObj", entry.getName()); + } private static InputStream openSampleStream(String sampleFileName) { return HSSFTestDataSamples.openSampleFileStream(sampleFileName); diff --git a/test-data/poifs/Notes.ole2 b/test-data/poifs/Notes.ole2 new file mode 100644 index 000000000..9aaed99d3 Binary files /dev/null and b/test-data/poifs/Notes.ole2 differ