Fixed OOM in HSSFWorkbook#getAllPictures when reading .xls files containing metafiles, see Bugzilla 47143

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@786793 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2009-06-20 11:17:30 +00:00
parent 07bff0902a
commit 2089d73506
6 changed files with 43 additions and 8 deletions

View File

@ -33,6 +33,7 @@
<changes>
<release version="3.5-beta7" date="2009-??-??">
<action dev="POI-DEVELOPERS" type="fix">47143 - Fixed OOM in HSSFWorkbook#getAllPictures when reading .xls files containing metafiles</action>
<action dev="POI-DEVELOPERS" type="add">Added implementation for ISNA()</action>
<action dev="POI-DEVELOPERS" type="add">46793 - fixed SimpleShape#getLineWidth to handle default line width </action>
<action dev="POI-DEVELOPERS" type="add">47356 - removed unused private fields in HWPF BorderCode</action>

View File

@ -310,13 +310,13 @@ public final class EscherBSERecord extends EscherRecord {
}
public String toString() {
String extraData = HexDump.toHex(_remainingData, 32);
String extraData = _remainingData == null ? null : HexDump.toHex(_remainingData, 32);
return getClass().getName() + ":" + '\n' +
" RecordId: 0x" + HexDump.toHex( RECORD_ID ) + '\n' +
" Options: 0x" + HexDump.toHex( getOptions() ) + '\n' +
" BlipTypeWin32: " + field_1_blipTypeWin32 + '\n' +
" BlipTypeMacOS: " + field_2_blipTypeMacOS + '\n' +
" SUID: " + HexDump.toHex(field_3_uid) + '\n' +
" SUID: " + (field_3_uid == null ? "" : HexDump.toHex(field_3_uid)) + '\n' +
" Tag: " + field_4_tag + '\n' +
" Size: " + field_5_size + '\n' +
" Ref: " + field_6_ref + '\n' +

View File

@ -122,7 +122,7 @@ public final class EscherDggRecord extends EscherRecord {
public String toString() {
StringBuffer field_5_string = new StringBuffer();
for (int i = 0; i < field_5_fileIdClusters.length; i++) {
if(field_5_fileIdClusters != null) for (int i = 0; i < field_5_fileIdClusters.length; i++) {
field_5_string.append(" DrawingGroupId").append(i+1).append(": ");
field_5_string.append(field_5_fileIdClusters[i].field_1_drawingGroupId);
field_5_string.append('\n');
@ -156,7 +156,7 @@ public final class EscherDggRecord extends EscherRecord {
* Number of id clusters + 1
*/
public int getNumIdClusters() {
return field_5_fileIdClusters.length + 1;
return (field_5_fileIdClusters == null ? 0 : (field_5_fileIdClusters.length + 1));
}
public int getNumShapesSaved() {

View File

@ -65,11 +65,11 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
private byte field_7_fFilter;
private byte[] raw_pictureData;
private byte[] remainingData;
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
int bytesAfterHeader = readHeader( data, offset );
int pos = offset + HEADER_SIZE;
field_1_UID = new byte[16];
System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16;
@ -91,6 +91,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
raw_pictureData = new byte[field_5_cbSave];
System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave );
pos += field_5_cbSave;
// 0 means DEFLATE compression
// 0xFE means no compression
@ -100,6 +101,11 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
field_pictureData = raw_pictureData;
}
int remaining = bytesAfterHeader - pos + offset + HEADER_SIZE;
if(remaining > 0) {
remainingData = new byte[remaining];
System.arraycopy( data, pos, remainingData, 0, remaining );
}
return bytesAfterHeader + HEADER_SIZE;
}
@ -126,7 +132,10 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
data[pos] = field_6_fCompression; pos++;
data[pos] = field_7_fFilter; pos++;
System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length );
System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length ); pos += raw_pictureData.length;
if(remainingData != null) {
System.arraycopy( remainingData, 0, data, pos, remainingData.length ); pos += remainingData.length;
}
listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this);
return getRecordSize();
@ -157,6 +166,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
public int getRecordSize() {
int size = 8 + 50 + raw_pictureData.length;
if(remainingData != null) size += remainingData.length;
if((getOptions() ^ getSignature()) == 0x10){
size += field_2_UID.length;
}
@ -227,10 +237,14 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
field_6_fCompression = compressed ? 0 : (byte)0xFE;
}
public byte[] getRemainingData() {
return remainingData;
}
// filtering is always 254 according to available docs, so no point giving it a setter method.
public String toString() {
String extraData = HexDump.toHex(field_pictureData, 32);
String extraData = "";//HexDump.toHex(field_pictureData, 32);
return getClass().getName() + ":" + '\n' +
" RecordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' +
" Options: 0x" + HexDump.toHex( getOptions() ) + '\n' +
@ -242,7 +256,9 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
" Compressed Size: " + HexDump.toHex( field_5_cbSave ) + '\n' +
" Compression: " + HexDump.toHex( field_6_fCompression ) + '\n' +
" Filter: " + HexDump.toHex( field_7_fFilter ) + '\n' +
" Extra Data:" + '\n' + extraData;
" Extra Data:" + '\n' + extraData +
(remainingData == null ? null : ("\n" +
" Remaining Data: " + HexDump.toHex(remainingData, 32)));
}
/**

View File

@ -152,4 +152,22 @@ public final class TestEscherBlipRecord extends TestCase {
return data;
}
/**
* The test data was created from pl031405.xls attached to Bugzilla #47143
*/
public void test47143() {
byte[] data = read(new File(cwd, "47143.dat"));
EscherBSERecord bse = new EscherBSERecord();
bse.fillFields(data, 0, new DefaultEscherRecordFactory());
bse.toString(); //assert that toString() works
assertTrue(bse.getBlipRecord() instanceof EscherMetafileBlip);
EscherMetafileBlip blip = (EscherMetafileBlip)bse.getBlipRecord();
blip.toString(); //assert that toString() works
byte[] remaining = blip.getRemainingData();
assertNotNull(remaining);
byte[] ser = bse.serialize(); //serialize and assert against the source data
assertTrue(Arrays.equals(data, ser));
}
}

Binary file not shown.