Allow multiple instances of HeaderFooterRecord in CustomViewSettingsRecordAggregate similar to ChartSubstreamRecordAggreagte in order to read sample 49931.xls correctly after re-saving it with HSSFWorkbook

Improve error output


git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1697600 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2015-08-25 08:28:54 +00:00
parent 868f3209e3
commit 97fa448a2c
3 changed files with 88 additions and 5 deletions

View File

@ -50,7 +50,7 @@ public final class ChartSubstreamRecordAggregate extends RecordAggregate {
continue;
}
throw new IllegalStateException(
"Found more than one PageSettingsBlock in chart sub-stream");
"Found more than one PageSettingsBlock in chart sub-stream, had sid: " + rs.peekNextSid());
}
_psBlock = new PageSettingsBlock(rs);
temp.add(_psBlock);

View File

@ -47,10 +47,15 @@ public final class CustomViewSettingsRecordAggregate extends RecordAggregate {
List<RecordBase> temp = new ArrayList<RecordBase>();
while (rs.peekNextSid() != UserSViewEnd.sid) {
if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
if (_psBlock != null) {
throw new IllegalStateException(
"Found more than one PageSettingsBlock in custom view settings sub-stream");
}
if (_psBlock != null) {
if (rs.peekNextSid() == HeaderFooterRecord.sid) {
// test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls
_psBlock.addLateHeaderFooter((HeaderFooterRecord)rs.getNext());
continue;
}
throw new IllegalStateException(
"Found more than one PageSettingsBlock in chart sub-stream, had sid: " + rs.peekNextSid());
}
_psBlock = new PageSettingsBlock(rs);
temp.add(_psBlock);
continue;

View File

@ -380,4 +380,82 @@ public final class TestPageSettingsBlock extends TestCase {
assertArrayEquals(svb.getGuid(), hd2.getGuid());
}
public void testDuplicateHeaderFooterInside_bug48026() {
Record[] recs = {
BOFRecord.createSheetBOF(),
new IndexRecord(),
//PageSettingsBlock
new HeaderRecord("&LDecember"),
new FooterRecord("&LJanuary"),
new DimensionsRecord(),
new WindowTwoRecord(),
//CustomViewSettingsRecordAggregate
new UserSViewBegin(HexRead.readFromString("53 CE BD CC DE 38 44 45 97 C1 5C 89 F9 37 32 1B 01 00 00 00 64 00 00 00 40 00 00 00 03 00 00 00 7D 00 00 20 00 00 34 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF")),
new SelectionRecord(0, 0),
// two HeaderFooterRecord records, the first one has zero GUID (16 bytes at offset 12) and belongs to the PSB,
// the other is matched with a CustomViewSettingsRecordAggregate having UserSViewBegin with the same GUID
new HeaderFooterRecord(HexRead.readFromString("9C 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 34 33 00 00 00 00 00 00 00 00")),
new HeaderFooterRecord(HexRead.readFromString("9C 08 00 00 00 00 00 00 00 00 00 00 53 CE BD CC DE 38 44 45 97 C1 5C 89 F9 37 32 1B 34 33 00 00 00 00 00 00 00 00")),
new UserSViewEnd(HexRead.readFromString("01 00")),
EOFRecord.instance,
};
RecordStream rs = new RecordStream(Arrays.asList(recs), 0);
InternalSheet sheet;
try {
sheet = InternalSheet.createSheet(rs);
} catch (RuntimeException e) {
if (e.getMessage().equals("Duplicate PageSettingsBlock record (sid=0x89c)")) {
throw new AssertionFailedError("Identified bug 48026");
}
throw e;
}
RecordCollector rv = new RecordCollector();
sheet.visitContainedRecords(rv, 0);
Record[] outRecs = rv.getRecords();
assertEquals(recs.length+1, outRecs.length);
//expected order of records:
Record[] expectedRecs = {
recs[0], //BOFRecord
recs[1], //IndexRecord
//PageSettingsBlock
recs[2], //HeaderRecord
recs[3], //FooterRecord
recs[4], // DimensionsRecord
recs[5], // WindowTwoRecord
//CustomViewSettingsRecordAggregate
recs[6], // UserSViewBegin
recs[7], // SelectionRecord
recs[2], //HeaderRecord
recs[3], //FooterRecord
recs[8], // HeaderFooterRecord
// recs[9], //HeaderFooterRecord
recs[10], // UserSViewEnd
recs[11], //EOFRecord
};
for(int i=0; i < expectedRecs.length; i++){
assertEquals("Record mismatch at index " + i, expectedRecs[i].getClass(), outRecs[i].getClass());
}
HeaderFooterRecord hd1 = (HeaderFooterRecord)expectedRecs[10];
//GUID is zero
assertArrayEquals(new byte[16], hd1.getGuid());
assertTrue(hd1.isCurrentSheet());
UserSViewBegin svb = (UserSViewBegin)expectedRecs[6];
HeaderFooterRecord hd2 = (HeaderFooterRecord)recs[9];
assertFalse(hd2.isCurrentSheet());
//GUIDs of HeaderFooterRecord and UserSViewBegin must be the same
assertArrayEquals(svb.getGuid(), hd2.getGuid());
}
}