diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 76c0e8556..5ef12fb3a 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,7 +34,8 @@ - 48415 - improved javadoc on HSSPicture.resize() + 47215 - fixed InterfaceEndRecord to tolerate unexpected record contents + 48415 - improved javadoc on HSSPicture.resize() added Ant target to install artifacts in local repository 48026 - fixed PageSettingsBlock to allow multiple HeaderFooterRecord records 48202 - fixed CellRangeUtil.mergeCellRanges to work for adjacent cell regions diff --git a/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java b/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java index 620d580f6..865906040 100644 --- a/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java +++ b/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java @@ -18,6 +18,9 @@ package org.apache.poi.hssf.record; import org.apache.poi.util.LittleEndianOutput; +import org.apache.poi.util.HexDump; +import org.apache.poi.util.POILogger; +import org.apache.poi.util.POILogFactory; /** * Title: Interface End Record (0x00E2)

@@ -28,17 +31,23 @@ import org.apache.poi.util.LittleEndianOutput; * @version 2.0-pre */ public final class InterfaceEndRecord extends StandardRecord { + private static POILogger logger = POILogFactory.getLogger(InterfaceEndRecord.class); + public final static short sid = 0x00E2; + private byte[] _unknownData; + public InterfaceEndRecord() { } - /** - * @param in unused (since this record has no data) - */ public InterfaceEndRecord(RecordInputStream in) { + if(in.available() > 0){ + _unknownData = in.readRemainder(); + logger.log(POILogger.WARN, "encountered unexpected " + + _unknownData.length + " bytes in InterfaceEndRecord"); + } } public String toString() @@ -46,15 +55,19 @@ public final class InterfaceEndRecord extends StandardRecord { StringBuffer buffer = new StringBuffer(); buffer.append("[INTERFACEEND]\n"); + buffer.append(" unknownData=").append(HexDump.toHex(_unknownData)).append("\n"); buffer.append("[/INTERFACEEND]\n"); return buffer.toString(); } public void serialize(LittleEndianOutput out) { + if(_unknownData != null) out.write(_unknownData); } protected int getDataSize() { - return 0; + int size = 0; + if(_unknownData != null) size += _unknownData.length; + return size; } public short getSid() diff --git a/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java b/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java new file mode 100644 index 000000000..9de79b3fd --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java @@ -0,0 +1,56 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record; + + +import junit.framework.TestCase; +import org.apache.poi.util.HexRead; +import org.apache.poi.util.HexDump; +import java.util.List; +import java.io.ByteArrayInputStream; + +/** + * Tests the serialization and deserialization of the EndSubRecord + * class works correctly. Test data taken directly from a real + * Excel file. + * + * @author Yegor Kozlov + */ +public final class TestInterfaceEndRecord extends TestCase { + + public void testCreate() { + InterfaceEndRecord record = new InterfaceEndRecord(); + assertEquals(0, record.getDataSize()); + } + + /** + * Silently swallow unexpected contents in InterfaceEndRecord. + * Although it violates the spec, Excel silently reads such files. + */ + public void testUnexpectedBytes_bug47251(){ + String hex = "" + + "09 08 10 00 00 06 05 00 EC 15 CD 07 C1 C0 00 00 06 03 00 00 " + //BOF + "E2 00 02 00 B0 04 " + //INTERFACEEND with extra two bytes + "0A 00 00 00"; // EOF + byte[] data = HexRead.readFromString(hex); + List records = RecordFactory.createRecords(new ByteArrayInputStream(data)); + assertEquals(3, records.size()); + InterfaceEndRecord r = (InterfaceEndRecord)records.get(1); + assertEquals("[E2, 00, 02, 00, B0, 04]", HexDump.toHex(r.serialize())); + } +} \ No newline at end of file diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 5b2d69af7..df3f23488 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -1533,4 +1533,8 @@ public final class TestBugs extends BaseTestBugzillaIssues { public void test48026() { openSample("48026.xls"); } + + public void test47251() { + openSample("47251.xls"); + } } diff --git a/test-data/spreadsheet/47251.xls b/test-data/spreadsheet/47251.xls new file mode 100644 index 000000000..e498c2be0 Binary files /dev/null and b/test-data/spreadsheet/47251.xls differ