aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java34
-rw-r--r--poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java19
-rw-r--r--test-data/spreadsheet/notenoughstrings.txt13
3 files changed, 47 insertions, 19 deletions
diff --git a/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java b/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java
index b4c2d3cd73..d840078c73 100644
--- a/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java
+++ b/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java
@@ -29,13 +29,11 @@ import static org.apache.logging.log4j.util.Unbox.box;
/**
* Handles the task of deserializing a SST string. The two main entry points are
*/
-class SSTDeserializer
-{
+class SSTDeserializer {
private static final Logger LOG = LogManager.getLogger(SSTDeserializer.class);
private IntMapper<UnicodeString> strings;
- public SSTDeserializer( IntMapper<UnicodeString> strings )
- {
+ public SSTDeserializer(IntMapper<UnicodeString> strings) {
this.strings = strings;
}
@@ -44,23 +42,21 @@ class SSTDeserializer
* strings may span across multiple continuations. Read the SST record
* carefully before beginning to hack.
*/
- public void manufactureStrings( int stringCount, RecordInputStream in )
- {
- for (int i=0;i<stringCount;i++) {
- // Extract exactly the count of strings from the SST record.
- UnicodeString str;
- if (in.available() == 0 && !in.hasNextRecord()) {
- LOG.atError().log("Ran out of data before creating all the strings! String at index {}", box(i));
- str = new UnicodeString("");
- } else {
- str = new UnicodeString(in);
- }
- addToStringTable( strings, str );
- }
+ public void manufactureStrings(int stringCount, RecordInputStream in) {
+ for (int i = 0; i < stringCount; i++) {
+ // Extract exactly the count of strings from the SST record.
+ UnicodeString str;
+ if (in.available() == 0 && (!in.hasNextRecord() || in.getNextSid() != ContinueRecord.sid)) {
+ LOG.atError().log("Ran out of data before creating all the strings! String at index {}", box(i));
+ str = new UnicodeString("");
+ } else {
+ str = new UnicodeString(in);
+ }
+ addToStringTable(strings, str);
+ }
}
- static public void addToStringTable( IntMapper<UnicodeString> strings, UnicodeString string )
- {
+ static public void addToStringTable(IntMapper<UnicodeString> strings, UnicodeString string) {
strings.add(string);
}
}
diff --git a/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java b/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java
index 20057c42ac..c627bbfc55 100644
--- a/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java
+++ b/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java
@@ -120,4 +120,23 @@ final class TestSSTDeserializer {
assertEquals( "At a dinner party orAt At At ", strings.get( 0 ) + "" );
}
+
+ /**
+ * Ensure that invalid SST records with an incorrect number of strings specified, does not consume non-continuation records.
+ */
+ @Test
+ void test65543() throws IOException {
+ final byte[] sstRecord = readSampleHexData("notenoughstrings.txt", "sst-record", SSTRecord.sid);
+ byte[] nonContinuationRecord = readSampleHexData("notenoughstrings.txt", "non-continuation-record", ExtSSTRecord.sid);
+ RecordInputStream in = TestcaseRecordInputStream.create(concat(sstRecord, nonContinuationRecord));
+
+ IntMapper<UnicodeString> strings = new IntMapper<>();
+ SSTDeserializer deserializer = new SSTDeserializer(strings);
+
+ // The record data in notenoughstrings.txt only contains 1 string, deliberately pass in a larger number.
+ deserializer.manufactureStrings(2, in);
+
+ assertEquals("At a dinner party or", strings.get(0) + "");
+ assertEquals("", strings.get(1) + "");
+ }
}
diff --git a/test-data/spreadsheet/notenoughstrings.txt b/test-data/spreadsheet/notenoughstrings.txt
new file mode 100644
index 0000000000..3ecc2d3fda
--- /dev/null
+++ b/test-data/spreadsheet/notenoughstrings.txt
@@ -0,0 +1,13 @@
+[sst-record]
+14 00 # String length 0x14=20
+01 # Option flag, 16bit
+# String: At a dinner party or
+41 00 74 00 20 00 61 00 20 00
+64 00 69 00 6E 00 6E 00 65 00
+72 00 20 00 70 00 61 00 72 00
+74 00 79 00 20 00 6F 00 72 00
+
+# This is not a complete record
+# It only matters that the record type is not 0x003C
+[non-continuation-record]
+00 11 22 33