aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java5
-rw-r--r--poi-ooxml/src/test/java/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java39
2 files changed, 43 insertions, 1 deletions
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java
index 590251960a..bbdd30915c 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/eventusermodel/ReadOnlySharedStringsTable.java
@@ -248,7 +248,10 @@ public class ReadOnlySharedStringsTable extends DefaultHandler implements Shared
String uniqueCount = attributes.getValue("uniqueCount");
if(uniqueCount != null) this.uniqueCount = (int) Long.parseLong(uniqueCount);
- this.strings = new ArrayList<>(this.uniqueCount);
+ this.strings = new ArrayList<>(
+ // corrupted files may have a very large number here, so only use it
+ // up to some size as guideline for pre-allocating the list
+ Math.min(this.uniqueCount, 100_000));
characters = new StringBuilder(64);
} else if ("si".equals(localName)) {
if (characters != null) {
diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java
index 220963db79..4c7797695f 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/eventusermodel/TestReadOnlySharedStringsTable.java
@@ -20,10 +20,14 @@
package org.apache.poi.xssf.eventusermodel;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.regex.Pattern;
@@ -160,4 +164,39 @@ public final class TestReadOnlySharedStringsTable {
assertEquals(0, sst.getCount());
assertEquals(0, sst.getUniqueCount());
}
+
+ private static final String MINIMAL_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
+ "<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"55\" uniqueCount=\"49\">" +
+ "<si>" +
+ "<t>bla</t>" +
+ "<phoneticPr fontId=\"1\"/>" +
+ "</si>" +
+ "</sst>";
+
+ @Test
+ void testMinimalTable() throws IOException, SAXException {
+ ReadOnlySharedStringsTable tbl = new ReadOnlySharedStringsTable(
+ new ByteArrayInputStream(MINIMAL_XML.getBytes(StandardCharsets.UTF_8)));
+ assertNotNull(tbl);
+ assertEquals(49, tbl.getUniqueCount());
+ assertEquals(55, tbl.getCount());
+ assertTrue(tbl.includePhoneticRuns);
+ assertEquals("bla", tbl.getItemAt(0).getString());
+ assertThrows(IllegalStateException.class,
+ () -> tbl.getItemAt(1).getString());
+ }
+
+ @Test
+ void testHugeUniqueCount() throws IOException, SAXException {
+ ReadOnlySharedStringsTable tbl = new ReadOnlySharedStringsTable(
+ new ByteArrayInputStream(MINIMAL_XML.replace("49", "99999999999999999").
+ getBytes(StandardCharsets.UTF_8)));
+ assertNotNull(tbl);
+ assertEquals(1569325055, tbl.getUniqueCount());
+ assertEquals(55, tbl.getCount());
+ assertTrue(tbl.includePhoneticRuns);
+ assertEquals("bla", tbl.getItemAt(0).getString());
+ assertThrows(IllegalStateException.class,
+ () -> tbl.getItemAt(1).getString());
+ }
}