Bug 46953 - fixed PageSettingsBlock parsing logic in Sheet. Bug caused sheet EOFs to get misplaced.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@773412 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
636c0ed54e
commit
e2793ef74b
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
<!-- Don't forget to update status.xml too! -->
|
<!-- Don't forget to update status.xml too! -->
|
||||||
<release version="3.5-beta6" date="2009-??-??">
|
<release version="3.5-beta6" date="2009-??-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">46953 - More tweaks to PageSettingsBlock parsing logic in Sheet constructor</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">47089 - Fixed XSSFWorkbook.createSheet to properly increment sheetId</action>
|
<action dev="POI-DEVELOPERS" type="fix">47089 - Fixed XSSFWorkbook.createSheet to properly increment sheetId</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">46568 - Fixed XSLFPowerPointExtractor to properly process line breaks</action>
|
<action dev="POI-DEVELOPERS" type="fix">46568 - Fixed XSLFPowerPointExtractor to properly process line breaks</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">39056 - Fixed POIFSFileSystem to set CLSID of root when constructing instances from InputStream</action>
|
<action dev="POI-DEVELOPERS" type="fix">39056 - Fixed POIFSFileSystem to set CLSID of root when constructing instances from InputStream</action>
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
<!-- Don't forget to update changes.xml too! -->
|
<!-- Don't forget to update changes.xml too! -->
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.5-beta6" date="2009-??-??">
|
<release version="3.5-beta6" date="2009-??-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">46953 - More tweaks to PageSettingsBlock parsing logic in Sheet constructor</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">47089 - Fixed XSSFWorkbook.createSheet to properly increment sheetId</action>
|
<action dev="POI-DEVELOPERS" type="fix">47089 - Fixed XSSFWorkbook.createSheet to properly increment sheetId</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">46568 - Fixed XSLFPowerPointExtractor to properly process line breaks</action>
|
<action dev="POI-DEVELOPERS" type="fix">46568 - Fixed XSLFPowerPointExtractor to properly process line breaks</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">39056 - Fixed POIFSFileSystem to set CLSID of root when constructing instances from InputStream</action>
|
<action dev="POI-DEVELOPERS" type="fix">39056 - Fixed POIFSFileSystem to set CLSID of root when constructing instances from InputStream</action>
|
||||||
|
@ -50,6 +50,7 @@ import org.apache.poi.hssf.record.PrintHeadersRecord;
|
|||||||
import org.apache.poi.hssf.record.ProtectRecord;
|
import org.apache.poi.hssf.record.ProtectRecord;
|
||||||
import org.apache.poi.hssf.record.Record;
|
import org.apache.poi.hssf.record.Record;
|
||||||
import org.apache.poi.hssf.record.RecordBase;
|
import org.apache.poi.hssf.record.RecordBase;
|
||||||
|
import org.apache.poi.hssf.record.RecordFormatException;
|
||||||
import org.apache.poi.hssf.record.RefModeRecord;
|
import org.apache.poi.hssf.record.RefModeRecord;
|
||||||
import org.apache.poi.hssf.record.RowRecord;
|
import org.apache.poi.hssf.record.RowRecord;
|
||||||
import org.apache.poi.hssf.record.SCLRecord;
|
import org.apache.poi.hssf.record.SCLRecord;
|
||||||
@ -210,11 +211,15 @@ public final class Sheet implements Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PageSettingsBlock.isComponentRecord(recSid)) {
|
if (PageSettingsBlock.isComponentRecord(recSid)) {
|
||||||
PageSettingsBlock psb = new PageSettingsBlock(rs);
|
PageSettingsBlock psb;
|
||||||
if (_psBlock == null) {
|
if (_psBlock == null) {
|
||||||
|
psb = new PageSettingsBlock(rs);
|
||||||
_psBlock = psb;
|
_psBlock = psb;
|
||||||
} else {
|
records.add(psb);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (bofEofNestingLevel == 2) {
|
if (bofEofNestingLevel == 2) {
|
||||||
|
psb = new PageSettingsBlock(rs);
|
||||||
// It's normal for a chart to have its own PageSettingsBlock
|
// It's normal for a chart to have its own PageSettingsBlock
|
||||||
// Fall through and add psb here, because chart records
|
// Fall through and add psb here, because chart records
|
||||||
// are stored loose among the sheet records.
|
// are stored loose among the sheet records.
|
||||||
@ -227,11 +232,15 @@ public final class Sheet implements Model {
|
|||||||
// Also several times in bugzilla samples 46840-23373 and 46840-23374
|
// Also several times in bugzilla samples 46840-23373 and 46840-23374
|
||||||
if (recSid == UnknownRecord.HEADER_FOOTER_089C) {
|
if (recSid == UnknownRecord.HEADER_FOOTER_089C) {
|
||||||
_psBlock.addLateHeaderFooter(rs.getNext());
|
_psBlock.addLateHeaderFooter(rs.getNext());
|
||||||
} else if (rs.peekNextSid() != UnknownRecord.USERSVIEWEND_01AB) {
|
continue;
|
||||||
|
}
|
||||||
|
psb = new PageSettingsBlock(rs);
|
||||||
|
if (rs.peekNextSid() != UnknownRecord.USERSVIEWEND_01AB) {
|
||||||
// not quite the expected situation
|
// not quite the expected situation
|
||||||
throw new RuntimeException("two Page Settings Blocks found in the same sheet");
|
throw new RuntimeException("two Page Settings Blocks found in the same sheet");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
psb = new PageSettingsBlock(rs);
|
||||||
// Some apps write PLS, WSBOOL, <psb> but PLS is part of <psb>
|
// Some apps write PLS, WSBOOL, <psb> but PLS is part of <psb>
|
||||||
// This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"
|
// This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"
|
||||||
// In this case the first PSB is two records back
|
// In this case the first PSB is two records back
|
||||||
@ -244,7 +253,6 @@ public final class Sheet implements Model {
|
|||||||
psb = mergePSBs(_psBlock, psb);
|
psb = mergePSBs(_psBlock, psb);
|
||||||
_psBlock = psb;
|
_psBlock = psb;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
records.add(psb);
|
records.add(psb);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -274,6 +282,11 @@ public final class Sheet implements Model {
|
|||||||
bofEofNestingLevel++;
|
bofEofNestingLevel++;
|
||||||
if (log.check( POILogger.DEBUG ))
|
if (log.check( POILogger.DEBUG ))
|
||||||
log.log(POILogger.DEBUG, "Hit BOF record. Nesting increased to " + bofEofNestingLevel);
|
log.log(POILogger.DEBUG, "Hit BOF record. Nesting increased to " + bofEofNestingLevel);
|
||||||
|
BOFRecord bof = (BOFRecord)rec;
|
||||||
|
// TODO - extract chart sub-stream into record aggregate
|
||||||
|
if (bof.getType() != BOFRecord.TYPE_CHART) {
|
||||||
|
throw new RecordFormatException("Bad BOF record type: " + bof.getType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (recSid == EOFRecord.sid)
|
else if (recSid == EOFRecord.sid)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,7 @@ import org.apache.poi.hssf.record.Margin;
|
|||||||
import org.apache.poi.hssf.record.PageBreakRecord;
|
import org.apache.poi.hssf.record.PageBreakRecord;
|
||||||
import org.apache.poi.hssf.record.PrintSetupRecord;
|
import org.apache.poi.hssf.record.PrintSetupRecord;
|
||||||
import org.apache.poi.hssf.record.Record;
|
import org.apache.poi.hssf.record.Record;
|
||||||
|
import org.apache.poi.hssf.record.RecordFormatException;
|
||||||
import org.apache.poi.hssf.record.RightMarginRecord;
|
import org.apache.poi.hssf.record.RightMarginRecord;
|
||||||
import org.apache.poi.hssf.record.TopMarginRecord;
|
import org.apache.poi.hssf.record.TopMarginRecord;
|
||||||
import org.apache.poi.hssf.record.UnknownRecord;
|
import org.apache.poi.hssf.record.UnknownRecord;
|
||||||
@ -539,6 +540,9 @@ public final class PageSettingsBlock extends RecordAggregate {
|
|||||||
if (_headerFooter != null) {
|
if (_headerFooter != null) {
|
||||||
throw new IllegalStateException("This page settings block already has a header/footer record");
|
throw new IllegalStateException("This page settings block already has a header/footer record");
|
||||||
}
|
}
|
||||||
|
if (rec.getSid() != UnknownRecord.HEADER_FOOTER_089C) {
|
||||||
|
throw new RecordFormatException("Unexpected header-footer record sid: 0x" + Integer.toHexString(rec.getSid()));
|
||||||
|
}
|
||||||
_headerFooter = rec;
|
_headerFooter = rec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public final class AllRecordAggregateTests {
|
|||||||
result.addTestSuite(TestRowRecordsAggregate.class);
|
result.addTestSuite(TestRowRecordsAggregate.class);
|
||||||
result.addTestSuite(TestSharedValueManager.class);
|
result.addTestSuite(TestSharedValueManager.class);
|
||||||
result.addTestSuite(TestValueRecordsAggregate.class);
|
result.addTestSuite(TestValueRecordsAggregate.class);
|
||||||
result.addTestSuite(TestPageSettingBlock.class);
|
result.addTestSuite(TestPageSettingsBlock.class);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import org.apache.poi.hssf.record.DimensionsRecord;
|
|||||||
import org.apache.poi.hssf.record.EOFRecord;
|
import org.apache.poi.hssf.record.EOFRecord;
|
||||||
import org.apache.poi.hssf.record.FooterRecord;
|
import org.apache.poi.hssf.record.FooterRecord;
|
||||||
import org.apache.poi.hssf.record.HeaderRecord;
|
import org.apache.poi.hssf.record.HeaderRecord;
|
||||||
|
import org.apache.poi.hssf.record.IndexRecord;
|
||||||
import org.apache.poi.hssf.record.NumberRecord;
|
import org.apache.poi.hssf.record.NumberRecord;
|
||||||
import org.apache.poi.hssf.record.Record;
|
import org.apache.poi.hssf.record.Record;
|
||||||
import org.apache.poi.hssf.record.UnknownRecord;
|
import org.apache.poi.hssf.record.UnknownRecord;
|
||||||
@ -45,7 +46,7 @@ import org.apache.poi.util.HexRead;
|
|||||||
*
|
*
|
||||||
* @author Dmitriy Kumshayev
|
* @author Dmitriy Kumshayev
|
||||||
*/
|
*/
|
||||||
public final class TestPageSettingBlock extends TestCase {
|
public final class TestPageSettingsBlock extends TestCase {
|
||||||
|
|
||||||
public void testPrintSetup_bug46548() {
|
public void testPrintSetup_bug46548() {
|
||||||
|
|
||||||
@ -109,6 +110,48 @@ public final class TestPageSettingBlock extends TestCase {
|
|||||||
assertEquals(13, outRecs.length);
|
assertEquals(13, outRecs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bug 46953 occurred because POI didn't handle late PSB records properly.
|
||||||
|
*/
|
||||||
|
public void testLateHeaderFooter_bug46953() {
|
||||||
|
|
||||||
|
int rowIx = 5;
|
||||||
|
int colIx = 6;
|
||||||
|
NumberRecord nr = new NumberRecord();
|
||||||
|
nr.setRow(rowIx);
|
||||||
|
nr.setColumn((short) colIx);
|
||||||
|
nr.setValue(3.0);
|
||||||
|
|
||||||
|
Record[] recs = {
|
||||||
|
BOFRecord.createSheetBOF(),
|
||||||
|
new HeaderRecord("&LSales Figures"),
|
||||||
|
new FooterRecord("&LJanuary"),
|
||||||
|
new DimensionsRecord(),
|
||||||
|
new WindowTwoRecord(),
|
||||||
|
ur(UnknownRecord.HEADER_FOOTER_089C, "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 C4 60 00 00 00 00 00 00 00 00"),
|
||||||
|
EOFRecord.instance,
|
||||||
|
};
|
||||||
|
RecordStream rs = new RecordStream(Arrays.asList(recs), 0);
|
||||||
|
Sheet sheet = Sheet.createSheet(rs);
|
||||||
|
|
||||||
|
RecordCollector rv = new RecordCollector();
|
||||||
|
sheet.visitContainedRecords(rv, rowIx);
|
||||||
|
Record[] outRecs = rv.getRecords();
|
||||||
|
if (outRecs[4] == EOFRecord.instance) {
|
||||||
|
throw new AssertionFailedError("Identified bug 46953 - EOF incorrectly appended to PSB");
|
||||||
|
}
|
||||||
|
assertEquals(recs.length+1, outRecs.length); // +1 for index record
|
||||||
|
|
||||||
|
assertEquals(BOFRecord.class, outRecs[0].getClass());
|
||||||
|
assertEquals(IndexRecord.class, outRecs[1].getClass());
|
||||||
|
assertEquals(HeaderRecord.class, outRecs[2].getClass());
|
||||||
|
assertEquals(FooterRecord.class, outRecs[3].getClass());
|
||||||
|
assertEquals(UnknownRecord.HEADER_FOOTER_089C, outRecs[4].getSid());
|
||||||
|
assertEquals(DimensionsRecord.class, outRecs[5].getClass());
|
||||||
|
assertEquals(WindowTwoRecord.class, outRecs[6].getClass());
|
||||||
|
assertEquals(EOFRecord.instance, outRecs[7]);
|
||||||
|
}
|
||||||
|
|
||||||
private static UnknownRecord ur(int sid, String hexData) {
|
private static UnknownRecord ur(int sid, String hexData) {
|
||||||
return new UnknownRecord(sid, HexRead.readFromString(hexData));
|
return new UnknownRecord(sid, HexRead.readFromString(hexData));
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user