git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1809169 13f79535-47bb-0310-9956-ffa450edef68pull/64/head
@@ -19,6 +19,7 @@ package org.apache.poi.poifs.poibrowser; | |||
import java.io.*; | |||
import org.apache.poi.poifs.filesystem.*; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
* <p>Describes the most important (whatever that is) features of a | |||
@@ -26,6 +27,10 @@ import org.apache.poi.poifs.filesystem.*; | |||
*/ | |||
public class DocumentDescriptor | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
String name; | |||
POIFSDocumentPath path; | |||
DocumentInputStream stream; | |||
@@ -60,7 +65,7 @@ public class DocumentDescriptor | |||
if (stream.markSupported()) | |||
{ | |||
stream.mark(nrOfBytes); | |||
final byte[] b = new byte[nrOfBytes]; | |||
final byte[] b = IOUtils.safelyAllocate(nrOfBytes, MAX_RECORD_LENGTH); | |||
final int read = stream.read(b, 0, Math.min(size, b.length)); | |||
bytes = new byte[read]; | |||
System.arraycopy(b, 0, bytes, 0, read); |
@@ -21,6 +21,7 @@ import java.util.Iterator; | |||
import java.util.NoSuchElementException; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -28,6 +29,10 @@ import org.apache.poi.util.LittleEndian; | |||
* with all sorts of special cases. I'm hopeful I've got them all. | |||
*/ | |||
public final class EscherArrayProperty extends EscherComplexProperty implements Iterable<byte[]> { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* The size of the header that goes at the | |||
* start of the array, before the data | |||
@@ -69,7 +74,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements | |||
public void setNumberOfElementsInArray(int numberOfElements) { | |||
int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE; | |||
if (expectedArraySize != getComplexData().length) { | |||
byte[] newArray = new byte[expectedArraySize]; | |||
byte[] newArray = IOUtils.safelyAllocate(expectedArraySize, MAX_RECORD_LENGTH); | |||
System.arraycopy(getComplexData(), 0, newArray, 0, getComplexData().length); | |||
setComplexData(newArray); | |||
} | |||
@@ -83,7 +88,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements | |||
public void setNumberOfElementsInMemory(int numberOfElements) { | |||
int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE; | |||
if (expectedArraySize != getComplexData().length) { | |||
byte[] newArray = new byte[expectedArraySize]; | |||
byte[] newArray = IOUtils.safelyAllocate(expectedArraySize, MAX_RECORD_LENGTH); | |||
System.arraycopy(getComplexData(), 0, newArray, 0, expectedArraySize); | |||
setComplexData(newArray); | |||
} | |||
@@ -100,7 +105,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements | |||
int expectedArraySize = getNumberOfElementsInArray() * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE; | |||
if (expectedArraySize != getComplexData().length) { | |||
// Keep just the first 6 bytes. The rest is no good to us anyway. | |||
byte[] newArray = new byte[expectedArraySize]; | |||
byte[] newArray = IOUtils.safelyAllocate(expectedArraySize, MAX_RECORD_LENGTH); | |||
System.arraycopy( getComplexData(), 0, newArray, 0, 6 ); | |||
setComplexData(newArray); | |||
} | |||
@@ -108,7 +113,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements | |||
public byte[] getElement(int index) { | |||
int actualSize = getActualSizeOfElements(getSizeOfElements()); | |||
byte[] result = new byte[actualSize]; | |||
byte[] result = IOUtils.safelyAllocate(actualSize, MAX_RECORD_LENGTH); | |||
System.arraycopy(getComplexData(), FIXED_SIZE + index * actualSize, result, 0, result.length ); | |||
return result; | |||
} |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.ddf; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -27,6 +28,10 @@ import org.apache.poi.util.LittleEndian; | |||
* @see EscherBlipRecord | |||
*/ | |||
public final class EscherBSERecord extends EscherRecord { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static final short RECORD_ID = (short) 0xF007; | |||
public static final String RECORD_DESCRIPTION = "MsofbtBSE"; | |||
@@ -84,7 +89,7 @@ public final class EscherBSERecord extends EscherRecord { | |||
pos += 36 + bytesRead; | |||
bytesRemaining -= bytesRead; | |||
_remainingData = new byte[bytesRemaining]; | |||
_remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, pos, _remainingData, 0, bytesRemaining ); | |||
return bytesRemaining + 8 + 36 + (field_12_blipRecord == null ? 0 : field_12_blipRecord.getRecordSize()) ; | |||
@@ -17,9 +17,14 @@ | |||
package org.apache.poi.ddf; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
public class EscherBlipRecord extends EscherRecord { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000_000; | |||
public static final short RECORD_ID_START = (short) 0xF018; | |||
public static final short RECORD_ID_END = (short) 0xF117; | |||
public static final String RECORD_DESCRIPTION = "msofbtBlip"; | |||
@@ -36,7 +41,7 @@ public class EscherBlipRecord extends EscherRecord { | |||
int bytesAfterHeader = readHeader( data, offset ); | |||
int pos = offset + HEADER_SIZE; | |||
field_pictureData = new byte[bytesAfterHeader]; | |||
field_pictureData = IOUtils.safelyAllocate(bytesAfterHeader, MAX_RECORD_LENGTH); | |||
System.arraycopy(data, pos, field_pictureData, 0, bytesAfterHeader); | |||
return bytesAfterHeader + 8; | |||
@@ -94,7 +99,7 @@ public class EscherBlipRecord extends EscherRecord { | |||
if (pictureData == null || offset < 0 || length < 0 || pictureData.length < offset+length) { | |||
throw new IllegalArgumentException("picture data can't be null"); | |||
} | |||
field_pictureData = new byte[length]; | |||
field_pictureData = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); | |||
System.arraycopy(pictureData, offset, field_pictureData, 0, length); | |||
} | |||
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.ddf; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -30,6 +31,9 @@ import org.apache.poi.util.LittleEndian; | |||
public class EscherClientAnchorRecord | |||
extends EscherRecord | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static final short RECORD_ID = (short) 0xF010; | |||
public static final String RECORD_DESCRIPTION = "MsofbtClientAnchor"; | |||
@@ -83,7 +87,7 @@ public class EscherClientAnchorRecord | |||
} | |||
} | |||
bytesRemaining -= size; | |||
remainingData = new byte[bytesRemaining]; | |||
remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining ); | |||
return 8 + size + bytesRemaining; | |||
} |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.ddf; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -27,6 +28,9 @@ import org.apache.poi.util.LittleEndian; | |||
public class EscherClientDataRecord | |||
extends EscherRecord | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static final short RECORD_ID = (short) 0xF011; | |||
public static final String RECORD_DESCRIPTION = "MsofbtClientData"; | |||
@@ -36,7 +40,7 @@ public class EscherClientDataRecord | |||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { | |||
int bytesRemaining = readHeader( data, offset ); | |||
int pos = offset + 8; | |||
remainingData = new byte[bytesRemaining]; | |||
remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, pos, remainingData, 0, bytesRemaining ); | |||
return 8 + bytesRemaining; | |||
} |
@@ -26,12 +26,15 @@ import java.util.zip.DeflaterOutputStream; | |||
import java.util.zip.InflaterInputStream; | |||
import org.apache.poi.hssf.usermodel.HSSFPictureData; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
public final class EscherMetafileBlip extends EscherBlipRecord { | |||
private static final POILogger log = POILogFactory.getLogger(EscherMetafileBlip.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000_000; | |||
public static final short RECORD_ID_EMF = (short) 0xF018 + 2; | |||
public static final short RECORD_ID_WMF = (short) 0xF018 + 3; | |||
@@ -79,7 +82,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord { | |||
field_6_fCompression = data[pos]; pos++; | |||
field_7_fFilter = data[pos]; pos++; | |||
raw_pictureData = new byte[field_5_cbSave]; | |||
raw_pictureData = IOUtils.safelyAllocate(field_5_cbSave, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave ); | |||
pos += field_5_cbSave; | |||
@@ -93,7 +96,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord { | |||
int remaining = bytesAfterHeader - pos + offset + HEADER_SIZE; | |||
if(remaining > 0) { | |||
remainingData = new byte[remaining]; | |||
remainingData = IOUtils.safelyAllocate(remaining, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, pos, remainingData, 0, remaining ); | |||
} | |||
return bytesAfterHeader + HEADER_SIZE; |
@@ -24,12 +24,15 @@ import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.util.zip.InflaterInputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
public final class EscherPictBlip extends EscherBlipRecord { | |||
private static final POILogger log = POILogFactory.getLogger(EscherPictBlip.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static final short RECORD_ID_EMF = (short) 0xF018 + 2; | |||
public static final short RECORD_ID_WMF = (short) 0xF018 + 3; | |||
@@ -68,7 +71,7 @@ public final class EscherPictBlip extends EscherBlipRecord { | |||
field_6_fCompression = data[pos]; pos++; | |||
field_7_fFilter = data[pos]; pos++; | |||
raw_pictureData = new byte[field_5_cbSave]; | |||
raw_pictureData = IOUtils.safelyAllocate(field_5_cbSave, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave ); | |||
// 0 means DEFLATE compression |
@@ -20,12 +20,17 @@ package org.apache.poi.ddf; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
* Generates a property given a reference into the byte array storing that property. | |||
*/ | |||
public final class EscherPropertyFactory { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000_000; | |||
/** | |||
* Create new properties from a byte array. | |||
* | |||
@@ -64,9 +69,9 @@ public final class EscherPropertyFactory { | |||
if ( !isComplex ) { | |||
ep = new EscherSimpleProperty( propId, propData ); | |||
} else if ( propertyType == EscherPropertyMetaData.TYPE_ARRAY) { | |||
ep = new EscherArrayProperty( propId, new byte[propData]); | |||
ep = new EscherArrayProperty( propId, IOUtils.safelyAllocate(propData, MAX_RECORD_LENGTH)); | |||
} else { | |||
ep = new EscherComplexProperty( propId, new byte[propData]); | |||
ep = new EscherComplexProperty( propId, IOUtils.safelyAllocate(propData, MAX_RECORD_LENGTH)); | |||
} | |||
break; | |||
} |
@@ -20,6 +20,7 @@ package org.apache.poi.ddf; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.RecordFormatException; | |||
@@ -30,6 +31,10 @@ import org.apache.poi.util.RecordFormatException; | |||
* they will be in the parent's format, not Escher format. | |||
*/ | |||
public final class EscherTextboxRecord extends EscherRecord implements Cloneable { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static final short RECORD_ID = (short)0xF00D; | |||
public static final String RECORD_DESCRIPTION = "msofbtClientTextbox"; | |||
@@ -48,7 +53,7 @@ public final class EscherTextboxRecord extends EscherRecord implements Cloneable | |||
// Save the data, ready for the calling code to do something | |||
// useful with it | |||
thedata = new byte[bytesRemaining]; | |||
thedata = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining ); | |||
return bytesRemaining + 8; | |||
} | |||
@@ -97,7 +102,7 @@ public final class EscherTextboxRecord extends EscherRecord implements Cloneable | |||
*/ | |||
public void setData(byte[] b, int start, int length) | |||
{ | |||
thedata = new byte[length]; | |||
thedata = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); | |||
System.arraycopy(b,start,thedata,0,length); | |||
} | |||
@@ -21,6 +21,7 @@ import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -28,6 +29,10 @@ import org.apache.poi.util.LittleEndian; | |||
* we do not explicitly support. | |||
*/ | |||
public final class UnknownEscherRecord extends EscherRecord implements Cloneable { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000_000; | |||
private static final byte[] NO_BYTES = new byte[0]; | |||
/** The data for this record not including the the 8 byte header */ | |||
@@ -70,7 +75,7 @@ public final class UnknownEscherRecord extends EscherRecord implements Cloneable | |||
bytesRemaining = 0; | |||
} | |||
thedata = new byte[bytesRemaining]; | |||
thedata = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH); | |||
System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining ); | |||
return bytesRemaining + 8; | |||
} |
@@ -16,18 +16,23 @@ | |||
==================================================================== */ | |||
package org.apache.poi.hpsf; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndianInput; | |||
@Internal | |||
class Blob { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private byte[] _value; | |||
Blob() {} | |||
void read( LittleEndianInput lei ) { | |||
int size = lei.readInt(); | |||
_value = new byte[size]; | |||
_value = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
if ( size > 0 ) { | |||
lei.readFully(_value); | |||
} |
@@ -26,6 +26,9 @@ import org.apache.poi.util.POILogger; | |||
@Internal | |||
class ClipboardData { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000_000; | |||
private static final POILogger LOG = POILogFactory.getLogger( ClipboardData.class ); | |||
private int _format; | |||
@@ -48,7 +51,7 @@ class ClipboardData { | |||
} | |||
_format = lei.readInt(); | |||
_value = new byte[size - LittleEndianConsts.INT_SIZE]; | |||
_value = IOUtils.safelyAllocate(size - LittleEndianConsts.INT_SIZE, MAX_RECORD_LENGTH); | |||
lei.readFully(_value); | |||
} | |||
@@ -21,6 +21,7 @@ import java.io.OutputStream; | |||
import java.io.UnsupportedEncodingException; | |||
import org.apache.poi.util.CodePageUtil; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianByteArrayInputStream; | |||
@@ -30,6 +31,9 @@ import org.apache.poi.util.POILogger; | |||
@Internal | |||
class CodePageString { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private final static POILogger LOG = POILogFactory.getLogger( CodePageString.class ); | |||
private byte[] _value; | |||
@@ -40,7 +44,7 @@ class CodePageString { | |||
void read( LittleEndianByteArrayInputStream lei ) { | |||
int offset = lei.getReadIndex(); | |||
int size = lei.readInt(); | |||
_value = new byte[size]; | |||
_value = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
if (size == 0) { | |||
return; | |||
} |
@@ -33,6 +33,7 @@ import org.apache.commons.collections4.bidimap.TreeBidiMap; | |||
import org.apache.poi.hpsf.wellknown.PropertyIDMap; | |||
import org.apache.poi.hpsf.wellknown.SectionIDMap; | |||
import org.apache.poi.util.CodePageUtil; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianByteArrayInputStream; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
@@ -43,6 +44,9 @@ import org.apache.poi.util.POILogger; | |||
* Represents a section in a {@link PropertySet}. | |||
*/ | |||
public class Section { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final POILogger LOG = POILogFactory.getLogger(Section.class); | |||
/** | |||
@@ -835,7 +839,7 @@ public class Section { | |||
} | |||
try { | |||
byte buf[] = new byte[nrBytes]; | |||
byte buf[] = IOUtils.safelyAllocate(nrBytes, MAX_RECORD_LENGTH); | |||
leis.readFully(buf, 0, nrBytes); | |||
final String str = CodePageUtil.getStringFromCodePage(buf, 0, nrBytes, cp); | |||
@@ -21,6 +21,7 @@ import java.io.OutputStream; | |||
import java.io.UnsupportedEncodingException; | |||
import org.apache.poi.util.CodePageUtil; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianByteArrayInputStream; | |||
@@ -32,6 +33,8 @@ import org.apache.poi.util.StringUtil; | |||
@Internal | |||
class UnicodeString { | |||
private static final POILogger LOG = POILogFactory.getLogger( UnicodeString.class ); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private byte[] _value; | |||
@@ -40,7 +43,7 @@ class UnicodeString { | |||
void read(LittleEndianByteArrayInputStream lei) { | |||
final int length = lei.readInt(); | |||
final int unicodeBytes = length*2; | |||
_value = new byte[unicodeBytes]; | |||
_value = IOUtils.safelyAllocate(unicodeBytes, MAX_RECORD_LENGTH); | |||
// If Length is zero, this field MUST be zero bytes in length. If Length is | |||
// nonzero, this field MUST be a null-terminated array of 16-bit Unicode characters, followed by |
@@ -25,6 +25,7 @@ import java.util.Date; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianByteArrayInputStream; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
@@ -58,6 +59,9 @@ public class VariantSupport extends Variant { | |||
private static final POILogger logger = POILogFactory.getLogger(VariantSupport.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static boolean logUnsupportedTypes; | |||
/** | |||
@@ -172,7 +176,7 @@ public class VariantSupport extends Variant { | |||
typedPropertyValue.readValue(lei); | |||
} catch ( UnsupportedOperationException exc ) { | |||
int propLength = Math.min( length, lei.available() ); | |||
final byte[] v = new byte[propLength]; | |||
final byte[] v = IOUtils.safelyAllocate(propLength, MAX_RECORD_LENGTH); | |||
lei.readFully(v, 0, propLength); | |||
throw new ReadingNotSupportedException( type, v ); | |||
} | |||
@@ -248,7 +252,7 @@ public class VariantSupport extends Variant { | |||
default: | |||
final int unpadded = lei.getReadIndex()-offset; | |||
lei.setReadIndex(offset); | |||
final byte[] v = new byte[unpadded]; | |||
final byte[] v = IOUtils.safelyAllocate(unpadded, MAX_RECORD_LENGTH); | |||
lei.readFully( v, 0, unpadded ); | |||
throw new ReadingNotSupportedException( type, v ); | |||
} |
@@ -57,6 +57,9 @@ import org.apache.poi.util.IOUtils; | |||
public class OldExcelExtractor implements Closeable { | |||
private final static int FILE_PASS_RECORD_SID = 0x2f; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private RecordInputStream ris; | |||
@@ -278,7 +281,7 @@ public class OldExcelExtractor implements Closeable { | |||
break; | |||
default: | |||
ris.readFully(new byte[ris.remaining()]); | |||
ris.readFully(IOUtils.safelyAllocate(ris.remaining(), MAX_RECORD_LENGTH)); | |||
} | |||
} | |||
@@ -36,6 +36,7 @@ import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType; | |||
import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
import org.apache.poi.util.POILogger; | |||
@@ -50,6 +51,10 @@ import org.apache.poi.util.POILogger; | |||
* this is only used for the other types | |||
*/ | |||
public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cloneable { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static final short sid = 0x087A; | |||
private FtrHeader futureHeader; | |||
@@ -92,7 +97,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl | |||
priority = 0; | |||
template_type = getConditionType(); | |||
template_param_length = 16; | |||
template_params = new byte[template_param_length]; | |||
template_params = IOUtils.safelyAllocate(template_param_length, MAX_RECORD_LENGTH); | |||
} | |||
/** | |||
@@ -236,7 +241,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl | |||
} else { | |||
int len = readFormatOptions(in); | |||
if (len < ext_formatting_length) { | |||
ext_formatting_data = new byte[ext_formatting_length-len]; | |||
ext_formatting_data = IOUtils.safelyAllocate(ext_formatting_length-len, MAX_RECORD_LENGTH); | |||
in.readFully(ext_formatting_data); | |||
} | |||
} | |||
@@ -252,7 +257,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl | |||
template_type = in.readUShort(); | |||
template_param_length = in.readByte(); | |||
if (template_param_length == 0 || template_param_length == 16) { | |||
template_params = new byte[template_param_length]; | |||
template_params = IOUtils.safelyAllocate(template_param_length, MAX_RECORD_LENGTH); | |||
in.readFully(template_params); | |||
} else { | |||
logger.log(POILogger.WARN, "CF Rule v12 template params length should be 0 or 16, found " + template_param_length); | |||
@@ -465,7 +470,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl | |||
// use min() to gracefully handle cases where the length-property and the array-length do not match | |||
// we saw some such files in circulation | |||
rec.ext_formatting_length = Math.min(ext_formatting_length, ext_formatting_data.length); | |||
rec.ext_formatting_data = new byte[ext_formatting_length]; | |||
rec.ext_formatting_data = IOUtils.safelyAllocate(ext_formatting_length, MAX_RECORD_LENGTH); | |||
System.arraycopy(ext_formatting_data, 0, rec.ext_formatting_data, 0, rec.ext_formatting_length); | |||
rec.formula_scale = formula_scale.copy(); | |||
@@ -474,7 +479,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl | |||
rec.priority = priority; | |||
rec.template_type = template_type; | |||
rec.template_param_length = template_param_length; | |||
rec.template_params = new byte[template_param_length]; | |||
rec.template_params = IOUtils.safelyAllocate(template_param_length, MAX_RECORD_LENGTH); | |||
System.arraycopy(template_params, 0, rec.template_params, 0, template_param_length); | |||
if (color_gradient != null) { | |||
@@ -487,7 +492,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl | |||
rec.data_bar = (DataBarFormatting)data_bar.clone(); | |||
} | |||
if (filter_data != null) { | |||
rec.filter_data = new byte[filter_data.length]; | |||
rec.filter_data = IOUtils.safelyAllocate(filter_data.length, MAX_RECORD_LENGTH); | |||
System.arraycopy(filter_data, 0, rec.filter_data, 0, filter_data.length); | |||
} | |||
@@ -20,6 +20,7 @@ package org.apache.poi.hssf.record; | |||
import java.util.Arrays; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
import org.apache.poi.util.RecordFormatException; | |||
@@ -69,6 +70,9 @@ import org.apache.poi.util.StringUtil; | |||
public class DConRefRecord extends StandardRecord | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* The id of the record type, | |||
* <code>sid = {@value}</code> | |||
@@ -142,7 +146,7 @@ public class DConRefRecord extends StandardRecord | |||
*/ | |||
int byteLength = charCount * ((charType & 1) + 1); | |||
path = LittleEndian.getByteArray(data, offset, byteLength); | |||
path = LittleEndian.getByteArray(data, offset, byteLength, MAX_RECORD_LENGTH); | |||
offset += byteLength; | |||
/* | |||
@@ -150,7 +154,7 @@ public class DConRefRecord extends StandardRecord | |||
* unused field. Not sure If i need to bother with this... | |||
*/ | |||
if (path[0] == 0x02) | |||
_unused = LittleEndian.getByteArray(data, offset, (charType + 1)); | |||
_unused = LittleEndian.getByteArray(data, offset, (charType + 1), MAX_RECORD_LENGTH); | |||
} | |||
@@ -175,7 +179,7 @@ public class DConRefRecord extends StandardRecord | |||
// byteLength depends on whether we are using single- or double-byte chars. | |||
int byteLength = charCount * (charType + 1); | |||
path = new byte[byteLength]; | |||
path = IOUtils.safelyAllocate(byteLength, MAX_RECORD_LENGTH); | |||
inStream.readFully(path); | |||
if (path[0] == 0x02) |
@@ -25,6 +25,7 @@ import org.apache.poi.ss.formula.ptg.Ptg; | |||
import org.apache.poi.ss.formula.ptg.Ref3DPtg; | |||
import org.apache.poi.ss.formula.ptg.RefPtg; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.LittleEndianInputStream; | |||
@@ -41,6 +42,9 @@ import org.apache.poi.util.StringUtil; | |||
*/ | |||
public final class EmbeddedObjectRefSubRecord extends SubRecord implements Cloneable { | |||
private static POILogger logger = POILogFactory.getLogger(EmbeddedObjectRefSubRecord.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static final short sid = 0x0009; | |||
private static final byte[] EMPTY_BYTE_ARRAY = { }; | |||
@@ -173,7 +177,7 @@ public final class EmbeddedObjectRefSubRecord extends SubRecord implements Clone | |||
if (size == 0) { | |||
return EMPTY_BYTE_ARRAY; | |||
} | |||
byte[] result = new byte[size]; | |||
byte[] result = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
in.readFully(result); | |||
return result; | |||
} |
@@ -36,6 +36,7 @@ import org.apache.poi.ddf.EscherSerializationListener; | |||
import org.apache.poi.ddf.EscherSpRecord; | |||
import org.apache.poi.ddf.EscherSpgrRecord; | |||
import org.apache.poi.ddf.EscherTextboxRecord; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.apache.poi.util.RecordFormatException; | |||
@@ -85,6 +86,9 @@ import org.apache.poi.util.RecordFormatException; | |||
public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
public static final short sid = 9876; // not a real sid - dummy value | |||
private static POILogger log = POILogFactory.getLogger(EscherAggregate.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000_000; | |||
public static final short ST_MIN = (short) 0; | |||
public static final short ST_NOT_PRIMATIVE = ST_MIN; | |||
@@ -592,7 +596,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { | |||
// Determine buffer size | |||
List<EscherRecord> records = getEscherRecords(); | |||
int rawEscherSize = getEscherRecordSize(records); | |||
byte[] buffer = new byte[rawEscherSize]; | |||
byte[] buffer = IOUtils.safelyAllocate(rawEscherSize, MAX_RECORD_LENGTH); | |||
final List<Integer> spEndingOffsets = new ArrayList<>(); | |||
int pos = 0; | |||
for (EscherRecord e : records) { |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
import org.apache.poi.util.RecordFormatException; | |||
@@ -48,7 +49,7 @@ public final class FtCblsSubRecord extends SubRecord implements Cloneable { | |||
throw new RecordFormatException("Unexpected size (" + size + ")"); | |||
} | |||
//just grab the raw data | |||
byte[] buf = new byte[size]; | |||
byte[] buf = IOUtils.safelyAllocate(size, ENCODED_SIZE); | |||
in.readFully(buf); | |||
reserved = buf; | |||
} |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
@@ -27,6 +28,9 @@ import org.apache.poi.util.LittleEndianOutput; | |||
*/ | |||
public final class GroupMarkerSubRecord extends SubRecord implements Cloneable { | |||
public final static short sid = 0x0006; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final byte[] EMPTY_BYTE_ARRAY = { }; | |||
@@ -38,7 +42,7 @@ public final class GroupMarkerSubRecord extends SubRecord implements Cloneable { | |||
} | |||
public GroupMarkerSubRecord(LittleEndianInput in, int size) { | |||
byte[] buf = new byte[size]; | |||
byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
in.readFully(buf); | |||
reserved = buf; | |||
} |
@@ -20,6 +20,7 @@ package org.apache.poi.hssf.record; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.HexRead; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
@@ -36,6 +37,9 @@ import org.apache.poi.util.StringUtil; | |||
public final class HyperlinkRecord extends StandardRecord implements Cloneable { | |||
public final static short sid = 0x01B8; | |||
private static POILogger logger = POILogFactory.getLogger(HyperlinkRecord.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
static final class GUID { | |||
/* | |||
@@ -525,7 +529,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable { | |||
int len = in.readInt(); | |||
byte[] path_bytes = new byte[len]; | |||
byte[] path_bytes = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
in.readFully(path_bytes); | |||
_address = new String(path_bytes, StringUtil.UTF8); |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
import org.apache.poi.util.RecordFormatException; | |||
@@ -55,7 +56,7 @@ public final class NoteStructureSubRecord extends SubRecord implements Cloneable | |||
throw new RecordFormatException("Unexpected size (" + size + ")"); | |||
} | |||
//just grab the raw data | |||
byte[] buf = new byte[size]; | |||
byte[] buf = IOUtils.safelyAllocate(size, ENCODED_SIZE); | |||
in.readFully(buf); | |||
reserved = buf; | |||
} |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.apache.poi.util.RecordFormatException; | |||
@@ -29,6 +30,8 @@ import org.apache.poi.util.RecordFormatException; | |||
*/ | |||
public final class OldLabelRecord extends OldCellRecord { | |||
private final static POILogger logger = POILogFactory.getLogger(OldLabelRecord.class); | |||
//arbitrarily set, may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public final static short biff2_sid = 0x0004; | |||
public final static short biff345_sid = 0x0204; | |||
@@ -51,7 +54,7 @@ public final class OldLabelRecord extends OldCellRecord { | |||
} | |||
// Can only decode properly later when you know the codepage | |||
field_5_bytes = new byte[field_4_string_len]; | |||
field_5_bytes = IOUtils.safelyAllocate(field_4_string_len, MAX_RECORD_LENGTH); | |||
in.read(field_5_bytes, 0, field_4_string_len); | |||
if (in.remaining() > 0) { |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
* Title: Bound Sheet Record (aka BundleSheet) (0x0085) for BIFF 5<P> | |||
@@ -26,6 +27,10 @@ import org.apache.poi.util.HexDump; | |||
* file. | |||
*/ | |||
public final class OldSheetRecord { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public final static short sid = 0x0085; | |||
private int field_1_position_of_BOF; | |||
@@ -39,7 +44,7 @@ public final class OldSheetRecord { | |||
field_2_visibility = in.readUByte(); | |||
field_3_type = in.readUByte(); | |||
int field_4_sheetname_length = in.readUByte(); | |||
field_5_sheetname = new byte[field_4_sheetname_length]; | |||
field_5_sheetname = IOUtils.safelyAllocate(field_4_sheetname_length, MAX_RECORD_LENGTH); | |||
in.read(field_5_sheetname, 0, field_4_sheetname_length); | |||
} | |||
@@ -21,6 +21,7 @@ import java.io.UnsupportedEncodingException; | |||
import org.apache.poi.hpsf.Property; | |||
import org.apache.poi.util.CodePageUtil; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
@@ -28,6 +29,10 @@ import org.apache.poi.util.CodePageUtil; | |||
* formula string results. | |||
*/ | |||
public final class OldStringRecord { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public final static short biff2_sid = 0x0007; | |||
public final static short biff345_sid = 0x0207; | |||
@@ -49,7 +54,7 @@ public final class OldStringRecord { | |||
} | |||
// Can only decode properly later when you know the codepage | |||
field_2_bytes = new byte[field_1_string_len]; | |||
field_2_bytes = IOUtils.safelyAllocate(field_1_string_len, MAX_RECORD_LENGTH); | |||
in.read(field_2_bytes, 0, field_1_string_len); | |||
} | |||
@@ -25,6 +25,7 @@ import java.util.Locale; | |||
import org.apache.poi.hssf.dev.BiffViewer; | |||
import org.apache.poi.hssf.record.crypto.Biff8DecryptingStream; | |||
import org.apache.poi.poifs.crypt.EncryptionInfo; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
import org.apache.poi.util.LittleEndianInput; | |||
@@ -36,9 +37,13 @@ import org.apache.poi.util.RecordFormatException; | |||
* Description: Wraps a stream and provides helper methods for the construction of records.<P> | |||
*/ | |||
public final class RecordInputStream implements LittleEndianInput { | |||
/** Maximum size of a single record (minus the 4 byte header) without a continue*/ | |||
public final static short MAX_RECORD_DATA_SIZE = 8224; | |||
private static final int INVALID_SID_VALUE = -1; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* When {@link #_currentDataLength} has this value, it means that the previous BIFF record is | |||
* finished, the next sid has been properly read, but the data size field has not been read yet. | |||
@@ -441,7 +446,7 @@ public final class RecordInputStream implements LittleEndianInput { | |||
if (size ==0) { | |||
return EMPTY_BYTE_ARRAY; | |||
} | |||
byte[] result = new byte[size]; | |||
byte[] result = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
readFully(result); | |||
return result; | |||
} |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.hssf.record; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
import org.apache.poi.util.LittleEndianOutputStream; | |||
@@ -28,6 +29,10 @@ import java.io.ByteArrayOutputStream; | |||
* Subrecords are part of the OBJ class. | |||
*/ | |||
public abstract class SubRecord { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
protected SubRecord() { | |||
// no fields to initialise | |||
} | |||
@@ -107,7 +112,7 @@ public abstract class SubRecord { | |||
public UnknownSubRecord(LittleEndianInput in, int sid, int size) { | |||
_sid = sid; | |||
byte[] buf = new byte[size]; | |||
byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
in.readFully(buf); | |||
_data = buf; | |||
} |
@@ -28,6 +28,7 @@ import org.apache.poi.hssf.record.cont.ContinuableRecordInput; | |||
import org.apache.poi.hssf.record.cont.ContinuableRecordOutput; | |||
import org.apache.poi.util.BitField; | |||
import org.apache.poi.util.BitFieldFactory; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.LittleEndianOutput; | |||
import org.apache.poi.util.POILogFactory; | |||
@@ -46,6 +47,10 @@ public class UnicodeString implements Comparable<UnicodeString> { | |||
// TODO - make this final when the compatibility version is removed | |||
private static POILogger _logger = POILogFactory.getLogger(UnicodeString.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private short field_1_charCount; | |||
private byte field_2_optionflags; | |||
private String field_3_string; | |||
@@ -196,7 +201,7 @@ public class UnicodeString implements Comparable<UnicodeString> { | |||
_logger.log( POILogger.WARN, "Warning - ExtRst overran by " + (0-extraDataLength) + " bytes"); | |||
extraDataLength = 0; | |||
} | |||
extraData = new byte[extraDataLength]; | |||
extraData = IOUtils.safelyAllocate(extraDataLength, MAX_RECORD_LENGTH); | |||
for(int i=0; i<extraData.length; i++) { | |||
extraData[i] = in.readByte(); | |||
} |
@@ -27,6 +27,7 @@ import org.apache.poi.hssf.record.InterfaceHdrRecord; | |||
import org.apache.poi.poifs.crypt.ChunkedCipherInputStream; | |||
import org.apache.poi.poifs.crypt.Decryptor; | |||
import org.apache.poi.poifs.crypt.EncryptionInfo; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
import org.apache.poi.util.LittleEndianInput; | |||
@@ -35,6 +36,8 @@ import org.apache.poi.util.RecordFormatException; | |||
public final class Biff8DecryptingStream implements BiffHeaderInput, LittleEndianInput { | |||
public static final int RC4_REKEYING_INTERVAL = 1024; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private final EncryptionInfo info; | |||
private ChunkedCipherInputStream ccis; | |||
@@ -43,7 +46,7 @@ public final class Biff8DecryptingStream implements BiffHeaderInput, LittleEndia | |||
public Biff8DecryptingStream(InputStream in, int initialOffset, EncryptionInfo info) throws RecordFormatException { | |||
try { | |||
byte initialBuf[] = new byte[initialOffset]; | |||
byte initialBuf[] = IOUtils.safelyAllocate(initialOffset, MAX_RECORD_LENGTH); | |||
InputStream stream; | |||
if (initialOffset == 0) { | |||
stream = in; |
@@ -112,6 +112,7 @@ import org.apache.poi.ss.usermodel.SheetVisibility; | |||
import org.apache.poi.ss.usermodel.Workbook; | |||
import org.apache.poi.util.Configurator; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianByteArrayInputStream; | |||
@@ -128,6 +129,10 @@ import org.apache.poi.util.POILogger; | |||
* @see org.apache.poi.hssf.usermodel.HSSFSheet | |||
*/ | |||
public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final Pattern COMMA_PATTERN = Pattern.compile(","); | |||
/** | |||
@@ -1552,7 +1557,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss | |||
if (sid == BoundSheetRecord.sid) { | |||
// special case for the field_1_position_of_BOF (=lbPlyPos) field of | |||
// the BoundSheet8 record which must be unencrypted | |||
byte bsrBuf[] = new byte[len]; | |||
byte bsrBuf[] = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
plain.readFully(bsrBuf); | |||
os.writePlain(bsrBuf, 0, 4); | |||
os.write(bsrBuf, 4, len-4); |
@@ -27,11 +27,16 @@ import javax.crypto.IllegalBlockSizeException; | |||
import javax.crypto.ShortBufferException; | |||
import org.apache.poi.EncryptedDocumentException; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndianInputStream; | |||
@Internal | |||
public abstract class ChunkedCipherInputStream extends LittleEndianInputStream { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private final int chunkSize; | |||
private final int chunkBits; | |||
@@ -55,8 +60,8 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream { | |||
this.pos = initialPos; | |||
this.chunkSize = chunkSize; | |||
int cs = chunkSize == -1 ? 4096 : chunkSize; | |||
this.chunk = new byte[cs]; | |||
this.plain = new byte[cs]; | |||
this.chunk = IOUtils.safelyAllocate(cs, MAX_RECORD_LENGTH); | |||
this.plain = IOUtils.safelyAllocate(cs, MAX_RECORD_LENGTH); | |||
this.chunkBits = Integer.bitCount(chunk.length-1); | |||
this.lastIndex = (int)(pos >> chunkBits); | |||
this.cipher = initCipherForBlock(null, lastIndex); |
@@ -47,6 +47,9 @@ import org.apache.poi.util.TempFile; | |||
@Internal | |||
public abstract class ChunkedCipherOutputStream extends FilterOutputStream { | |||
private static final POILogger LOG = POILogFactory.getLogger(ChunkedCipherOutputStream.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final int STREAMING = -1; | |||
private final int chunkSize; | |||
@@ -70,7 +73,7 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream { | |||
super(null); | |||
this.chunkSize = chunkSize; | |||
int cs = chunkSize == STREAMING ? 4096 : chunkSize; | |||
this.chunk = new byte[cs]; | |||
this.chunk = IOUtils.safelyAllocate(cs, MAX_RECORD_LENGTH); | |||
this.plainByteFlags = new BitSet(cs); | |||
this.chunkBits = Integer.bitCount(cs-1); | |||
this.fileOut = TempFile.createTempFile("encrypted_package", "crypt"); | |||
@@ -84,7 +87,7 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream { | |||
super(stream); | |||
this.chunkSize = chunkSize; | |||
int cs = chunkSize == STREAMING ? 4096 : chunkSize; | |||
this.chunk = new byte[cs]; | |||
this.chunk = IOUtils.safelyAllocate(cs, MAX_RECORD_LENGTH); | |||
this.plainByteFlags = new BitSet(cs); | |||
this.chunkBits = Integer.bitCount(cs-1); | |||
this.fileOut = null; |
@@ -34,6 +34,7 @@ import javax.crypto.spec.IvParameterSpec; | |||
import javax.crypto.spec.RC2ParameterSpec; | |||
import org.apache.poi.EncryptedDocumentException; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
@@ -44,6 +45,10 @@ import org.apache.poi.util.StringUtil; | |||
*/ | |||
@Internal | |||
public class CryptoFunctions { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* <p><cite>2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)<br> | |||
* 2.3.4.11 Encryption Key Generation (Agile Encryption)</cite></p> | |||
@@ -280,7 +285,7 @@ public class CryptoFunctions { | |||
private static byte[] getBlockX(byte[] hash, int size, byte fill) { | |||
if (hash.length == size) return hash; | |||
byte[] result = new byte[size]; | |||
byte[] result = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
Arrays.fill(result, fill); | |||
System.arraycopy(hash, 0, result, 0, Math.min(result.length, hash.length)); | |||
return result; |
@@ -26,6 +26,7 @@ import org.apache.poi.poifs.filesystem.DirectoryEntry; | |||
import org.apache.poi.poifs.filesystem.DocumentEntry; | |||
import org.apache.poi.poifs.filesystem.POIFSWriterEvent; | |||
import org.apache.poi.poifs.filesystem.POIFSWriterListener; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianByteArrayOutputStream; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
import org.apache.poi.util.LittleEndianInput; | |||
@@ -33,6 +34,10 @@ import org.apache.poi.util.LittleEndianOutput; | |||
import org.apache.poi.util.StringUtil; | |||
public class DataSpaceMapUtils { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static void addDefaultDataSpace(DirectoryEntry dir) throws IOException { | |||
DataSpaceMapEntry dsme = new DataSpaceMapEntry( | |||
new int[]{ 0 } | |||
@@ -332,7 +337,7 @@ public class DataSpaceMapUtils { | |||
return length == 0 ? null : ""; | |||
} | |||
byte data[] = new byte[length]; | |||
byte data[] = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); | |||
is.readFully(data); | |||
// Padding (variable): A set of bytes that MUST be of correct size such that the size of the UTF-8-LP-P4 |
@@ -39,6 +39,10 @@ import org.apache.poi.util.IOUtils; | |||
* Dump internal structure of a OLE2 file into file system | |||
*/ | |||
public class POIFSDump { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
public static void main(String[] args) throws IOException { | |||
if (args.length == 0) { | |||
System.err.println("Must specify at least one file to dump"); | |||
@@ -132,7 +136,7 @@ public class POIFSDump { | |||
try { | |||
NPOIFSStream stream = new NPOIFSStream(fs, startBlock); | |||
byte[] b = new byte[fs.getBigBlockSize()]; | |||
byte[] b = IOUtils.safelyAllocate(fs.getBigBlockSize(), MAX_RECORD_LENGTH); | |||
for (ByteBuffer bb : stream) { | |||
int len = bb.remaining(); | |||
bb.get(b); |
@@ -20,6 +20,7 @@ package org.apache.poi.poifs.filesystem; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndianInput; | |||
import org.apache.poi.util.SuppressForbidden; | |||
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer; | |||
import java.util.Iterator; | |||
import org.apache.poi.poifs.property.DocumentProperty; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -224,7 +225,7 @@ public final class NDocumentInputStream extends DocumentInputStream { | |||
long rval = new_offset - _current_offset; | |||
// TODO Do this better | |||
byte[] skip = new byte[(int)rval]; | |||
byte[] skip = IOUtils.safelyAllocate(rval, Integer.MAX_VALUE); | |||
readFully(skip); | |||
return rval; | |||
} |
@@ -31,13 +31,18 @@ import org.apache.poi.poifs.common.POIFSConstants; | |||
import org.apache.poi.poifs.dev.POIFSViewable; | |||
import org.apache.poi.poifs.property.DocumentProperty; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
* This class manages a document in the NIO POIFS filesystem. | |||
* This is the {@link NPOIFSFileSystem} version. | |||
*/ | |||
public final class NPOIFSDocument implements POIFSViewable { | |||
private DocumentProperty _property; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private DocumentProperty _property; | |||
private NPOIFSFileSystem _filesystem; | |||
private NPOIFSStream _stream; | |||
@@ -147,7 +152,7 @@ public final class NPOIFSDocument implements POIFSViewable { | |||
int usedInBlock = length % _block_size; | |||
if (usedInBlock != 0 && usedInBlock != _block_size) { | |||
int toBlockEnd = _block_size - usedInBlock; | |||
byte[] padding = new byte[toBlockEnd]; | |||
byte[] padding = IOUtils.safelyAllocate(toBlockEnd, MAX_RECORD_LENGTH); | |||
Arrays.fill(padding, (byte)0xFF); | |||
os.write(padding); | |||
} | |||
@@ -214,7 +219,7 @@ public final class NPOIFSDocument implements POIFSViewable { | |||
if(getSize() > 0) { | |||
// Get all the data into a single array | |||
byte[] data = new byte[getSize()]; | |||
byte[] data = IOUtils.safelyAllocate(getSize(), MAX_RECORD_LENGTH); | |||
int offset = 0; | |||
for(ByteBuffer buffer : _stream) { | |||
int length = Math.min(_block_size, data.length-offset); |
@@ -66,7 +66,10 @@ import org.apache.poi.util.POILogger; | |||
public class NPOIFSFileSystem extends BlockStore | |||
implements POIFSViewable, Closeable | |||
{ | |||
private static final POILogger LOG = POILogFactory.getLogger(NPOIFSFileSystem.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final POILogger LOG = POILogFactory.getLogger(NPOIFSFileSystem.class); | |||
/** | |||
* Convenience method for clients that want to avoid the auto-close behaviour of the constructor. | |||
@@ -103,7 +106,8 @@ public class NPOIFSFileSystem extends BlockStore | |||
if(newFS) { | |||
// Data needs to initially hold just the header block, | |||
// a single bat block, and an empty properties section | |||
_data = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize()*3]); | |||
_data = new ByteArrayBackedDataSource(IOUtils.safelyAllocate( | |||
bigBlockSize.getBigBlockSize()*3, MAX_RECORD_LENGTH)); | |||
} | |||
} | |||
@@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
import org.apache.poi.util.LittleEndianOutputStream; | |||
@@ -34,9 +35,12 @@ import org.apache.poi.util.StringUtil; | |||
*/ | |||
public class Ole10Native { | |||
public static final String OLE10_NATIVE = "\u0001Ole10Native"; | |||
protected static final String ISO1 = "ISO-8859-1"; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000_000; | |||
// (the fields as they appear in the raw record:) | |||
private int totalSize; // 4 bytes, total size of record not including this field | |||
private short flags1 = 2; // 2 bytes, unknown, mostly [02 00] | |||
@@ -97,7 +101,7 @@ public class Ole10Native { | |||
public static Ole10Native createFromEmbeddedOleObject(DirectoryNode directory) throws IOException, Ole10NativeException { | |||
DocumentEntry nativeEntry = | |||
(DocumentEntry)directory.getEntry(OLE10_NATIVE); | |||
byte[] data = new byte[nativeEntry.getSize()]; | |||
byte[] data = IOUtils.safelyAllocate(nativeEntry.getSize(), MAX_RECORD_LENGTH); | |||
int readBytes = directory.createDocumentInputStream(nativeEntry).read(data); | |||
assert(readBytes == data.length); | |||
@@ -196,7 +200,7 @@ public class Ole10Native { | |||
if ((long)dataSize + (long)ofs > (long)data.length) { //cast to avoid overflow | |||
throw new Ole10NativeException("Invalid Ole10Native: declared data length > available data"); | |||
} | |||
dataBuffer = new byte[dataSize]; | |||
dataBuffer = IOUtils.safelyAllocate(dataSize, MAX_RECORD_LENGTH); | |||
System.arraycopy(data, ofs, dataBuffer, 0, dataSize); | |||
ofs += dataSize; | |||
} |
@@ -17,6 +17,8 @@ | |||
package org.apache.poi.poifs.nio; | |||
import org.apache.poi.util.IOUtils; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.nio.ByteBuffer; | |||
@@ -25,6 +27,9 @@ import java.nio.ByteBuffer; | |||
* A POIFS {@link DataSource} backed by a byte array. | |||
*/ | |||
public class ByteArrayBackedDataSource extends DataSource { | |||
//Can we make this shorter? | |||
private static final int MAX_RECORD_LENGTH = Integer.MAX_VALUE; | |||
private byte[] buffer; | |||
private long size; | |||
@@ -76,7 +81,8 @@ public class ByteArrayBackedDataSource extends DataSource { | |||
difference = 4096; | |||
} | |||
byte[] nb = new byte[(int)(difference+buffer.length)]; | |||
long totalLen = difference+buffer.length; | |||
byte[] nb = IOUtils.safelyAllocate(totalLen, MAX_RECORD_LENGTH); | |||
System.arraycopy(buffer, 0, nb, 0, (int)size); | |||
buffer = nb; | |||
} |
@@ -29,6 +29,7 @@ import org.apache.poi.poifs.common.POIFSConstants; | |||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; | |||
import org.apache.poi.poifs.filesystem.NPOIFSStream; | |||
import org.apache.poi.poifs.storage.HeaderBlock; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
@@ -40,6 +41,9 @@ import org.apache.poi.util.POILogger; | |||
public final class NPropertyTable extends PropertyTableBase { | |||
private static final POILogger _logger = | |||
POILogFactory.getLogger(NPropertyTable.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private POIFSBigBlockSize _bigBigBlockSize; | |||
public NPropertyTable(HeaderBlock headerBlock) | |||
@@ -86,7 +90,7 @@ public final class NPropertyTable extends PropertyTableBase { | |||
bb.array().length == bigBlockSize.getBigBlockSize()) { | |||
data = bb.array(); | |||
} else { | |||
data = new byte[bigBlockSize.getBigBlockSize()]; | |||
data = IOUtils.safelyAllocate(bigBlockSize.getBigBlockSize(), MAX_RECORD_LENGTH); | |||
int toRead = data.length; | |||
if (bb.remaining() < bigBlockSize.getBigBlockSize()) { |
@@ -32,6 +32,10 @@ import org.apache.poi.util.IOUtils; | |||
* @author Marc Johnson (mjohnson at apache dot org) | |||
*/ | |||
public final class DocumentBlock extends BigBlock { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final byte _default_value = ( byte ) 0xFF; | |||
private byte[] _data; | |||
private int _bytes_read; | |||
@@ -81,7 +85,7 @@ public final class DocumentBlock extends BigBlock { | |||
private DocumentBlock(POIFSBigBlockSize bigBlockSize) | |||
{ | |||
super(bigBlockSize); | |||
_data = new byte[ bigBlockSize.getBigBlockSize() ]; | |||
_data = IOUtils.safelyAllocate(bigBlockSize.getBigBlockSize(), MAX_RECORD_LENGTH); | |||
Arrays.fill(_data, _default_value); | |||
} | |||
@@ -41,7 +41,11 @@ import org.apache.poi.util.ShortField; | |||
* The block containing the archive header | |||
*/ | |||
public final class HeaderBlock implements HeaderBlockConstants { | |||
private static final byte _default_value = ( byte ) 0xFF; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final byte _default_value = ( byte ) 0xFF; | |||
/** | |||
* What big block size the file uses. Most files | |||
@@ -104,7 +108,7 @@ public final class HeaderBlock implements HeaderBlockConstants { | |||
// Fetch the rest of the block if needed | |||
if(bigBlockSize.getBigBlockSize() != 512) { | |||
int rest = bigBlockSize.getBigBlockSize() - 512; | |||
byte[] tmp = new byte[rest]; | |||
byte[] tmp = IOUtils.safelyAllocate(rest, MAX_RECORD_LENGTH); | |||
IOUtils.readFully(stream, tmp); | |||
} | |||
} |
@@ -35,6 +35,9 @@ import java.io.*; | |||
public class RawDataBlock | |||
implements ListManagedBlock | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private byte[] _data; | |||
private boolean _eof; | |||
private boolean _hasData; | |||
@@ -66,7 +69,7 @@ public class RawDataBlock | |||
*/ | |||
public RawDataBlock(final InputStream stream, int blockSize) | |||
throws IOException { | |||
_data = new byte[ blockSize ]; | |||
_data = IOUtils.safelyAllocate(blockSize, MAX_RECORD_LENGTH); | |||
int count = IOUtils.readFully(stream, _data); | |||
_hasData = (count > 0); | |||
@@ -23,6 +23,7 @@ import org.apache.poi.ss.formula.ptg.ExpPtg; | |||
import org.apache.poi.ss.formula.ptg.Ptg; | |||
import org.apache.poi.ss.formula.ptg.TblPtg; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianByteArrayInputStream; | |||
import org.apache.poi.util.LittleEndianInput; | |||
@@ -35,6 +36,9 @@ import org.apache.poi.util.LittleEndianOutput; | |||
*/ | |||
public class Formula { | |||
//Arbitrarily set. May need to increase. | |||
private static final int MAX_ENCODED_LEN = 100000; | |||
private static final Formula EMPTY = new Formula(new byte[0], 0); | |||
/** immutable */ | |||
@@ -72,7 +76,7 @@ public class Formula { | |||
* @return A new formula object as read from the stream. Possibly empty, never <code>null</code>. | |||
*/ | |||
public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) { | |||
byte[] byteEncoding = new byte[totalEncodedLen]; | |||
byte[] byteEncoding = IOUtils.safelyAllocate(totalEncodedLen, MAX_ENCODED_LEN); | |||
in.readFully(byteEncoding); | |||
return new Formula(byteEncoding, encodedTokenLen); | |||
} |
@@ -28,6 +28,7 @@ import java.util.Set; | |||
import java.util.regex.Pattern; | |||
import org.apache.poi.ss.formula.ptg.Ptg; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
* Converts the text meta-data file into a <tt>FunctionMetadataRegistry</tt> | |||
@@ -36,6 +37,9 @@ import org.apache.poi.ss.formula.ptg.Ptg; | |||
*/ | |||
final class FunctionMetadataReader { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private static final String METADATA_FILE_NAME = "functionMetadata.txt"; | |||
/** plain ASCII text metadata file uses three dots for ellipsis */ | |||
@@ -141,7 +145,7 @@ final class FunctionMetadataReader { | |||
// (all unspecified params are assumed to be the same as the last) | |||
nItems --; | |||
} | |||
byte[] result = new byte[nItems]; | |||
byte[] result = IOUtils.safelyAllocate(nItems, MAX_RECORD_LENGTH); | |||
for (int i = 0; i < nItems; i++) { | |||
result[i] = parseOperandTypeCode(array[i]); | |||
} |
@@ -34,12 +34,26 @@ public final class IOUtils { | |||
* The default buffer size to use for the skip() methods. | |||
*/ | |||
private static final int SKIP_BUFFER_SIZE = 2048; | |||
private static int BYTE_ARRAY_MAX_OVERRIDE = -1; | |||
private static byte[] SKIP_BYTE_BUFFER; | |||
private IOUtils() { | |||
// no instances of this class | |||
} | |||
/** | |||
* If this value is set to > 0, {@link #safelyAllocate(long, int)} will ignore the | |||
* maximum record length parameter. This is designed to allow users to bypass | |||
* the hard-coded maximum record lengths if they are willing to accept the risk | |||
* of an OutOfMemoryException. | |||
* | |||
* @param maxOverride | |||
* @since 4.0.0 | |||
*/ | |||
public static void setByteArrayMaxOverride(int maxOverride) { | |||
BYTE_ARRAY_MAX_OVERRIDE = maxOverride; | |||
} | |||
/** | |||
* Peeks at the first 8 bytes of the stream. Returns those bytes, but | |||
* with the stream unaffected. Requires a stream that supports mark/reset, | |||
@@ -480,12 +494,23 @@ public final class IOUtils { | |||
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"); | |||
if (BYTE_ARRAY_MAX_OVERRIDE > 0) { | |||
if (length > BYTE_ARRAY_MAX_OVERRIDE) { | |||
throwRFE(length, BYTE_ARRAY_MAX_OVERRIDE); | |||
} | |||
} else if (length > maxLength) { | |||
throwRFE(length, maxLength); | |||
} | |||
return new byte[(int)length]; | |||
} | |||
private static void throwRFE(long length, int maxLength) { | |||
throw new RecordFormatException("Tried to allocate an array of length "+length + | |||
", but "+ maxLength+" is the maximum for this record type.\n" + | |||
"If the file is not corrupt, please open an issue on bugzilla to request \n" + | |||
"increasing the maximum allowable size for this record type.\n"+ | |||
"As a temporary workaround, consider setting a higher override value with " + | |||
"IOUtils.setByteArrayMaxOverride()"); | |||
} | |||
} |
@@ -32,6 +32,10 @@ import java.io.OutputStream; | |||
* http://marknelson.us/1989/10/01/lzw-data-compression/ | |||
*/ | |||
public abstract class LZWDecompresser { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** | |||
* Does the mask bit mean it's compressed or uncompressed? | |||
*/ | |||
@@ -119,7 +123,7 @@ public abstract class LZWDecompresser { | |||
// These are bytes as looked up in the dictionary | |||
// It needs to be signed, as it'll get passed on to | |||
// the output stream | |||
byte[] dataB = new byte[16+codeLengthIncrease]; | |||
byte[] dataB = IOUtils.safelyAllocate(16+codeLengthIncrease, MAX_RECORD_LENGTH); | |||
// This is an unsigned byte read from the stream | |||
// It needs to be unsigned, so that bit stuff works | |||
int dataI; |
@@ -63,6 +63,9 @@ public class LittleEndian implements LittleEndianConsts | |||
* @param size | |||
* Number of bytes to copy. | |||
* @return The byteArray value | |||
* | |||
* @see #getByteArray(byte[], int, int, long) if size is not a constant | |||
* | |||
* @throws IndexOutOfBoundsException | |||
* - if copying would cause access of data outside array bounds. | |||
*/ | |||
@@ -74,6 +77,31 @@ public class LittleEndian implements LittleEndianConsts | |||
return copy; | |||
} | |||
/** | |||
* Copy a portion of a byte array | |||
* | |||
* @param data | |||
* the original byte array | |||
* @param offset | |||
* Where to start copying from. | |||
* @param size | |||
* Number of bytes to copy. | |||
* @param maxSize | |||
* Size must be <= maxSize or an exception is thrown. | |||
* Use this to avoid potential OOMs on corrupt data. | |||
* @return The byteArray value | |||
* @throws IndexOutOfBoundsException | |||
* - if copying would cause access of data outside array bounds. | |||
*/ | |||
public static byte[] getByteArray( byte[] data, int offset, int size, int maxSize) | |||
{ | |||
byte[] copy = IOUtils.safelyAllocate(size, maxSize); | |||
System.arraycopy( data, offset, copy, 0, size ); | |||
return copy; | |||
} | |||
/** | |||
* get a double value from a byte array, reads it in little endian format | |||
* then converts the resulting revolting IEEE 754 (curse them) floating |
@@ -28,6 +28,9 @@ import java.util.Map; | |||
@Internal | |||
public class StringUtil { | |||
protected static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 10000000; | |||
public static final Charset UTF16LE = Charset.forName("UTF-16LE"); | |||
public static final Charset UTF8 = Charset.forName("UTF-8"); | |||
public static final Charset WIN_1252 = Charset.forName("cp1252"); | |||
@@ -118,7 +121,7 @@ public class StringUtil { | |||
} | |||
public static String readCompressedUnicode(LittleEndianInput in, int nChars) { | |||
byte[] buf = new byte[nChars]; | |||
byte[] buf = IOUtils.safelyAllocate(nChars, MAX_RECORD_LENGTH); | |||
in.readFully(buf); | |||
return new String(buf, ISO_8859_1); | |||
} | |||
@@ -252,7 +255,7 @@ public class StringUtil { | |||
} | |||
public static String readUnicodeLE(LittleEndianInput in, int nChars) { | |||
byte[] bytes = new byte[nChars*2]; | |||
byte[] bytes = IOUtils.safelyAllocate(nChars*2, MAX_RECORD_LENGTH); | |||
in.readFully(bytes); | |||
return new String(bytes, UTF16LE); | |||
} |
@@ -58,6 +58,7 @@ import org.apache.poi.poifs.crypt.HashAlgorithm; | |||
import org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier.AgileCertificateEntry; | |||
import org.apache.poi.poifs.crypt.standard.EncryptionRecord; | |||
import org.apache.poi.poifs.filesystem.DirectoryNode; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianByteArrayOutputStream; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
@@ -76,6 +77,10 @@ import com.microsoft.schemas.office.x2006.keyEncryptor.certificate.CTCertificate | |||
import com.microsoft.schemas.office.x2006.keyEncryptor.password.CTPasswordKeyEncryptor; | |||
public class AgileEncryptor extends Encryptor implements Cloneable { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private byte integritySalt[]; | |||
private byte pwHash[]; | |||
@@ -91,11 +96,11 @@ public class AgileEncryptor extends Encryptor implements Cloneable { | |||
int keySize = header.getKeySize()/8; | |||
int hashSize = header.getHashAlgorithm().hashSize; | |||
byte[] newVerifierSalt = new byte[blockSize] | |||
, newVerifier = new byte[blockSize] | |||
, newKeySalt = new byte[blockSize] | |||
, newKeySpec = new byte[keySize] | |||
, newIntegritySalt = new byte[hashSize]; | |||
byte[] newVerifierSalt = IOUtils.safelyAllocate(blockSize, MAX_RECORD_LENGTH) | |||
, newVerifier = IOUtils.safelyAllocate(blockSize, MAX_RECORD_LENGTH) | |||
, newKeySalt = IOUtils.safelyAllocate(blockSize, MAX_RECORD_LENGTH) | |||
, newKeySpec = IOUtils.safelyAllocate(keySize, MAX_RECORD_LENGTH) | |||
, newIntegritySalt = IOUtils.safelyAllocate(hashSize, MAX_RECORD_LENGTH); | |||
r.nextBytes(newVerifierSalt); // blocksize | |||
r.nextBytes(newVerifier); // blocksize | |||
r.nextBytes(newKeySalt); // blocksize |
@@ -57,7 +57,9 @@ import org.apache.poi.xssf.usermodel.XSSFObjectData; | |||
@Beta | |||
public class EmbeddedExtractor implements Iterable<EmbeddedExtractor> { | |||
private static final POILogger LOG = POILogFactory.getLogger(EmbeddedExtractor.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
// contentType | |||
private static final String CONTENT_TYPE_BYTES = "binary/octet-stream"; | |||
private static final String CONTENT_TYPE_PDF = "application/pdf"; | |||
@@ -252,7 +254,7 @@ public class EmbeddedExtractor implements Iterable<EmbeddedExtractor> { | |||
} | |||
int pictureBytesLen = idxEnd-idxStart+6; | |||
byte[] pdfBytes = new byte[pictureBytesLen]; | |||
byte[] pdfBytes = IOUtils.safelyAllocate(pictureBytesLen, MAX_RECORD_LENGTH); | |||
System.arraycopy(pictureBytes, idxStart, pdfBytes, 0, pictureBytesLen); | |||
String filename = source.getShapeName().trim(); | |||
if (!endsWithIgnoreCase(filename, ".pdf")) { |
@@ -73,6 +73,8 @@ import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument | |||
public class XMLSlideShow extends POIXMLDocument | |||
implements SlideShow<XSLFShape,XSLFTextParagraph> { | |||
private static final POILogger LOG = POILogFactory.getLogger(XMLSlideShow.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private CTPresentation _presentation; | |||
private List<XSLFSlide> _slides; | |||
@@ -533,7 +535,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> { | |||
public XSLFPictureData addPicture(File pict, PictureType format) throws IOException | |||
{ | |||
int length = (int) pict.length(); | |||
byte[] data = new byte[length]; | |||
byte[] data = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); | |||
FileInputStream is = new FileInputStream(pict); | |||
try { | |||
IOUtils.readFully(is, data); |
@@ -21,6 +21,7 @@ import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.BitSet; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndianInputStream; | |||
@@ -34,6 +35,9 @@ import org.apache.poi.util.LittleEndianInputStream; | |||
@Internal | |||
public abstract class XSSFBParser { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private final LittleEndianInputStream is; | |||
private final BitSet records; | |||
@@ -88,8 +92,7 @@ public abstract class XSSFBParser { | |||
} | |||
if (records == null || records.get(recordId)) { | |||
//add sanity check for length? | |||
byte[] buff = new byte[(int) recordLength]; | |||
byte[] buff = IOUtils.safelyAllocate(recordLength, MAX_RECORD_LENGTH); | |||
is.readFully(buff); | |||
handleRecord(recordId, buff); | |||
} else { |
@@ -26,6 +26,7 @@ import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.StringTokenizer; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LocaleUtil; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
@@ -38,6 +39,11 @@ import org.apache.poi.util.POILogger; | |||
* to process the chunk value area | |||
*/ | |||
public final class ChunkFactory { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** The version of the currently open document */ | |||
private int version; | |||
/** | |||
@@ -179,7 +185,7 @@ public final class ChunkFactory { | |||
} | |||
// Now, create the chunk | |||
byte[] contents = new byte[header.getLength()]; | |||
byte[] contents = IOUtils.safelyAllocate(header.getLength(), MAX_RECORD_LENGTH); | |||
System.arraycopy(data, offset+header.getSizeInBytes(), contents, 0, contents.length); | |||
Chunk chunk = new Chunk(header, trailer, separator, contents); | |||
@@ -21,12 +21,17 @@ import java.io.ByteArrayInputStream; | |||
import java.io.IOException; | |||
import org.apache.poi.hdgf.HDGFLZW; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
* A StreamStore where the data on-disk is compressed, | |||
* using the crazy Visio LZW | |||
*/ | |||
public final class CompressedStreamStore extends StreamStore { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** The raw, compressed contents */ | |||
private byte[] compressedContents; | |||
/** | |||
@@ -46,7 +51,7 @@ public final class CompressedStreamStore extends StreamStore { | |||
protected CompressedStreamStore(byte[] data, int offset, int length) throws IOException { | |||
this(decompress(data,offset,length)); | |||
compressedContents = new byte[length]; | |||
compressedContents = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); | |||
System.arraycopy(data, offset, compressedContents, 0, length); | |||
} | |||
/** |
@@ -17,24 +17,29 @@ | |||
package org.apache.poi.hdgf.streams; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
* Holds the representation of the stream on-disk, and | |||
* handles de-compressing it as required. | |||
* In future, may also handle writing it back out again | |||
*/ | |||
public class StreamStore { // TODO - instantiable superclass | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 10_000_000; | |||
private byte[] contents; | |||
/** | |||
* Creates a new, non compressed Stream Store | |||
*/ | |||
protected StreamStore(byte[] data, int offset, int length) { | |||
contents = new byte[length]; | |||
contents = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); | |||
System.arraycopy(data, offset, contents, 0, length); | |||
} | |||
protected void prependContentsWith(byte[] b) { | |||
byte[] newContents = new byte[contents.length + b.length]; | |||
byte[] newContents = IOUtils.safelyAllocate(contents.length + b.length, MAX_RECORD_LENGTH); | |||
System.arraycopy(b, 0, newContents, 0, b.length); | |||
System.arraycopy(contents, 0, newContents, b.length, contents.length); | |||
contents = newContents; |
@@ -34,7 +34,7 @@ import org.apache.poi.util.RecordFormatException; | |||
@Internal | |||
public class HemfCommentEMFPlus extends AbstractHemfComment { | |||
private static final int MAX_RECORD_LENGTH = 1000000; | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
long dataSize; |
@@ -36,7 +36,7 @@ import org.apache.poi.util.RecordFormatException; | |||
@Internal | |||
public class HemfCommentPublic { | |||
private static final int MAX_RECORD_LENGTH = 1000000; | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** |
@@ -36,7 +36,7 @@ import org.apache.poi.util.RecordFormatException; | |||
*/ | |||
@Internal | |||
public class HemfCommentRecord implements HemfRecord { | |||
private static final int MAX_RECORD_LENGTH = 1000000; | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
public final static long COMMENT_EMFSPOOL = 0x00000000; | |||
public final static long COMMENT_EMFPLUS = 0x2B464D45; |
@@ -32,7 +32,7 @@ import org.apache.poi.util.LittleEndianInputStream; | |||
@Internal | |||
public class HemfHeader implements HemfRecord { | |||
private static final int MAX_RECORD_LENGTH = 1000000; | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private Rectangle boundsRectangle; |
@@ -40,7 +40,7 @@ import org.apache.poi.util.RecordFormatException; | |||
public class HemfText { | |||
private static final Charset UTF16LE = Charset.forName("UTF-16LE"); | |||
private static final int MAX_RECORD_LENGTH = 1000000; | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
public static class ExtCreateFontIndirectW extends UnimplementedHemfRecord { | |||
} |
@@ -38,6 +38,10 @@ import org.apache.poi.util.StringUtil; | |||
* or one of its {@link Attachment}s. | |||
*/ | |||
public class MAPIAttribute { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private final MAPIProperty property; | |||
private final int type; | |||
private final byte[] data; | |||
@@ -144,7 +148,7 @@ public class MAPIAttribute { | |||
} else { | |||
// Custom name was stored | |||
int mplen = LittleEndian.readInt(inp); | |||
byte[] mpdata = new byte[mplen]; | |||
byte[] mpdata = IOUtils.safelyAllocate(mplen, MAX_RECORD_LENGTH); | |||
IOUtils.readFully(inp, mpdata); | |||
name = StringUtil.getFromUnicodeLE(mpdata, 0, (mplen/2)-1); | |||
skipToBoundary(mplen, inp); | |||
@@ -164,7 +168,7 @@ public class MAPIAttribute { | |||
} | |||
for(int j=0; j<values; j++) { | |||
int len = getLength(type, inp); | |||
byte[] data = new byte[len]; | |||
byte[] data = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
IOUtils.readFully(inp, data); | |||
skipToBoundary(len, inp); | |||
@@ -203,9 +207,11 @@ public class MAPIAttribute { | |||
private static void skipToBoundary(int length, InputStream inp) throws IOException { | |||
// Data is always padded out to a 4 byte boundary | |||
if(length % 4 != 0) { | |||
int skip = 4 - (length % 4); | |||
byte[] padding = new byte[skip]; | |||
IOUtils.readFully(inp, padding); | |||
int toSkip = 4 - (length % 4); | |||
long skipped = IOUtils.skipFully(inp, toSkip); | |||
if (skipped != toSkip) { | |||
throw new IOException("tried to skip "+toSkip +" but only skipped:"+skipped); | |||
} | |||
} | |||
} | |||
} |
@@ -24,6 +24,7 @@ import org.apache.poi.hmef.Attachment; | |||
import org.apache.poi.hmef.CompressedRTF; | |||
import org.apache.poi.hmef.HMEFMessage; | |||
import org.apache.poi.hsmf.datatypes.MAPIProperty; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.StringUtil; | |||
/** | |||
@@ -31,6 +32,10 @@ import org.apache.poi.util.StringUtil; | |||
* to a {@link HMEFMessage} or one of its {@link Attachment}s. | |||
*/ | |||
public final class MAPIRtfAttribute extends MAPIAttribute { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private final byte[] decompressed; | |||
private final String data; | |||
@@ -41,7 +46,7 @@ public final class MAPIRtfAttribute extends MAPIAttribute { | |||
CompressedRTF rtf = new CompressedRTF(); | |||
byte[] tmp = rtf.decompress(new ByteArrayInputStream(data)); | |||
if(tmp.length > rtf.getDeCompressedSize()) { | |||
this.decompressed = new byte[rtf.getDeCompressedSize()]; | |||
this.decompressed = IOUtils.safelyAllocate(rtf.getDeCompressedSize(), MAX_RECORD_LENGTH); | |||
System.arraycopy(tmp, 0, decompressed, 0, decompressed.length); | |||
} else { | |||
this.decompressed = tmp; |
@@ -33,6 +33,10 @@ import org.apache.poi.util.LittleEndian; | |||
* ones, so we can't just re-use the HSMF ones. | |||
*/ | |||
public class TNEFAttribute { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private final TNEFProperty property; | |||
private final int type; | |||
private final byte[] data; | |||
@@ -47,7 +51,7 @@ public class TNEFAttribute { | |||
int length = LittleEndian.readInt(inp); | |||
property = TNEFProperty.getBest(id, type); | |||
data = new byte[length]; | |||
data = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); | |||
IOUtils.readFully(inp, data); | |||
checksum = LittleEndian.readUShort(inp); |
@@ -29,12 +29,17 @@ import org.apache.poi.hmef.attribute.TNEFDateAttribute; | |||
import org.apache.poi.hmef.attribute.TNEFProperty; | |||
import org.apache.poi.hmef.attribute.TNEFStringAttribute; | |||
import org.apache.poi.util.HexDump; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
* Developer focused raw dumper | |||
*/ | |||
public final class HMEFDumper { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
public static void main(String[] args) throws Exception { | |||
if(args.length < 1) { | |||
throw new IllegalArgumentException("Filename must be given"); | |||
@@ -138,7 +143,7 @@ public final class HMEFDumper { | |||
thisLen = len - offset; | |||
} | |||
byte data[] = new byte[thisLen]; | |||
byte data[] = IOUtils.safelyAllocate(thisLen, MAX_RECORD_LENGTH); | |||
System.arraycopy(attr.getData(), offset, data, 0, thisLen); | |||
System.out.print( |
@@ -23,11 +23,16 @@ import java.util.ArrayList; | |||
import org.apache.poi.ddf.DefaultEscherRecordFactory; | |||
import org.apache.poi.ddf.EscherRecord; | |||
import org.apache.poi.poifs.filesystem.DirectoryNode; | |||
import org.apache.poi.util.IOUtils; | |||
/** | |||
* Parent class of all Escher parts | |||
*/ | |||
public abstract class EscherPart extends HPBFPart { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private EscherRecord[] records; | |||
/** | |||
@@ -69,7 +74,7 @@ public abstract class EscherPart extends HPBFPart { | |||
size += records[i].getRecordSize(); | |||
} | |||
byte data[] = new byte[size]; | |||
byte data[] = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
size = 0; | |||
for(int i=0; i<records.length; i++) { | |||
int thisSize = |
@@ -24,6 +24,7 @@ import org.apache.poi.hpbf.model.qcbits.QCPLCBit; | |||
import org.apache.poi.hpbf.model.qcbits.QCTextBit; | |||
import org.apache.poi.hpbf.model.qcbits.UnknownQCBit; | |||
import org.apache.poi.poifs.filesystem.DirectoryNode; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LocaleUtil; | |||
import org.apache.poi.util.POILogFactory; | |||
@@ -34,6 +35,8 @@ import org.apache.poi.util.POILogger; | |||
*/ | |||
public final class QuillContents extends HPBFPart { | |||
private static POILogger logger = POILogFactory.getLogger(QuillContents.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private static final String[] PATH = { "Quill", "QuillSub", "CONTENTS", }; | |||
private QCBit[] bits; | |||
@@ -66,7 +69,7 @@ public final class QuillContents extends HPBFPart { | |||
int from = (int)LittleEndian.getUInt(data, offset+16); | |||
int len = (int)LittleEndian.getUInt(data, offset+20); | |||
byte[] bitData = new byte[len]; | |||
byte[] bitData = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
System.arraycopy(data, from, bitData, 0, len); | |||
// Create |
@@ -17,12 +17,17 @@ | |||
package org.apache.poi.hpbf.model.qcbits; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.StringUtil; | |||
/** | |||
* A Text based bit of Quill Contents | |||
*/ | |||
public final class QCTextBit extends QCBit { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
public QCTextBit(String thingType, String bitType, byte[] data) { | |||
super(thingType, bitType, data); | |||
} | |||
@@ -36,7 +41,7 @@ public final class QCTextBit extends QCBit { | |||
} | |||
public void setText(String text) { | |||
byte data[] = new byte[text.length()*2]; | |||
byte data[] = IOUtils.safelyAllocate(text.length()*2, MAX_RECORD_LENGTH); | |||
StringUtil.putUnicodeLE(text, data, 0); | |||
setData(data); | |||
} |
@@ -26,6 +26,7 @@ import java.io.IOException; | |||
import javax.imageio.ImageIO; | |||
import org.apache.poi.hslf.usermodel.HSLFPictureData; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.Units; | |||
/** | |||
@@ -38,7 +39,7 @@ public abstract class Bitmap extends HSLFPictureData { | |||
public byte[] getData(){ | |||
byte[] rawdata = getRawData(); | |||
int prefixLen = 16*getUIDInstanceCount()+1; | |||
byte[] imgdata = new byte[rawdata.length-prefixLen]; | |||
byte[] imgdata = IOUtils.safelyAllocate(rawdata.length-prefixLen, rawdata.length); | |||
System.arraycopy(rawdata, prefixLen, imgdata, 0, imgdata.length); | |||
return imgdata; | |||
} |
@@ -19,12 +19,17 @@ package org.apache.poi.hslf.blip; | |||
import java.io.IOException; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
* Represents a DIB picture data in a PPT file | |||
*/ | |||
public final class DIB extends Bitmap { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** | |||
* Size of the BITMAPFILEHEADER structure preceding the actual DIB bytes | |||
*/ | |||
@@ -87,7 +92,7 @@ public final class DIB extends Bitmap { | |||
LittleEndian.putInt(header, 10, offset); | |||
//DIB data is the header + dib bytes | |||
byte[] dib = new byte[header.length + data.length]; | |||
byte[] dib = IOUtils.safelyAllocate(header.length + data.length, MAX_RECORD_LENGTH); | |||
System.arraycopy(header, 0, dib, 0, header.length); | |||
System.arraycopy(data, 0, dib, header.length, data.length); | |||
@@ -97,7 +102,7 @@ public final class DIB extends Bitmap { | |||
@Override | |||
public void setData(byte[] data) throws IOException { | |||
//cut off the bitmap file-header | |||
byte[] dib = new byte[data.length-HEADER_SIZE]; | |||
byte[] dib = IOUtils.safelyAllocate(data.length-HEADER_SIZE, data.length); | |||
System.arraycopy(data, HEADER_SIZE, dib, 0, dib.length); | |||
super.setData(dib); | |||
} |
@@ -39,6 +39,10 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public final class PPTXMLDump { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private static final int HEADER_SIZE = 8; //size of the record header | |||
private static final int PICT_HEADER_SIZE = 25; //size of the picture header | |||
private static final String PICTURES_ENTRY = "Pictures"; | |||
@@ -164,7 +168,7 @@ public final class PPTXMLDump { | |||
System.arraycopy(data, pos, header, 0, header.length); | |||
int size = LittleEndian.getInt(header, 4) - 17; | |||
byte[] pictdata = new byte[size]; | |||
byte[] pictdata = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
System.arraycopy(data, pos + PICT_HEADER_SIZE, pictdata, 0, pictdata.length); | |||
pos += PICT_HEADER_SIZE + size; | |||
@@ -48,7 +48,11 @@ import org.apache.poi.util.LittleEndian; | |||
* from hslf.record.RecordTypes also) | |||
*/ | |||
public final class SlideShowDumper { | |||
private byte[] docstream; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private byte[] docstream; | |||
/** Do we try to use DDF to understand the escher objects? */ | |||
private boolean ddfEscher; | |||
@@ -209,7 +213,7 @@ public void walkTree(int depth, int startPos, int maxLen) throws IOException { | |||
final String ind = (indent == 0) ? "%1$s" : "%1$"+indent+"s"; | |||
byte[] contents = new byte[len]; | |||
byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
System.arraycopy(docstream,pos,contents,0,len); | |||
DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory(); | |||
EscherRecord record = erf.createRecord(contents,0); |
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -29,6 +30,9 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public final class AnimationInfoAtom extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* whether the animation plays in the reverse direction | |||
*/ | |||
@@ -98,7 +102,7 @@ public final class AnimationInfoAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Grab the record data | |||
_recdata = new byte[len-8]; | |||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_recdata,0,len-8); | |||
} | |||
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.StringUtil; | |||
@@ -32,6 +33,10 @@ import org.apache.poi.util.StringUtil; | |||
*/ | |||
public final class CString extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private byte[] _header; | |||
private static long _type = 4026l; | |||
@@ -83,7 +88,7 @@ public final class CString extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Grab the text | |||
_text = new byte[len-8]; | |||
_text = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_text,0,len-8); | |||
} | |||
/** |
@@ -22,6 +22,7 @@ import java.io.OutputStream; | |||
import java.util.Date; | |||
import org.apache.poi.hslf.util.SystemTimeUtils; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -32,6 +33,10 @@ import org.apache.poi.util.LittleEndian; | |||
public final class Comment2000Atom extends RecordAtom | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* Record header. | |||
*/ | |||
@@ -68,7 +73,7 @@ public final class Comment2000Atom extends RecordAtom | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
} | |||
@@ -31,6 +31,7 @@ import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; | |||
import org.apache.poi.poifs.filesystem.DirectoryNode; | |||
import org.apache.poi.poifs.filesystem.DocumentEntry; | |||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
@@ -44,6 +45,8 @@ import org.apache.poi.util.StringUtil; | |||
public class CurrentUserAtom | |||
{ | |||
private final static POILogger logger = POILogFactory.getLogger(CurrentUserAtom.class); | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** Standard Atom header */ | |||
public static final byte[] atomHeader = new byte[] { 0, 0, -10, 15 }; | |||
@@ -127,7 +130,7 @@ public class CurrentUserAtom | |||
// Grab the contents | |||
int len = docProps.getSize(); | |||
_contents = new byte[len]; | |||
_contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
InputStream in = dir.createDocumentInputStream("Current User"); | |||
int readLen = in.read(_contents); | |||
in.close(); | |||
@@ -197,12 +200,12 @@ public class CurrentUserAtom | |||
int len = 2*(int)usernameLen; | |||
if(_contents.length >= start+len) { | |||
byte[] textBytes = new byte[len]; | |||
byte[] textBytes = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
System.arraycopy(_contents,start,textBytes,0,len); | |||
lastEditUser = StringUtil.getFromUnicodeLE(textBytes); | |||
} else { | |||
// Fake from the 8 bit version | |||
byte[] textBytes = new byte[(int)usernameLen]; | |||
byte[] textBytes = IOUtils.safelyAllocate(usernameLen, MAX_RECORD_LENGTH); | |||
System.arraycopy(_contents,28,textBytes,0,(int)usernameLen); | |||
lastEditUser = StringUtil.getFromCompressedUnicode(textBytes,0,(int)usernameLen); | |||
} | |||
@@ -219,7 +222,7 @@ public class CurrentUserAtom | |||
// 4 = revision | |||
// 3 * len = ascii + unicode | |||
int size = 8 + 20 + 4 + (3 * lastEditUser.length()); | |||
_contents = new byte[size]; | |||
_contents = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH); | |||
// First we have a 8 byte atom header | |||
System.arraycopy(atomHeader,0,_contents,0,4); | |||
@@ -238,7 +241,7 @@ public class CurrentUserAtom | |||
// The username gets stored twice, once as US | |||
// ascii, and again as unicode laster on | |||
byte[] asciiUN = new byte[lastEditUser.length()]; | |||
byte[] asciiUN = IOUtils.safelyAllocate(lastEditUser.length(), MAX_RECORD_LENGTH); | |||
StringUtil.putCompressedUnicode(lastEditUser,asciiUN,0); | |||
// Now we're able to do the length of the last edited user | |||
@@ -260,7 +263,7 @@ public class CurrentUserAtom | |||
LittleEndian.putInt(_contents,28+asciiUN.length,(int)releaseVersion); | |||
// username in unicode | |||
byte [] ucUN = new byte[lastEditUser.length()*2]; | |||
byte [] ucUN = IOUtils.safelyAllocate(lastEditUser.length()*2, MAX_RECORD_LENGTH); | |||
StringUtil.putUnicodeLE(lastEditUser,ucUN,0); | |||
System.arraycopy(ucUN,0,_contents,28+asciiUN.length+4,ucUN.length); | |||
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hslf.record; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
@@ -30,6 +31,9 @@ import java.io.OutputStream; | |||
public final class DocumentAtom extends RecordAtom | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private byte[] _header; | |||
private static long _type = 1001l; | |||
@@ -137,7 +141,7 @@ public final class DocumentAtom extends RecordAtom | |||
showComments = source[start+39+8]; | |||
// If there's any other bits of data, keep them about | |||
reserved = new byte[len-40-8]; | |||
reserved = IOUtils.safelyAllocate(len-40-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+48,reserved,0,reserved.length); | |||
} | |||
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -40,6 +41,9 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public class ExEmbedAtom extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** | |||
* Embedded document does not follow the color scheme. | |||
*/ | |||
@@ -91,7 +95,7 @@ public class ExEmbedAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
// Must be at least 8 bytes long |
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -29,6 +30,10 @@ import org.apache.poi.util.LittleEndian; | |||
* @author Nick Burch | |||
*/ | |||
public final class ExHyperlinkAtom extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* Record header. | |||
*/ | |||
@@ -66,7 +71,7 @@ public final class ExHyperlinkAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
// Must be at least 4 bytes long |
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -29,6 +30,8 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public final class ExMediaAtom extends RecordAtom | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** | |||
* A bit that specifies whether the audio or video data is repeated continuously during playback. | |||
@@ -78,7 +81,7 @@ public final class ExMediaAtom extends RecordAtom | |||
System.arraycopy(source,start,_header,0,8); | |||
// Grab the record data | |||
_recdata = new byte[len-8]; | |||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_recdata,0,len-8); | |||
} | |||
@@ -21,6 +21,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -31,6 +32,10 @@ import org.apache.poi.util.LittleEndian; | |||
public class ExObjListAtom extends RecordAtom | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** | |||
* Record header. | |||
*/ | |||
@@ -68,7 +73,7 @@ public class ExObjListAtom extends RecordAtom | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
// Must be at least 4 bytes long |
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -65,6 +66,9 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public class ExOleObjAtom extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** | |||
* The object) is displayed as an embedded object inside of a container, | |||
*/ | |||
@@ -148,7 +152,7 @@ public class ExOleObjAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
// Must be at least 24 bytes long |
@@ -27,6 +27,7 @@ import java.util.zip.DeflaterOutputStream; | |||
import java.util.zip.InflaterInputStream; | |||
import org.apache.poi.util.BoundedInputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -34,6 +35,9 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public class ExOleObjStg extends PositionDependentRecordAtom implements PersistRecord { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private int _persistId; // Found from PersistPtrHolder | |||
/** | |||
@@ -72,7 +76,7 @@ public class ExOleObjStg extends PositionDependentRecordAtom implements PersistR | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
} | |||
@@ -22,6 +22,7 @@ import java.io.OutputStream; | |||
import java.util.Arrays; | |||
import org.apache.poi.hslf.exceptions.HSLFException; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.StringUtil; | |||
@@ -35,7 +36,11 @@ import org.apache.poi.util.StringUtil; | |||
*/ | |||
public final class FontEntityAtom extends RecordAtom { | |||
/** | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
/** | |||
* record header | |||
*/ | |||
private byte[] _header; | |||
@@ -54,7 +59,7 @@ public final class FontEntityAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Grab the record data | |||
_recdata = new byte[len-8]; | |||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_recdata,0,len-8); | |||
} | |||
@@ -27,6 +27,7 @@ import org.apache.poi.ddf.EscherClientDataRecord; | |||
import org.apache.poi.ddf.EscherRecordFactory; | |||
import org.apache.poi.ddf.EscherSerializationListener; | |||
import org.apache.poi.hslf.exceptions.HSLFException; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -38,6 +39,9 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public class HSLFEscherClientDataRecord extends EscherClientDataRecord { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private final List<Record> _childRecords = new ArrayList<>(); | |||
public List<? extends Record> getHSLFChildRecords() { | |||
@@ -60,7 +64,7 @@ public class HSLFEscherClientDataRecord extends EscherClientDataRecord { | |||
@Override | |||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { | |||
int bytesRemaining = readHeader( data, offset ); | |||
byte remainingData[] = new byte[bytesRemaining]; | |||
byte remainingData[] = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH); | |||
System.arraycopy(data, offset+8, remainingData, 0, bytesRemaining); | |||
setRemainingData(remainingData); | |||
return bytesRemaining + 8; |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hslf.record; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
@@ -30,6 +31,10 @@ import java.io.OutputStream; | |||
public final class HeadersFootersAtom extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* A bit that specifies whether the date is displayed in the footer. | |||
* @see #getMask() | |||
@@ -96,7 +101,7 @@ public final class HeadersFootersAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Grab the record data | |||
_recdata = new byte[len-8]; | |||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_recdata,0,len-8); | |||
} | |||
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.record; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -31,6 +32,10 @@ import org.apache.poi.util.LittleEndian; | |||
*/ | |||
public class InteractiveInfoAtom extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* Action Table | |||
*/ | |||
@@ -105,7 +110,7 @@ public class InteractiveInfoAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
// Must be at least 16 bytes long |
@@ -24,6 +24,7 @@ import java.util.Collections; | |||
import java.util.List; | |||
import org.apache.poi.hslf.model.textproperties.IndentProp; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.POILogger; | |||
@@ -31,6 +32,10 @@ import org.apache.poi.util.POILogger; | |||
* Specifies the Indent Level for the text | |||
*/ | |||
public final class MasterTextPropAtom extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
/** | |||
* Record header. | |||
*/ | |||
@@ -71,7 +76,7 @@ public final class MasterTextPropAtom extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the record data. | |||
_data = new byte[len-8]; | |||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_data,0,len-8); | |||
try { | |||
@@ -108,7 +113,7 @@ public final class MasterTextPropAtom extends RecordAtom { | |||
*/ | |||
private void write() { | |||
int pos = 0; | |||
_data = new byte[indents.size()*6]; | |||
_data = IOUtils.safelyAllocate(indents.size()*6, MAX_RECORD_LENGTH); | |||
for (IndentProp prop : indents) { | |||
LittleEndian.putInt(_data, pos, prop.getCharactersCovered()); | |||
LittleEndian.putShort(_data, pos+4, (short)prop.getIndentLevel()); |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hslf.record; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
@@ -30,6 +31,10 @@ import java.io.OutputStream; | |||
public final class NotesAtom extends RecordAtom | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private byte[] _header; | |||
private static long _type = 1009l; | |||
@@ -86,7 +91,7 @@ public final class NotesAtom extends RecordAtom | |||
} | |||
// There might be 2 more bytes, which are a reserved field | |||
reserved = new byte[len-14]; | |||
reserved = IOUtils.safelyAllocate(len-14, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+14,reserved,0,reserved.length); | |||
} | |||
@@ -36,6 +36,7 @@ import org.apache.poi.ddf.EscherSpRecord; | |||
import org.apache.poi.ddf.EscherSpgrRecord; | |||
import org.apache.poi.ddf.EscherTextboxRecord; | |||
import org.apache.poi.sl.usermodel.ShapeType; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.POILogger; | |||
@@ -52,6 +53,11 @@ import org.apache.poi.util.POILogger; | |||
// For now, pretending to be an atom. Might not always be, but that | |||
// would require a wrapping class | |||
public final class PPDrawing extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private byte[] _header; | |||
private long _type; | |||
@@ -100,7 +106,7 @@ public final class PPDrawing extends RecordAtom { | |||
_type = LittleEndian.getUShort(_header,2); | |||
// Get the contents for now | |||
final byte[] contents = new byte[len]; | |||
final byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start,contents,0,len); | |||
// Build up a tree of Escher records contained within |
@@ -18,6 +18,7 @@ | |||
package org.apache.poi.hslf.record; | |||
import org.apache.poi.ddf.*; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import java.io.OutputStream; | |||
@@ -35,6 +36,10 @@ import java.util.Iterator; | |||
*/ | |||
public final class PPDrawingGroup extends RecordAtom { | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private byte[] _header; | |||
private EscherContainerRecord dggContainer; | |||
//cached dgg | |||
@@ -46,7 +51,7 @@ public final class PPDrawingGroup extends RecordAtom { | |||
System.arraycopy(source,start,_header,0,8); | |||
// Get the contents for now | |||
byte[] contents = new byte[len]; | |||
byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start,contents,0,len); | |||
DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory(); |
@@ -29,6 +29,7 @@ import java.util.TreeMap; | |||
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; | |||
import org.apache.poi.hslf.exceptions.HSLFException; | |||
import org.apache.poi.util.BitField; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.POILogger; | |||
@@ -46,6 +47,10 @@ import org.apache.poi.util.POILogger; | |||
public final class PersistPtrHolder extends PositionDependentRecordAtom | |||
{ | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 100_000; | |||
private final byte[] _header; | |||
private byte[] _ptrData; // Will need to update this once we allow updates to _slideLocations | |||
private long _type; | |||
@@ -109,7 +114,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom | |||
// count * 32 bit offsets | |||
// Repeat as many times as you have data | |||
_slideLocations = new HashMap<>(); | |||
_ptrData = new byte[len-8]; | |||
_ptrData = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+8,_ptrData,0,_ptrData.length); | |||
int pos = 0; |
@@ -21,6 +21,7 @@ import java.io.IOException; | |||
import java.io.OutputStream; | |||
import org.apache.poi.hslf.record.SlideAtomLayout.SlideLayoutType; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
@@ -33,7 +34,10 @@ public final class SlideAtom extends RecordAtom { | |||
public static final int USES_MASTER_SLIDE_ID = 0x80000000; | |||
// private static final int MASTER_SLIDE_ID = 0x00000000; | |||
private byte[] _header; | |||
//arbitrarily selected; may need to increase | |||
private static final int MAX_RECORD_LENGTH = 1_000_000; | |||
private byte[] _header; | |||
private static long _type = 1007l; | |||
private int masterID; | |||
@@ -109,7 +113,7 @@ public final class SlideAtom extends RecordAtom { | |||
// If there's any other bits of data, keep them about | |||
// 8 bytes header + 20 bytes to flags + 2 bytes flags = 30 bytes | |||
reserved = new byte[len-30]; | |||
reserved = IOUtils.safelyAllocate(len-30, MAX_RECORD_LENGTH); | |||
System.arraycopy(source,start+30,reserved,0,reserved.length); | |||
} | |||