[bug-65543] HSSF: fix issue with incomplete SSTs. Thanks to Simon Carter.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1906434 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2023-01-06 23:50:54 +00:00
parent c8c06d1ec0
commit 968dabd462
3 changed files with 47 additions and 19 deletions

View File

@ -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);
}
}

View File

@ -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) + "");
}
}

View File

@ -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