You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by av...@apache.org on 2003/03/07 16:49:04 UTC
cvs commit: jakarta-poi/src/testcases/org/apache/poi/hssf/record TestRecordFactory.java
avik 2003/03/07 07:49:04
Modified: src/java/org/apache/poi/hssf/eventmodel
EventRecordFactory.java
src/java/org/apache/poi/hssf/record ContinueRecord.java
RecordFactory.java
src/testcases/org/apache/poi/hssf/eventmodel
TestEventRecordFactory.java
src/testcases/org/apache/poi/hssf/record
TestRecordFactory.java
Log:
Fixed bug 17373 - incorrect handling of continue records after unknown records corrupting a template. Patch submitted by Csaba Nagy -- thanks
Revision Changes Path
1.3 +4 -4 jakarta-poi/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java
Index: EventRecordFactory.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- EventRecordFactory.java 23 Nov 2002 18:58:17 -0000 1.2
+++ EventRecordFactory.java 7 Mar 2003 15:49:03 -0000 1.3
@@ -89,7 +89,6 @@
import org.apache.poi.hssf.record.FontRecord;
import org.apache.poi.hssf.record.FooterRecord;
import org.apache.poi.hssf.record.FormatRecord;
-import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.GridsetRecord;
import org.apache.poi.hssf.record.GutsRecord;
import org.apache.poi.hssf.record.HCenterRecord;
@@ -151,6 +150,7 @@
* @author Andrew C. Oliver (acoliver@apache.org) - probably to blame for the bugs (so yank his chain on the list)
* @author Marc Johnson (mjohnson at apache dot org) - methods taken from RecordFactory
* @author Glen Stampoultzis (glens at apache.org) - methods taken from RecordFactory
+ * @author Csaba Nagy (ncsaba at yahoo dot com)
*/
public class EventRecordFactory
{
@@ -289,8 +289,6 @@
* @param in the InputStream from which the records will be
* obtained
*
- * @return an array of Records created from the InputStream
- *
* @exception RecordFormatException on error processing the
* InputStream
*/
@@ -337,7 +335,9 @@
if (record != null)
{
- if (rectype == ContinueRecord.sid)
+ if (rectype == ContinueRecord.sid &&
+ ! (last_record instanceof ContinueRecord) && // include continuation records after
+ ! (last_record instanceof UnknownRecord) ) // unknown records or previous continuation records
{
if (last_record == null)
{
1.4 +10 -7 jakarta-poi/src/java/org/apache/poi/hssf/record/ContinueRecord.java
Index: ContinueRecord.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/ContinueRecord.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ContinueRecord.java 2 Jun 2002 07:30:40 -0000 1.3
+++ ContinueRecord.java 7 Mar 2003 15:49:03 -0000 1.4
@@ -65,6 +65,7 @@
* stream; content is tailored to that prior record<P>
* @author Marc Johnson (mjohnson at apache dot org)
* @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Csaba Nagy (ncsaba at yahoo dot com)
* @version 2.0-pre
*/
@@ -116,17 +117,19 @@
public byte [] serialize()
{
byte[] retval = new byte[ field_1_data.length + 4 ];
-
- LittleEndian.putShort(retval, 0, sid);
- LittleEndian.putShort(retval, 2, ( short ) field_1_data.length);
- System.arraycopy(field_1_data, 0, retval, 4, field_1_data.length);
+ serialize(0, retval);
return retval;
}
public int serialize(int offset, byte [] data)
{
- throw new RecordFormatException(
- "You're not supposed to serialize Continue records like this directly");
+
+ LittleEndian.putShort(data, offset, sid);
+ LittleEndian.putShort(data, offset + 2, ( short ) field_1_data.length);
+ System.arraycopy(field_1_data, 0, data, offset + 4, field_1_data.length);
+ return field_1_data.length + 4;
+ // throw new RecordFormatException(
+ // "You're not supposed to serialize Continue records like this directly");
}
/**
@@ -212,7 +215,7 @@
protected void fillFields(byte [] ignored_parm1, short ignored_parm2)
{
-
+ this.field_1_data = ignored_parm1;
// throw new RecordFormatException("Are you crazy? Don't fill a continue record");
// do nothing
}
1.14 +5 -2 jakarta-poi/src/java/org/apache/poi/hssf/record/RecordFactory.java
Index: RecordFactory.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/RecordFactory.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- RecordFactory.java 28 Nov 2002 19:20:36 -0000 1.13
+++ RecordFactory.java 7 Mar 2003 15:49:03 -0000 1.14
@@ -69,10 +69,11 @@
* Description: Takes a stream and outputs an array of Record objects.<P>
*
* @deprecated use EventRecordFactory instead
- * @see org.apache.poi.hssf.record.EventRecordFactory
+ * @see org.apache.poi.hssf.eventmodel.EventRecordFactory
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Marc Johnson (mjohnson at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
+ * @author Csaba Nagy (ncsaba at yahoo dot com)
* @version 1.0-pre
*/
@@ -208,7 +209,9 @@
if (record != null)
{
- if (rectype == ContinueRecord.sid)
+ if (rectype == ContinueRecord.sid &&
+ ! (last_record instanceof ContinueRecord) && // include continuation records after
+ ! (last_record instanceof UnknownRecord) ) // unknown records or previous continuation records
{
if (last_record == null)
{
1.2 +59 -0 jakarta-poi/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java
Index: TestEventRecordFactory.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestEventRecordFactory.java 11 Nov 2002 01:34:00 -0000 1.1
+++ TestEventRecordFactory.java 7 Mar 2003 15:49:04 -0000 1.2
@@ -3,10 +3,13 @@
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.util.Iterator;
+import java.util.Arrays;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.UnknownRecord;
+import org.apache.poi.hssf.record.ContinueRecord;
import junit.framework.TestCase;
@@ -14,6 +17,7 @@
* enclosing_type describe the purpose here
*
* @author Andrew C. Oliver acoliver@apache.org
+ * @author Csaba Nagy (ncsaba at yahoo dot com)
*/
public class TestEventRecordFactory extends TestCase
{
@@ -173,4 +177,59 @@
// fail("not implemented");
}
+
+ /**
+ * TEST NAME: Test Creating ContinueRecords After Unknown Records From An InputStream <P>
+ * OBJECTIVE: Test that the RecordFactory given an InputStream
+ * constructs the expected records.<P>
+ * SUCCESS: Record factory creates the expected records.<P>
+ * FAILURE: The wrong records are created or contain the wrong values <P>
+ *
+ */
+ public void testContinuedUnknownRecord()
+ {
+ final byte[] data = new byte[]
+ {
+ 0, -1, 0, 0, // an unknown record with 0 length
+ 0x3C , 0, 3, 0, 1, 2, 3, // a continuation record with 3 bytes of data
+ 0x3C , 0, 1, 0, 4 // one more continuation record with 1 byte of data
+ };
+
+ final int[] recCnt = { 0 };
+ final int[] offset = { 0 };
+ factory.registerListener(
+ new ERFListener() {
+ private String[] expectedRecordTypes = {
+ UnknownRecord.class.getName(),
+ ContinueRecord.class.getName(),
+ ContinueRecord.class.getName()
+ };
+ public boolean processRecord(Record rec)
+ {
+ // System.out.println(rec.toString());
+ assertEquals(
+ "Record type",
+ expectedRecordTypes[recCnt[0]],
+ rec.getClass().getName()
+ );
+ compareData(rec, "Record " + recCnt[0] + ": ");
+ recCnt[0]++;
+ return true;
+ }
+ private void compareData(Record record, String message) {
+ byte[] recData = record.serialize();
+ for (int i = 0; i < recData.length; i++) {
+ assertEquals(message + " data byte " + i, data[offset[0]++], recData[i]);
+ }
+ }
+ },
+ new short[] {-256, 0x3C}
+ );
+
+ factory.processRecords(new ByteArrayInputStream(data));
+ assertEquals("nr. of processed records", 3, recCnt[0]);
+ assertEquals("nr. of processed bytes", data.length, offset[0]);
+ }
+
+
}
1.3 +44 -0 jakarta-poi/src/testcases/org/apache/poi/hssf/record/TestRecordFactory.java
Index: TestRecordFactory.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/testcases/org/apache/poi/hssf/record/TestRecordFactory.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestRecordFactory.java 11 Feb 2002 04:23:10 -0000 1.2
+++ TestRecordFactory.java 7 Mar 2003 15:49:04 -0000 1.3
@@ -55,12 +55,15 @@
package org.apache.poi.hssf.record;
+import java.io.ByteArrayInputStream;
+
import junit.framework.TestCase;
/**
* Tests the record factory
* @author Glen Stampoultzis (glens at apache.org)
* @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Csaba Nagy (ncsaba at yahoo dot com)
*/
public class TestRecordFactory
@@ -156,6 +159,47 @@
assertEquals(515, numberRecord.getSid());
assertEquals(0.0, numberRecord.getValue(), 0.001);
assertEquals(21, numberRecord.getXFIndex());
+ }
+
+ /**
+ * TEST NAME: Test Creating ContinueRecords After Unknown Records From An InputStream <P>
+ * OBJECTIVE: Test that the RecordFactory given an InputStream
+ * constructs the expected array of records.<P>
+ * SUCCESS: Record factory creates the expected records.<P>
+ * FAILURE: The wrong records are created or contain the wrong values <P>
+ *
+ */
+ public void testContinuedUnknownRecord()
+ {
+ byte[] data = new byte[]
+ {
+ 0, -1, 0, 0, // an unknown record with 0 length
+ 0x3C , 0, 3, 0, 1, 2, 3, // a continuation record with 3 bytes of data
+ 0x3C , 0, 1, 0, 4 // one more continuation record with 1 byte of data
+ };
+
+ ByteArrayInputStream bois = new ByteArrayInputStream(data);
+ Record[] records = (Record[])
+ RecordFactory.createRecords(bois).toArray(new Record[0]);
+ assertEquals("Created record count", 3, records.length);
+ assertEquals("1st record's type",
+ UnknownRecord.class.getName(),
+ records[ 0 ].getClass().getName());
+ assertEquals("1st record's sid", (short)-256, records[0].getSid());
+ assertEquals("2nd record's type",
+ ContinueRecord.class.getName(),
+ records[ 1 ].getClass().getName());
+ ContinueRecord record = (ContinueRecord) records[1];
+ assertEquals("2nd record's sid", 0x3C, record.getSid());
+ assertEquals("1st data byte", 1, record.getData()[ 0 ]);
+ assertEquals("2nd data byte", 2, record.getData()[ 1 ]);
+ assertEquals("3rd data byte", 3, record.getData()[ 2 ]);
+ assertEquals("3rd record's type",
+ ContinueRecord.class.getName(),
+ records[ 2 ].getClass().getName());
+ record = (ContinueRecord) records[2];
+ assertEquals("3nd record's sid", 0x3C, record.getSid());
+ assertEquals("4th data byte", 4, record.getData()[ 0 ]);
}
public static void main(String [] ignored_args)