]> source.dussan.org Git - poi.git/commitdiff
Bugzilla 48096 - relaxed validation check in RecalcIdRecord
authorJosh Micich <josh@apache.org>
Tue, 3 Nov 2009 20:23:21 +0000 (20:23 +0000)
committerJosh Micich <josh@apache.org>
Tue, 3 Nov 2009 20:23:21 +0000 (20:23 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@832536 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/RecalcIdRecord.java
src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
src/testcases/org/apache/poi/hssf/record/TestRecalcIdRecord.java [new file with mode: 0644]

index bd533988e6c150fc4f8003ae049facf1144aaa36..0cd747f15d7fb1594e9e8542879aa748c5efc788 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.6-beta1" date="2009-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">48096 - relaxed validation check in RecalcIdRecord</action>
            <action dev="POI-DEVELOPERS" type="fix">48085 - improved error checking in BlockAllocationTableReader to trap unreasonable field values</action>
            <action dev="POI-DEVELOPERS" type="fix">47924 - fixed logic for matching cells and comments in HSSFCell.getCellComment()</action>
            <action dev="POI-DEVELOPERS" type="add">47942 - added implementation of protection features to XLSX and DOCX files</action>
index 7b416a909aecc3e3ed072f5d6f8119e2bd67041e..c336e14d30777c34802aa9e1e34bfebde3c5c460 100644 (file)
@@ -25,11 +25,8 @@ import org.apache.poi.util.LittleEndianOutput;
  * Description:  This record contains an ID that marks when a worksheet was last
  *               recalculated. It's an optimization Excel uses to determine if it
  *               needs to  recalculate the spreadsheet when it's opened. So far, only
- *               the two values <code>0xC1 0x01 0x00 0x00 0x80 0x38 0x01 0x00</code>
- *               (do not recalculate) and <code>0xC1 0x01 0x00 0x00 0x60 0x69 0x01
- *               0x00</code> have been seen. If the field <code>isNeeded</code> is
- *               set to false (default), then this record is swallowed during the
- *               serialization process<p/>
+ *               the two engine ids <code>0x80 0x38 0x01 0x00</code> 
+ *               and <code>0x60 0x69 0x01 0x00</code> have been seen.<p/>
  * REFERENCE:  http://chicago.sourceforge.net/devel/docs/excel/biff8.html<p/>
  * @author Luc Girardin (luc dot girardin at macrofocus dot com)
  *
@@ -41,10 +38,7 @@ public final class RecalcIdRecord extends StandardRecord {
     private final int _engineId;
 
     public RecalcIdRecord(RecordInputStream in) {
-       int rt = in.readUShort();
-       if (rt != sid) {
-               throw new RecordFormatException("expected " + sid + " but got " + rt);
-       }
+       in.readUShort(); // field 'rt' should have value 0x01C1, but Excel doesn't care during reading
        _reserved0 = in.readUShort();
        _engineId = in.readInt();
     }
@@ -64,7 +58,7 @@ public final class RecalcIdRecord extends StandardRecord {
     }
 
     public void serialize(LittleEndianOutput out) {
-        out.writeShort(sid);
+        out.writeShort(sid); // always write 'rt' field as 0x01C1
         out.writeShort(_reserved0);
         out.writeInt(_engineId);
     }
index 920cfe7142323f66250765679fb10d8a3517a381..adb249ef34e99471078bc0596bbe8a239bec840a 100644 (file)
@@ -69,6 +69,7 @@ public final class AllRecordTests {
                result.addTestSuite(TestObjRecord.class);
                result.addTestSuite(TestPaletteRecord.class);
                result.addTestSuite(TestPaneRecord.class);
+               result.addTestSuite(TestRecalcIdRecord.class);
                result.addTestSuite(TestRecordFactory.class);
                result.addTestSuite(TestRecordFactoryInputStream.class);
                result.addTestSuite(TestRecordInputStream.class);
diff --git a/src/testcases/org/apache/poi/hssf/record/TestRecalcIdRecord.java b/src/testcases/org/apache/poi/hssf/record/TestRecalcIdRecord.java
new file mode 100644 (file)
index 0000000..9ac03d2
--- /dev/null
@@ -0,0 +1,72 @@
+/* ====================================================================
+   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 java.util.Arrays;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.util.HexRead;
+/**
+ *
+ * @author Josh Micich
+ */
+public final class TestRecalcIdRecord extends TestCase {
+
+       private static RecalcIdRecord create(byte[] data) {
+               RecordInputStream in = TestcaseRecordInputStream.create(RecalcIdRecord.sid, data);
+               RecalcIdRecord result = new RecalcIdRecord(in);
+               assertEquals(0, in.remaining());
+               return result;
+       }
+       public void testBasicDeserializeReserialize() {
+               
+               byte[] data = HexRead.readFromString(
+                               "C1 01" +  // rt
+                               "00 00" +  // reserved
+                               "1D EB 01 00"); // engine id
+
+               RecalcIdRecord r = create(data);
+               TestcaseRecordInputStream.confirmRecordEncoding(RecalcIdRecord.sid, data, r.serialize());
+       }
+
+       public void testBadFirstField_bug48096() {
+               /**
+                * Data taken from the sample file referenced in Bugzilla 48096, file offset 0x0D45.
+                * The apparent problem is that the first data short field has been written with the
+                * wrong <i>endianness</n>.  Excel seems to ignore whatever value is present in this
+                * field, and always rewrites it as (C1, 01). POI now does the same.
+                */
+               byte[] badData  = HexRead.readFromString("C1 01 08 00 01 C1 00 00 00 01 69 61");
+               byte[] goodData = HexRead.readFromString("C1 01 08 00 C1 01 00 00 00 01 69 61");
+
+               RecordInputStream in = TestcaseRecordInputStream.create(badData);
+               RecalcIdRecord r;
+               try {
+                       r = new RecalcIdRecord(in);
+               } catch (RecordFormatException e) {
+                       if (e.getMessage().equals("expected 449 but got 49409")) {
+                               throw new AssertionFailedError("Identified bug 48096");
+                       }
+                       throw e;
+               }
+               assertEquals(0, in.remaining());
+               assertTrue(Arrays.equals(r.serialize(), goodData));
+       }
+}