Author: fanningpj
Date: Fri Jan  6 23:50:54 2023
New Revision: 1906434

URL: http://svn.apache.org/viewvc?rev=1906434&view=rev
Log:
[bug-65543] HSSF: fix issue with incomplete SSTs. Thanks to Simon Carter.

Added:
    poi/trunk/test-data/spreadsheet/notenoughstrings.txt   (with props)
Modified:
    poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java
    
poi/trunk/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java

Modified: 
poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java?rev=1906434&r1=1906433&r2=1906434&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java 
(original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java 
Fri Jan  6 23:50:54 2023
@@ -29,13 +29,11 @@ import static org.apache.logging.log4j.u
 /**
  * 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);
     }
 }

Modified: 
poi/trunk/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java?rev=1906434&r1=1906433&r2=1906434&view=diff
==============================================================================
--- 
poi/trunk/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java 
(original)
+++ 
poi/trunk/poi/src/test/java/org/apache/poi/hssf/record/TestSSTDeserializer.java 
Fri Jan  6 23:50:54 2023
@@ -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) + "");
+    }
 }

Added: poi/trunk/test-data/spreadsheet/notenoughstrings.txt
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/notenoughstrings.txt?rev=1906434&view=auto
==============================================================================
--- poi/trunk/test-data/spreadsheet/notenoughstrings.txt (added)
+++ poi/trunk/test-data/spreadsheet/notenoughstrings.txt Fri Jan  6 23:50:54 
2023
@@ -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

Propchange: poi/trunk/test-data/spreadsheet/notenoughstrings.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: poi/trunk/test-data/spreadsheet/notenoughstrings.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to