Fix for bug 39800 - if the Array size in the simple block doesn't inclde the size of the header, make a note of this, and do the same when we write back out

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@413933 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2006-06-13 16:59:34 +00:00
parent 59ff1beb2b
commit afcd99d736
2 changed files with 69 additions and 23 deletions

View File

@ -32,7 +32,17 @@ import java.io.IOException;
public class EscherArrayProperty
extends EscherComplexProperty
{
/**
* The size of the header that goes at the
* start of the array, before the data
*/
private static final int FIXED_SIZE = 3 * 2;
/**
* Normally, the size recorded in the simple data (for the complex
* data) includes the size of the header.
* There are a few cases when it doesn't though...
*/
private boolean sizeIncludesHeaderSize = true;
public EscherArrayProperty( short id, byte[] complexData )
{
@ -158,12 +168,32 @@ public class EscherArrayProperty
short sizeOfElements = LittleEndian.getShort(data, offset + 4);
int arraySize = getActualSizeOfElements(sizeOfElements) * numElements;
if (arraySize == complexData.length)
complexData = new byte[arraySize + 6]; // Calculation missing the header for some reason
if (arraySize == complexData.length) {
// The stored data size in the simple block excludes the header size
complexData = new byte[arraySize + 6];
sizeIncludesHeaderSize = false;
}
System.arraycopy(data, offset, complexData, 0, complexData.length );
return complexData.length;
}
/**
* Serializes the simple part of this property. ie the first 6 bytes.
*
* Needs special code to handle the case when the size doesn't
* include the size of the header block
*/
public int serializeSimplePart( byte[] data, int pos )
{
LittleEndian.putShort(data, pos, getId());
int recordSize = complexData.length;
if(!sizeIncludesHeaderSize) {
recordSize -= 6;
}
LittleEndian.putInt(data, pos + 2, recordSize);
return 6;
}
/**
* Sometimes the element size is stored as a negative number. We
* negate it and shift it to get the real value.

View File

@ -158,26 +158,39 @@ public class TestEscherOptRecord extends TestCase
* Test serialisation of a particually complex example
* This test is currently broken!
*/
public void BROKENtestComplexSerialise() throws Exception {
public void testComplexSerialise() throws Exception {
byte[] data = new byte[] {
0x53, 0x01, 0x0B, 0xF0-256, 0x9C-256, 0x01, 0x00, 0x00, 0x42, 0x01,
0x49, 0x00, 0x00, 0x00, 0x43, 0x01, 0x85-256, 0x00, 0x00,
0x00, 0x44, 0x01, 0x04, 0x00, 0x00, 0x00,
0x45, 0xC1-256, 0x88-256, 0x00, 0x00, 0x00, 0x46, 0xC1-256,
0x90-256, 0x00, 0x00, 0x00, 0x7F, 0x01, 0x01, 0x00,
0x01, 0x00, 0x80-256, 0x01, 0x00, 0x00, 0x00, 0x00, 0x81-256,
0x01, 0x02, 0x00, 0x00, 0x08, 0xBF-256, 0x01,
0x10, 0x00, 0x10, 0x00, 0xC0-256, 0x01, 0x01, 0x00, 0x00, 0x08,
0x53, 0x01, 0x0B, 0xF0-256, 0x9C-256, 0x01, 0x00, 0x00,
// Simple data follows
0x42, 0x01, 0x49, 0x00, 0x00, 0x00, // SP @ 8
0x43, 0x01, 0x85-256, 0x00, 0x00, 0x00, // SP @ 14
0x44, 0x01, 0x04, 0x00, 0x00, 0x00, // SP @ 20
0x45, 0xC1-256, 0x88-256, 0x00, 0x00, 0x00, // SP @ 26
0x46, 0xC1-256, 0x90-256, 0x00, 0x00, 0x00, // SP @ 32
0x7F, 0x01, 0x01, 0x00, 0x01, 0x00,
0x80-256, 0x01, 0x00, 0x00, 0x00, 0x00,
0x81-256, 0x01, 0x02, 0x00, 0x00, 0x08,
0xBF-256, 0x01, 0x10, 0x00, 0x10, 0x00,
0xC0-256, 0x01, 0x01, 0x00, 0x00, 0x08, // SP 10
0xC1-256, 0x01, 0x00, 0x00, 0x01, 0x00,
0xC4-256, 0x01, 0x00, 0x00, 0x00, 0x00, 0xCB-256, 0x01, 0x38,
0x63, 0x00, 0x00, 0xCD-256, 0x01, 0x00, 0x00,
0x00, 0x00, 0xCE-256, 0x01, 0x00, 0x00, 0x00, 0x00, 0xD0-256,
0x01, 0x00, 0x00, 0x00, 0x00, 0xD1-256, 0x01,
0x00, 0x00, 0x00, 0x00, 0xD7-256, 0x01, 0x00, 0x00, 0x00, 0x00,
0xC4-256, 0x01, 0x00, 0x00, 0x00, 0x00,
0xCB-256, 0x01, 0x38, 0x63, 0x00, 0x00,
0xCD-256, 0x01, 0x00, 0x00, 0x00, 0x00,
0xCE-256, 0x01, 0x00, 0x00, 0x00, 0x00, // SP 15
0xD0-256, 0x01, 0x00, 0x00, 0x00, 0x00,
0xD1-256, 0x01, 0x00, 0x00, 0x00, 0x00,
0xD7-256, 0x01, 0x00, 0x00, 0x00, 0x00,
0xFF-256, 0x01, 0x18, 0x00, 0x18, 0x00,
0x01, 0x02, 0x02, 0x00, 0x00, 0x08, 0x3F, 0x02, 0x00, 0x00,
0x02, 0x00, 0x22, 0x00, 0x22, 0x00,
0xF0-256, 0xFF-256, 0x18, 0x00, 0x28, 0x00, 0x04, 0x00, 0x34,
0x01, 0x02, 0x02, 0x00, 0x00, 0x08,
0x3F, 0x02, 0x00, 0x00, 0x02, 0x00, // SP 21
// Complex data follows
// Complex data for Array #325
// Array header
0x22, 0x00, 0x22, 0x00, 0xF0-256, 0xFF-256,
// Array data
0x18, 0x00, 0x28, 0x00, 0x04, 0x00, 0x34,
0x00, 0x04, 0x00, 0x28, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x10,
0x00, 0x00, 0x00, 0x1C, 0x00,
@ -193,8 +206,11 @@ public class TestEscherOptRecord extends TestCase
0x00, 0x30, 0x00, 0x08, 0x00,
0x3C, 0x00, 0x08, 0x00, 0x48, 0x00, 0x08, 0x00, 0x54, 0x00, 0x00,
0x00, 0x48, 0x00, 0x00, 0x00,
0x3C, 0x00, 0x00, 0x00, 0x30, 0x00, 0x04, 0x00, 0x24, 0x00, 0x45,
0x00, 0x48, 0x00, 0x02, 0x00,
0x3C, 0x00, 0x00, 0x00, 0x30, 0x00, 0x04, 0x00, 0x24, 0x00,
// Complex data for Array #326
// Array header
0x45, 0x00, 0x48, 0x00, 0x02, 0x00,
// Array data
0x00, 0x40, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256,
0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00, 0x00, 0xB0-256, 0x01, 0x00,
@ -216,9 +232,10 @@ public class TestEscherOptRecord extends TestCase
// Create the record
EscherOptRecord r = new EscherOptRecord();
r.fillFields( data, new DefaultEscherRecordFactory() );
int filled = r.fillFields( data, new DefaultEscherRecordFactory() );
// Check it's the right length
assertEquals(data.length, filled);
assertEquals(data.length, r.getRecordSize());
// Serialise it
@ -228,7 +245,6 @@ public class TestEscherOptRecord extends TestCase
// Check it serialised it back to the same data
assertEquals(data.length, written);
for(int i=0; i<data.length; i++) {
System.err.println(i);
assertEquals(data[i], dest[i]);
}
}