From: Yegor Kozlov Date: Tue, 27 Jul 2010 15:24:25 +0000 (+0000) Subject: prevent ArrayIndexOutOfBoundException in UnknowEscherRecord, see bug #49579 X-Git-Tag: REL_3_7_BETA2~15 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e46e2c44a73cff9ffeff0b6499d4078e41c2a022;p=poi.git prevent ArrayIndexOutOfBoundException in UnknowEscherRecord, see bug #49579 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@979747 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 3d631d457a..6ec1c7c1a3 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 49579 - prevent ArrayIndexOutOfBoundException in UnknowEscherRecord 49593 - preserve leading and trailing white spaces in XWPFRun 49455 - Insert the content of fldSimple fields into the XWPFWordTextExtractor output 49640 - Fixed parsing formulas containing defined names beginning with an underscore diff --git a/src/java/org/apache/poi/ddf/UnknownEscherRecord.java b/src/java/org/apache/poi/ddf/UnknownEscherRecord.java index 5ade6a7c74..e5296123b1 100644 --- a/src/java/org/apache/poi/ddf/UnknownEscherRecord.java +++ b/src/java/org/apache/poi/ddf/UnknownEscherRecord.java @@ -28,6 +28,7 @@ import org.apache.poi.util.LittleEndian; * we do not explicitly support. * * @author Glen Stampoultzis (glens at apache.org) + * @author Zhang Zhang (zhangzzh at gmail.com) */ public final class UnknownEscherRecord extends EscherRecord { private static final byte[] NO_BYTES = new byte[0]; @@ -42,6 +43,17 @@ public final class UnknownEscherRecord extends EscherRecord { public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); + /* + * Modified by Zhang Zhang + * Have a check between avaliable bytes and bytesRemaining, + * take the avaliable length if the bytesRemaining out of range. + * July 09, 2010 + */ + int avaliable = data.length - (offset + 8); + if (bytesRemaining > avaliable) { + bytesRemaining = avaliable; + } + if (isContainerRecord()) { int bytesWritten = 0; thedata = new byte[0]; @@ -58,6 +70,7 @@ public final class UnknownEscherRecord extends EscherRecord { } return bytesWritten; } + thedata = new byte[bytesRemaining]; System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining ); return bytesRemaining + 8; diff --git a/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java b/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java index 2505dfc272..5973d8c167 100644 --- a/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java @@ -76,7 +76,45 @@ public final class TestUnknownEscherRecord extends TestCase { assertTrue( r.isContainerRecord() ); assertEquals( 1, r.getChildRecords().size() ); assertEquals( (short) 0xFFFF, r.getChild( 0 ).getRecordId() ); - + + //Add by Zhang Zhang test error situation when remaining bytes > avalible bytes + testData = + "00 02 " + // options + "11 F1 " + // record id + "05 00 00 00 " + // remaining bytes + "01 02 03 04"; + + r = new UnknownEscherRecord(); + r.fillFields( HexRead.readFromString( testData ), factory ); + + assertEquals( 0x0200, r.getOptions() ); + assertEquals( (short) 0xF111, r.getRecordId() ); + assertEquals( 12, r.getRecordSize() ); + assertFalse( r.isContainerRecord() ); + assertEquals( 0, r.getChildRecords().size() ); + assertEquals( 4, r.getData().length ); + assertEquals( 1, r.getData()[0] ); + assertEquals( 2, r.getData()[1] ); + assertEquals( 3, r.getData()[2] ); + assertEquals( 4, r.getData()[3] ); + + testData = + "0F 02 " + // options + "11 F1 " + // record id + "09 00 00 00 " + // remaining bytes + "00 02 " + // options + "FF FF " + // record id + "00 00 00 00"; // remaining bytes + + r = new UnknownEscherRecord(); + r.fillFields( HexRead.readFromString( testData ), factory ); + + assertEquals( 0x020F, r.getOptions() ); + assertEquals( (short) 0xF111, r.getRecordId() ); + assertEquals( 8, r.getRecordSize() ); + assertTrue( r.isContainerRecord() ); + assertEquals( 1, r.getChildRecords().size() ); + assertEquals( (short) 0xFFFF, r.getChild( 0 ).getRecordId() ); } public void testSerialize() {