Author: tallison
Date: Wed Jul 26 12:46:24 2017
New Revision: 1803041
URL: http://svn.apache.org/viewvc?rev=1803041&view=rev
Log:
61346 add more sanity checks before allocating byte arrays in emf/wmf
Modified:
poi/site/src/documentation/content/xdocs/status.xml
poi/trunk/src/java/org/apache/poi/util/IOUtils.java
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentEMFPlus.java
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentPublic.java
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentRecord.java
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfHeader.java
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
Modified: poi/site/src/documentation/content/xdocs/status.xml
URL:
http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/status.xml?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/status.xml (original)
+++ poi/site/src/documentation/content/xdocs/status.xml Wed Jul 26 12:46:24 2017
@@ -58,6 +58,7 @@
<release version="3.17-beta2" date="2017-09-??">
<actions>
+ <action dev="PD" type="fix" fixes-bug="61346" module="HEMF">Add more
sanity checks before allocation of byte arrays in HEMF/HWMF.</action>
<action dev="PD" type="fix" fixes-bug="61338" module="HWMF">Avoid
infinite loop with corrupt file.</action>
<action dev="PD" type="fix" fixes-bug="61295" module="HPSF">Avoid OOM
in hpsf with corrupt file.</action>
<action dev="PD" type="add" fixes-bug="61331" module="SL Common">Font
group handling / common font interface</action>
Modified: poi/trunk/src/java/org/apache/poi/util/IOUtils.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/util/IOUtils.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/util/IOUtils.java (original)
+++ poi/trunk/src/java/org/apache/poi/util/IOUtils.java Wed Jul 26 12:46:24 2017
@@ -431,4 +431,19 @@ public final class IOUtils {
return toSkip - remain;
}
+ public static byte[] safelyAllocate(long length, int maxLength) {
+ if (length < 0L) {
+ throw new RecordFormatException("Can't allocate an array of length
< 0");
+ }
+ if (length > (long)Integer.MAX_VALUE) {
+ throw new RecordFormatException("Can't allocate an array >
"+Integer.MAX_VALUE);
+ }
+ if (length > maxLength) {
+ throw new RecordFormatException("Not allowed to allocate an array
> "+
+ maxLength+" for this record type." +
+ "If the file is not corrupt, please open an issue on
bugzilla to request " +
+ "increasing the maximum allowable size for this record
type");
+ }
+ return new byte[(int)length];
+ }
}
Modified:
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentEMFPlus.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentEMFPlus.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
---
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentEMFPlus.java
(original)
+++
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentEMFPlus.java
Wed Jul 26 12:46:24 2017
@@ -23,6 +23,7 @@ import java.util.List;
import org.apache.poi.hemf.hemfplus.record.HemfPlusRecord;
import org.apache.poi.hemf.hemfplus.record.HemfPlusRecordType;
+import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.RecordFormatException;
@@ -33,6 +34,9 @@ import org.apache.poi.util.RecordFormatE
@Internal
public class HemfCommentEMFPlus extends AbstractHemfComment {
+ private static final int MAX_RECORD_LENGTH = 1000000;
+
+
long dataSize;
public HemfCommentEMFPlus(byte[] rawBytes) {
//these rawBytes contain only the EMFPlusRecord(s?)
@@ -93,7 +97,7 @@ public class HemfCommentEMFPlus extends
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
- byte[] dataBytes = new byte[size];
+ byte[] dataBytes = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
System.arraycopy(bytes, offset, dataBytes, 0, size);
try {
record.init(dataBytes, recordId, flags);
Modified:
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentPublic.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentPublic.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
---
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentPublic.java
(original)
+++
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentPublic.java
Wed Jul 26 12:46:24 2017
@@ -23,6 +23,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
+import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
@@ -35,6 +36,9 @@ import org.apache.poi.util.RecordFormatE
@Internal
public class HemfCommentPublic {
+ private static final int MAX_RECORD_LENGTH = 1000000;
+
+
/**
* Stub, to be implemented
*/
@@ -80,7 +84,7 @@ public class HemfCommentPublic {
}
List<HemfMultiFormatsData> list = new
ArrayList<HemfMultiFormatsData>();
for (EmrFormat emrFormat : emrFormatList) {
- byte[] data = new byte[emrFormat.size];
+ byte[] data = IOUtils.safelyAllocate(emrFormat.size,
MAX_RECORD_LENGTH);
System.arraycopy(rawBytes, emrFormat.offset-4, data, 0,
emrFormat.size);
list.add(new HemfMultiFormatsData(emrFormat.signature,
emrFormat.version, data));
}
@@ -129,12 +133,8 @@ public class HemfCommentPublic {
wmfBytes = new byte[0];
return;
}
- if (winMetafileSizeLong > Integer.MAX_VALUE) {
- throw new RecordFormatException("Metafile record length can't
be > Integer.MAX_VALUE");
- }
- int winMetafileSize = (int)winMetafileSizeLong;
- wmfBytes = new byte[winMetafileSize];
- System.arraycopy(rawBytes, offset, wmfBytes, 0, winMetafileSize);
+ wmfBytes = IOUtils.safelyAllocate(winMetafileSizeLong,
MAX_RECORD_LENGTH);
+ System.arraycopy(rawBytes, offset, wmfBytes, 0, wmfBytes.length);
}
/**
Modified:
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentRecord.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentRecord.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
---
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentRecord.java
(original)
+++
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentRecord.java
Wed Jul 26 12:46:24 2017
@@ -36,6 +36,7 @@ import org.apache.poi.util.RecordFormatE
*/
@Internal
public class HemfCommentRecord implements HemfRecord {
+ private static final int MAX_RECORD_LENGTH = 1000000;
public final static long COMMENT_EMFSPOOL = 0x00000000;
public final static long COMMENT_EMFPLUS = 0x2B464D45;
@@ -87,7 +88,7 @@ public class HemfCommentRecord implement
int dataSize = (int)remainingDataSize;
int recordSize = (int)remainingRecordSize;
- byte[] arr = new byte[dataSize+initialBytes.length];
+ byte[] arr = IOUtils.safelyAllocate(dataSize+initialBytes.length,
MAX_RECORD_LENGTH);
System.arraycopy(initialBytes,0,arr, 0, initialBytes.length);
long read = IOUtils.readFully(leis, arr, initialBytes.length,
dataSize);
if (read != dataSize) {
@@ -103,13 +104,12 @@ public class HemfCommentRecord implement
}
private byte[] readToByteArray(LittleEndianInputStream leis, long
dataSize, long recordSize) throws IOException {
- assert dataSize < Integer.MAX_VALUE;
if (recordSize == 0) {
return new byte[0];
}
- byte[] arr = new byte[(int)dataSize];
+ byte[] arr = IOUtils.safelyAllocate(dataSize, MAX_RECORD_LENGTH);
long read = IOUtils.readFully(leis, arr);
if (read != dataSize) {
Modified:
poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfHeader.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfHeader.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfHeader.java
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfHeader.java Wed
Jul 26 12:46:24 2017
@@ -32,6 +32,9 @@ import org.apache.poi.util.LittleEndianI
@Internal
public class HemfHeader implements HemfRecord {
+ private static final int MAX_RECORD_LENGTH = 1000000;
+
+
private Rectangle boundsRectangle;
private Rectangle frameRectangle;
private long bytes;
@@ -140,7 +143,7 @@ public class HemfHeader implements HemfR
throw new IOException("Not a valid EMF header. Record
type:"+recordId);
}
//read the record--id and size (2 bytes) have already been read
- byte[] data = new byte[(int)recordSize];
+ byte[] data = IOUtils.safelyAllocate(recordSize, MAX_RECORD_LENGTH);
IOUtils.readFully(leis, data);
int offset = 0;
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java Wed
Jul 26 12:46:24 2017
@@ -39,7 +39,8 @@ import org.apache.poi.util.RecordFormatE
@Internal
public class HemfText {
- private final static Charset UTF16LE = Charset.forName("UTF-16LE");
+ private static final Charset UTF16LE = Charset.forName("UTF-16LE");
+ private static final int MAX_RECORD_LENGTH = 1000000;
public static class ExtCreateFontIndirectW extends UnimplementedHemfRecord
{
}
@@ -80,7 +81,7 @@ public class HemfText {
}
//guarantee to read the rest of the EMRTextObjectRecord
//emrtextbytes start after 7*4 bytes read above
- byte[] emrTextBytes = new
byte[recordSizeInt-(7*LittleEndian.INT_SIZE)];
+ byte[] emrTextBytes =
IOUtils.safelyAllocate(recordSizeInt-(7*LittleEndian.INT_SIZE),
MAX_RECORD_LENGTH);
IOUtils.readFully(leis, emrTextBytes);
textObject = new EmrTextObject(emrTextBytes, getEncodingHint(),
20);//should be 28, but recordSizeInt has already subtracted 8
return recordSize;
@@ -218,9 +219,12 @@ public class HemfText {
}
if (numCharsLong > Integer.MAX_VALUE) {
throw new RecordFormatException("Number of characters can't be
> Integer.MAX_VALUE");
+ } else if (numCharsLong < 0) {
+ throw new RecordFormatException("Number of characters can't be
< 0");
}
+
numChars = (int)numCharsLong;
- rawTextBytes = new byte[emrTextObjBytes.length-start];
+ rawTextBytes =
IOUtils.safelyAllocate(emrTextObjBytes.length-start, MAX_RECORD_LENGTH);
System.arraycopy(emrTextObjBytes, start, rawTextBytes, 0,
emrTextObjBytes.length-start);
}
Modified:
poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
Wed Jul 26 12:46:24 2017
@@ -17,6 +17,7 @@
package org.apache.poi.hwmf.record;
+import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
@@ -24,8 +25,6 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import javax.imageio.ImageIO;
-
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
@@ -38,6 +37,9 @@ import org.apache.poi.util.RecordFormatE
* The DeviceIndependentBitmap Object defines an image in device-independent
bitmap (DIB) format.
*/
public class HwmfBitmapDib {
+
+ private static final int MAX_RECORD_LENGTH = 10000000;
+
public static enum BitCount {
/**
* The image SHOULD be in either JPEG or PNG format. <6> Neither of
these formats includes
@@ -385,7 +387,7 @@ public class HwmfBitmapDib {
int imageSize = (int)Math.max(imageData.length,
introSize+headerImageSize);
// create the image data and leave the parsing to the ImageIO api
- byte buf[] = new byte[BMP_HEADER_SIZE+imageSize];
+ byte buf[] = IOUtils.safelyAllocate(BMP_HEADER_SIZE+imageSize,
MAX_RECORD_LENGTH);
// https://en.wikipedia.org/wiki/BMP_file_format # Bitmap file header
buf[0] = (byte)'B';
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java?rev=1803041&r1=1803040&r2=1803041&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java Wed
Jul 26 12:46:24 2017
@@ -26,6 +26,7 @@ import org.apache.poi.hwmf.draw.HwmfGrap
import org.apache.poi.hwmf.record.HwmfMisc.WmfSetMapMode;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.POILogFactory;
@@ -33,7 +34,8 @@ import org.apache.poi.util.POILogger;
public class HwmfText {
private static final POILogger logger =
POILogFactory.getLogger(HwmfText.class);
-
+ private static final int MAX_RECORD_LENGTH = 1000000;
+
/**
* The META_SETTEXTCHAREXTRA record defines inter-character spacing for
text justification in the
* playback device context. Spacing is added to the white space between
each character, including
@@ -164,7 +166,7 @@ public class HwmfText {
@Override
public int init(LittleEndianInputStream leis, long recordSize, int
recordFunction) throws IOException {
stringLength = leis.readShort();
- rawTextBytes = new byte[stringLength+(stringLength&1)];
+ rawTextBytes =
IOUtils.safelyAllocate(stringLength+(stringLength&1), MAX_RECORD_LENGTH);
leis.readFully(rawTextBytes);
yStart = leis.readShort();
xStart = leis.readShort();
@@ -188,7 +190,7 @@ public class HwmfText {
* This does not include the extra optional padding on the byte array.
*/
private byte[] getTextBytes() {
- byte[] ret = new byte[stringLength];
+ byte[] ret = IOUtils.safelyAllocate(stringLength,
MAX_RECORD_LENGTH);
System.arraycopy(rawTextBytes, 0, ret, 0, stringLength);
return ret;
}
@@ -315,7 +317,7 @@ public class HwmfText {
size += 4*LittleEndianConsts.SHORT_SIZE;
}
- rawTextBytes = new byte[stringLength+(stringLength&1)];
+ rawTextBytes =
IOUtils.safelyAllocate(stringLength+(stringLength&1), MAX_RECORD_LENGTH);
leis.readFully(rawTextBytes);
size += rawTextBytes.length;
@@ -355,7 +357,7 @@ public class HwmfText {
* This does not include the extra optional padding on the byte array.
*/
private byte[] getTextBytes() {
- byte[] ret = new byte[stringLength];
+ byte[] ret = IOUtils.safelyAllocate(stringLength,
MAX_RECORD_LENGTH);
System.arraycopy(rawTextBytes, 0, ret, 0, stringLength);
return ret;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]