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)