mirror of https://github.com/apache/poi.git
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:
parent
0bef9fe7cc
commit
5aee7710b4
|
@ -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.
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue