From: Yegor Kozlov Date: Sat, 20 Jun 2009 11:17:30 +0000 (+0000) Subject: Fixed OOM in HSSFWorkbook#getAllPictures when reading .xls files containing metafiles... X-Git-Tag: REL_3_5-FINAL~95 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1c9e88d79e9c8f5cbb043fbb7440ef753e4dbda1;p=poi.git 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 --- diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 9e8e2a6a3b..0d68b29178 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 47143 - Fixed OOM in HSSFWorkbook#getAllPictures when reading .xls files containing metafiles Added implementation for ISNA() 46793 - fixed SimpleShape#getLineWidth to handle default line width 47356 - removed unused private fields in HWPF BorderCode diff --git a/src/java/org/apache/poi/ddf/EscherBSERecord.java b/src/java/org/apache/poi/ddf/EscherBSERecord.java index cfe4fe1028..a99c11fd5a 100644 --- a/src/java/org/apache/poi/ddf/EscherBSERecord.java +++ b/src/java/org/apache/poi/ddf/EscherBSERecord.java @@ -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' + diff --git a/src/java/org/apache/poi/ddf/EscherDggRecord.java b/src/java/org/apache/poi/ddf/EscherDggRecord.java index 2266d127ae..bdcf5ad068 100644 --- a/src/java/org/apache/poi/ddf/EscherDggRecord.java +++ b/src/java/org/apache/poi/ddf/EscherDggRecord.java @@ -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() { diff --git a/src/java/org/apache/poi/ddf/EscherMetafileBlip.java b/src/java/org/apache/poi/ddf/EscherMetafileBlip.java index 662a7a7d13..9989951f82 100644 --- a/src/java/org/apache/poi/ddf/EscherMetafileBlip.java +++ b/src/java/org/apache/poi/ddf/EscherMetafileBlip.java @@ -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))); } /** diff --git a/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java index 62c1f233b2..9e2921fe88 100755 --- a/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java @@ -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)); + } } diff --git a/src/testcases/org/apache/poi/ddf/data/47143.dat b/src/testcases/org/apache/poi/ddf/data/47143.dat new file mode 100755 index 0000000000..0745ce1b99 Binary files /dev/null and b/src/testcases/org/apache/poi/ddf/data/47143.dat differ