mirror of https://github.com/apache/poi.git
[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:
parent
c8c06d1ec0
commit
968dabd462
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) + "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue