]> source.dussan.org Git - poi.git/commitdiff
Bug 61349 -- add more sanity checks when allocating byte[]
authorTim Allison <tallison@apache.org>
Thu, 21 Sep 2017 14:52:59 +0000 (14:52 +0000)
committerTim Allison <tallison@apache.org>
Thu, 21 Sep 2017 14:52:59 +0000 (14:52 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1809169 13f79535-47bb-0310-9956-ffa450edef68

135 files changed:
src/examples/src/org/apache/poi/poifs/poibrowser/DocumentDescriptor.java
src/java/org/apache/poi/ddf/EscherArrayProperty.java
src/java/org/apache/poi/ddf/EscherBSERecord.java
src/java/org/apache/poi/ddf/EscherBlipRecord.java
src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java
src/java/org/apache/poi/ddf/EscherClientDataRecord.java
src/java/org/apache/poi/ddf/EscherMetafileBlip.java
src/java/org/apache/poi/ddf/EscherPictBlip.java
src/java/org/apache/poi/ddf/EscherPropertyFactory.java
src/java/org/apache/poi/ddf/EscherTextboxRecord.java
src/java/org/apache/poi/ddf/UnknownEscherRecord.java
src/java/org/apache/poi/hpsf/Blob.java
src/java/org/apache/poi/hpsf/ClipboardData.java
src/java/org/apache/poi/hpsf/CodePageString.java
src/java/org/apache/poi/hpsf/Section.java
src/java/org/apache/poi/hpsf/UnicodeString.java
src/java/org/apache/poi/hpsf/VariantSupport.java
src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java
src/java/org/apache/poi/hssf/record/CFRule12Record.java
src/java/org/apache/poi/hssf/record/DConRefRecord.java
src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
src/java/org/apache/poi/hssf/record/EscherAggregate.java
src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java
src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java
src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java
src/java/org/apache/poi/hssf/record/OldLabelRecord.java
src/java/org/apache/poi/hssf/record/OldSheetRecord.java
src/java/org/apache/poi/hssf/record/OldStringRecord.java
src/java/org/apache/poi/hssf/record/RecordInputStream.java
src/java/org/apache/poi/hssf/record/SubRecord.java
src/java/org/apache/poi/hssf/record/common/UnicodeString.java
src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java
src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
src/java/org/apache/poi/poifs/crypt/DataSpaceMapUtils.java
src/java/org/apache/poi/poifs/dev/POIFSDump.java
src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java
src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java
src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
src/java/org/apache/poi/poifs/filesystem/Ole10Native.java
src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java
src/java/org/apache/poi/poifs/property/NPropertyTable.java
src/java/org/apache/poi/poifs/storage/DocumentBlock.java
src/java/org/apache/poi/poifs/storage/HeaderBlock.java
src/java/org/apache/poi/poifs/storage/RawDataBlock.java
src/java/org/apache/poi/ss/formula/Formula.java
src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java
src/java/org/apache/poi/util/IOUtils.java
src/java/org/apache/poi/util/LZWDecompresser.java
src/java/org/apache/poi/util/LittleEndian.java
src/java/org/apache/poi/util/StringUtil.java
src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java
src/ooxml/java/org/apache/poi/ss/extractor/EmbeddedExtractor.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
src/ooxml/java/org/apache/poi/xssf/binary/XSSFBParser.java
src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkFactory.java
src/scratchpad/src/org/apache/poi/hdgf/streams/CompressedStreamStore.java
src/scratchpad/src/org/apache/poi/hdgf/streams/StreamStore.java
src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentEMFPlus.java
src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentPublic.java
src/scratchpad/src/org/apache/poi/hemf/record/HemfCommentRecord.java
src/scratchpad/src/org/apache/poi/hemf/record/HemfHeader.java
src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java
src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java
src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIRtfAttribute.java
src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFAttribute.java
src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java
src/scratchpad/src/org/apache/poi/hpbf/model/EscherPart.java
src/scratchpad/src/org/apache/poi/hpbf/model/QuillContents.java
src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCTextBit.java
src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java
src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java
src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
src/scratchpad/src/org/apache/poi/hslf/dev/SlideShowDumper.java
src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/CString.java
src/scratchpad/src/org/apache/poi/hslf/record/Comment2000Atom.java
src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/DocumentAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlinkAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/ExMediaAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/ExObjListAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java
src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java
src/scratchpad/src/org/apache/poi/hslf/record/HeadersFootersAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/MasterTextPropAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/NotesAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java
src/scratchpad/src/org/apache/poi/hslf/record/PersistPtrHolder.java
src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/SlidePersistAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java
src/scratchpad/src/org/apache/poi/hslf/record/StyleTextProp9Atom.java
src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoRun.java
src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java
src/scratchpad/src/org/apache/poi/hslf/record/UnknownRecordPlaceholder.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java
src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java
src/scratchpad/src/org/apache/poi/hwpf/HWPFOldDocument.java
src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java
src/scratchpad/src/org/apache/poi/hwpf/model/ComplexFileTable.java
src/scratchpad/src/org/apache/poi/hwpf/model/DocumentProperties.java
src/scratchpad/src/org/apache/poi/hwpf/model/Ffn.java
src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java
src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java
src/scratchpad/src/org/apache/poi/hwpf/model/OldSectionTable.java
src/scratchpad/src/org/apache/poi/hwpf/model/OldTextPieceTable.java
src/scratchpad/src/org/apache/poi/hwpf/model/PAPFormattedDiskPage.java
src/scratchpad/src/org/apache/poi/hwpf/model/PICFAndOfficeArtData.java
src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfCps.java
src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java
src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java
src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java
src/scratchpad/src/org/apache/poi/hwpf/sprm/SprmBuffer.java
src/scratchpad/src/org/apache/poi/hwpf/sprm/SprmUtils.java
src/scratchpad/src/org/apache/poi/hwpf/sprm/TableSprmCompressor.java

index 754da35ccccdbc487dd97c6d422d42cdb988b2d4..d3c837a44d78a8ab5529009f864e58cf499b1fc4 100644 (file)
@@ -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);
index 9033a49efa856a41d7d42d8d864070e8bc1a2f20..84026f54816e9e32b9468e7b09d38262c8cd34c4 100644 (file)
@@ -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;
     }
index efeb3f830c030bd5d00865de04526c459554f65f..d3e0514be71ee6ccf497c3f5d8b20165478dccbf 100644 (file)
@@ -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()) ;
 
index 266c1f03b19e35ebc0e482f830f0b83072ec7855..df49c4747eba77ef54c13beb614861f24189a762 100644 (file)
 
 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);
     }
 
index b038c12d305eb28d45c9bcae1e99e8c1ff6718ed..741ea0fdb47fdd26df35da479356cf7c3d363a00 100644 (file)
@@ -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;
     }
index d84054de6b35ffdca734baa0175c4756a4623c3b..801098854d97686505c6168ff0185ddb4d771ce1 100644 (file)
@@ -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;
     }
index 5fdbae6c86c0060107e0269625bd63d94a7422e0..fcc6d92b05c115ecd2674e771a0e368864b0861b 100644 (file)
@@ -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;
index c94f56f18d32a178d32efb64324abcf3e52a8602..69cf60138f4c4bf8700c0c78f3b08fc4901f2f9d 100644 (file)
@@ -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
index 3b05034caf8b220e65cedc3b1b6384cdab31c602..fe51c18c46a8aa6ff7ee35f182481fe382021700 100644 (file)
@@ -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;
             }
index 07527cb960bb9b033b13cd45cdf87592b85c29cb..fbf37f49b05e5f9ddca74870b239da6ae44f484d 100644 (file)
@@ -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);
     }
     
index f722f87b65b4c8c63c464f5f3181abe9cfeb15ae..38475be81881ad015f767d7ef6d56efedc458a29 100644 (file)
@@ -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;
     }
index af207feabb232f1078e6b0343e44f64e3c38111a..07c2c2ffe8f2d8ed49791c785da3fc1f92f8fb9e 100644 (file)
 ==================================================================== */
 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);
         }
index 3617c4ac6c67c3d5087a7a475cf0d278262232e4..ddc8ab09787acf11454205159f0d64f889226c35 100644 (file)
@@ -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);
     }
 
index d0d138a40baeb9563445f2f4d5ba756b0368ed3f..e45d224cdf89c57c3b902d847bf445a2010ee496 100644 (file)
@@ -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;
         }
index 0669ff34ca1ac8672c87e01f194fad7ace7e9e61..33fc3d4bb170cf30cdd5f271c28fa3f6a0bfe823 100644 (file)
@@ -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);
 
index 0826ced2d72eb8b81d9f8f2e3325e2eb97e70500..71e5fb7a088dac896907c4b9b8e3dd8ca09dfcdf 100644 (file)
@@ -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
index cf5cadb0b8a67934e17e52a7f1c6587063b6c6d4..7d57cbb5a63a5c3731ae520d582812c5e0569fab 100644 (file)
@@ -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 );
         }
index 7b76bca7c0b374f45bff79f873804ab2a33585f6..619984fdc56f21afe70c5cef03dd3a058f1452ad 100644 (file)
@@ -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));
             }
         }
 
index 3ec98c8004fc243d88131cfcc7d1977090530178..52bcf2ad24819e8d202664b317e9a469e767266b 100644 (file)
@@ -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);
         }
         
index 23bbdda117628ae4103d92f30a6490b2d8e270fa..f23f7317e60ffa17f25111be430863be6afb8b7d 100644 (file)
@@ -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)
index ae2777178884a71ac89b4fb85829ee3a44e8064e..b431223c423af72c67f6068fc949aa703a248b84 100644 (file)
@@ -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;
        }
index 10381fb5fdb04e7709960e330accaaec6acb7d2f..0eb886c2cc5f9e91688cda58352011d0c25f5be3 100644 (file)
@@ -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) {
index 28159b757c54e0eeff3f82b71dab07b772ce969d..76b4a4ee62c96c73233167a9eb6d3d724e45962f 100644 (file)
@@ -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;
     }
index c7af79ee33f3ad34a8ba08957ad21fae39922ee4..575ed7a5af91a71658288df4c074cab44eec5c42 100644 (file)
@@ -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;
     }
index 623065e08a8a553b6a4800407a669ad5cbc6d62c..f3999b1bcd4fd60259c719081991a0c9e431f8d9 100644 (file)
@@ -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);
index e2aa1e0008492b3c6406516cc5e788203a79621c..4f651b7c554789202c0ed39c9eab21d6eb860e4f 100644 (file)
@@ -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;
     }
index d77a45fc805de0199f50b6b22271d9a3a81ce0ba..447291daa3bd00b0a33a2cb1a6cfa8ddf5679de4 100644 (file)
@@ -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) {
index 92ffcf923bfa1f0c3562e38c0dfce531d4020136..8ccb3cf9d307755b1df5e0916239b72bf1a0e623 100644 (file)
@@ -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);
     }
 
index b28783c897cfd5b867dde66eaac8d9ed87eff095..e99313ee1932945fa5e434770f56be046ff18aaa 100644 (file)
@@ -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);
     }
 
index 11cd63cc0348439530054489fabc5b2bc4f8acb5..4f5f589032f068f3547644a8299e539428d22666 100644 (file)
@@ -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;
        }
index 2f74b5996b2d60cae5bb17d6f7028db921f014aa..9e242135193b8d0447777aa7aa40311d95c96879 100644 (file)
@@ -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;
                }
index 818e65087b340bcaf47a5f1e799bb2303172c51a..e20b5d52112604259778808073548f050aba2995 100644 (file)
@@ -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();
           }
index 1b5ea03cc586fecbad0deeecfbbe6b7e4602ad96..3c5be4267c9bea7540991759c6f1783c4c9d2ae8 100644 (file)
@@ -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;
index 861f3fff5f4f32ef5326d9d1559cc009e5a0a0f8..b8100d276757bcd865e601a2d5e72f0fd5b11b00 100644 (file)
@@ -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);
index e71cbd412e3babaa5068f30b98779ef15b84fb3f..77a967d1df543bbe5c96156f401d239d6dfe4925 100644 (file)
@@ -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);
index a846cca34f95d052bb3fa80cdd1e017b5024255d..62835109eb03504d260b90ab0a1f1933d9fd22aa 100644 (file)
@@ -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;
index e305376904ddc0799d736086c1ececf1302ec63e..af829839f896002335a2f110b31b0ceb916dbcf4 100644 (file)
@@ -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;
index 2f5ccfd7a9af4edf6c576519760648c51641c688..620b168eb0d8324399083db8f28a1bbdfead582a 100644 (file)
@@ -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
index ad3e6176ee68b6a05b8ad66361e40f375f9040bc..60a790e241f53ebd6904976cff016b4ec57dac59 100644 (file)
@@ -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);
index c77ce9e0460913d1face3d57e651d267fb20f0a0..314cae0ee2b5310b436a1994d0e646acc81e247e 100644 (file)
@@ -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;
 
index 848fd9f0063a950d13db6352420e088483ebc3a7..b32166ac1c8225730b550b21b1d8e4f34ea99e45 100644 (file)
@@ -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;
        }
index 7e7ca0780c5ba0cb5fb735e30501b3b5ccfc6ebb..22e4106962bba0252259168909a20fd4d9b956da 100644 (file)
@@ -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); 
index b3d9d4c8f8e17569fb84de34d61be04ed29f0e08..62a132ee45facfc46e9c025b651c575ef64a1078 100644 (file)
@@ -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));
         }
     }
     
index 5d197a8002b35ba18ade0dd045d1f9e75a14b264..7c1b9bec166a017e133d3d6b9c14dcf19524035c 100644 (file)
@@ -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;
     }
index 88ee7da7f320fa8cf1f37b2892afdb4d2364288f..72758c2d97ac7cd98c5c50582f3e3c56dfd642f5 100644 (file)
@@ -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;
    }
index fe948baf2c6c3a411c7faea23ff7b7548e71b341..d155f0079d5b8803939fd0d4746cc0544a84ac88 100644 (file)
@@ -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()) {
index a7c5686257909a3785a22e06bca7ea1290893a8f..3d9c67c65284f2891bd8f4fa595bd4d46bdab5cc 100644 (file)
@@ -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);
     }
 
index 5319a2173fd9abac00a9976c258cbe0f805ba155..c833138a240466cb9074070c72dac7a81b0c9ed9 100644 (file)
@@ -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);
                }
        }
index 923e76fac83c81bec0831057bcdb48b46d8cf77a..6ed834617d476d4e44ee6abcc84293ecdd8ea978 100644 (file)
@@ -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);
 
index 745a482d2d63f67f8d33e360058511abe3ff8c99..b0a284204070d84fcf80a71f46f449ecc0cdda80 100644 (file)
@@ -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);
        }
index 29b9612aecd299d0667640e22599b58143e0c7b7..e23275dbe3bb2bbfacb4b6ae7182ed30d1da00dd 100644 (file)
@@ -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]);
                }
index be63655a4bee863651f6ffcd4fbc2359cef462f1..c09ddf4e1395f3a6ac3fa0799f77faae174a298f 100644 (file)
@@ -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()");
+
+    }
 }
index 91aeb23b918e23441f15db2727829f9d25122f7e..ab24bf0f25fe983ff9e6ea1fe1c8febfaba113d0 100644 (file)
@@ -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;
index 1293e46ee6ba1fce68449490b8a95c3d09f19272..2bd1b3ab167741d247fed3e42e7ed3ad9d80de0c 100644 (file)
@@ -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
index e0473b2b5aa28fabad2cca578e6766a120bdc365..b9b904d669eda867ace2be92d9ed0f3bae942d0a 100644 (file)
@@ -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);
        }
index 407831a6635102079da4c43a991892158a82bacd..3ff47e3e8a13bd6325c1a78d31c94ce68d217f24 100644 (file)
@@ -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
index 2fa5fc21d7d56a1519ec342e4f244521cfb0d0dc..5c235267ca3343e7bf98f5220777f700e673c32f 100644 (file)
@@ -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")) {
index 8f13332af21f43a595220d36aa1e461814df2654..8f5dd8f84e51eba663d1c18e0941e09261073c0f 100644 (file)
@@ -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);
index 3c52ed78ca4e37166675a589efb19b7155fbb879..ac24ecd909511d5227b9b25226d031a3a68cad05 100644 (file)
@@ -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 {
index 762c2a12a9ede2079da40306d852d98913608518..b83979e145538bbb48b787b14f3daf78cd4274b1 100644 (file)
@@ -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);
 
index 24ba19653adf71b62de275c903ced0e481dc7a29..953987e7b4563aeba21a11206a4e76dc3adf9bdb 100644 (file)
@@ -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);
        }
        /**
index 1c4e4e7ed8f8a1be482b7d95ab6edbd0bdd6f140..30dead90a37c419d7e75f0c13ef454788275dc88 100644 (file)
 
 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;
index 873d42e1ee7e02c058cb8308af52cd142f655bdf..d5d4c10e849fb62c95f41b001aed30afa91c066b 100644 (file)
@@ -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;
index d527ed1c1b82f53cc9dac0714748e5ac8a8c9bd4..5ca5c375ce5d74d1bda9e9e6b87f364d2d79d7a1 100644 (file)
@@ -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;
 
 
     /**
index 90510f8d8fbca867b0e5ee95bfc98bf15bcb0021..af8aa2857212a302d338c78386a91df3f35faddc 100644 (file)
@@ -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;
index 2c3694c8444d706a9180c1c8834496379072baeb..7a6f87640094bd7937e5edc23701aa952a1593cb 100644 (file)
@@ -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;
index 8c32812d7f06a7dc9d18907421d02110f60f3d7d..87a7b4698850e176e4ff5206bd432a670a9ba898 100644 (file)
@@ -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 {
     }
index bb077b8f5bb52118f77580a14a288c86d781bcd4..159328fe7064cf203920c81285e82f9b4204a0cc 100644 (file)
@@ -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);
+         }
       }
    }
 }
index dfe4c2adc3bb9005048bba0f3f35cdf07b8e7715..744fc2b7dfd61fad3a36e6e54fbeff8254d5730f 100644 (file)
@@ -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;
index 8e386ca994d11ae70693e39700dd9f41bedd4825..11e865364d8e2fa06115503d8a4d4b0f4d3bd7b6 100644 (file)
@@ -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);
index fd79b290cda4437fe249e20d970a23a02f3f8f5b..edf96497438cc0e05f1dc02540a46dd38c4eca26 100644 (file)
@@ -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(
index 94b7536d881e477f96654eed1486803c6c4ad6b6..32ff69f24a2f9668e0b838c1b840b3fa114e5cd0 100644 (file)
@@ -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 =
index 439055c8aa12036039124eb561b8ecedb57d06f4..cc420922f796463b7f48cb18ac72a0ac64aee6b0 100644 (file)
@@ -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
index 41cd89014a5dd68cf544d827aa378f371e81ff31..38de0244e70de589ad4c1443b451420d4f75b351 100644 (file)
 
 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);
        }
index 2619af9f98bf4a600fee358af060340e8f9d32f2..1e944d48ed9ddd3c600cf0ea28026f00af2f3312 100644 (file)
@@ -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;
     }
index e71d2b4af84acdaf0a122a31aa247ab70c38e573..5699bbfeff4b20f47aa77d85309fed6ef8297942 100644 (file)
@@ -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);
     }
index 6986dbd9ad73088182257888f98df48ab85cbb36..a14a09bea4e50a23c4fc55a20e941edfc5f0e5b0 100644 (file)
@@ -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;
 
index 8b118d2f3fb5f4bd9325c186446c8e2b65e55692..05b442974b59184a9de24fe6f29c770289f0ab41 100644 (file)
@@ -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);
index a2ed09c79a9dabed474543d549dad713471422fa..d9451d95b25138feaa76705514aa0a2d4f7dc4d6 100644 (file)
@@ -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);
     }
 
index 0115438d2b4f11e50ef857de4344021ed17b795c..f126a819040051eb8600e021ba0ec1b857b4eab6 100644 (file)
@@ -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);
        }
        /**
index ab38e88d1c0e859257703edabb3999b77e327341..f73b4362802aecaef53aef57832a9ab2d9e47644 100644 (file)
@@ -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);
     }
 
index d05c5b2d1456aa3d4f90368b036734abd9140d5d..c0e2a98354bae24244d0d54cc083ca64690ec287 100644 (file)
@@ -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);
 
index 22a9b7c3eff93b44e48e25ced36b9fb51ecb7636..e2c49a9f35865dd0c50b26b30814b89005bdbe4c 100644 (file)
@@ -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);
        }
 
index 94aba471de8662c0060794ef702b9efb17903d14..5ebb2a43c6a6a510bb58f35a835b8f91ed018c0b 100644 (file)
@@ -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
index 99deafdbf22f364f64e91e36a8b9bf3a01bb1893..648f2aaa5702600b2747ca401c64ffa529d63971 100644 (file)
@@ -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
index 058f27ea5c2421c8d167fd0d062b23b6a60bd8ad..1ed5829532a1e0f5251a67b5c6cca3e213d30b50 100644 (file)
@@ -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);
     }
 
index 51bb5b4ee1dcf2d02a0e9727a675f4651778b5a2..e1224ef0bc0fd7ed26536e753421df1723097816 100644 (file)
@@ -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
index 9f412d249e89370abb18d53a5778c904342b3685..7b5a52e2c3859cbe0eda538698e6285a8a70ec31 100644 (file)
@@ -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
index 0ba89d7231b8b70f486a5bc50a28b06ca62b920a..6325fe8ec86c71cba7e68706369813795cf605a7 100644 (file)
@@ -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);
     }
 
index c0be885078fa2513664a559f6db639aa4e764b06..073ce26946ef066cca8b82df3ad2949d8c030a02 100644 (file)
@@ -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);
        }
 
index 2f82245258a77e5ca69431f426f578256a328c79..6bcfd2a9a32209f7c77712cda0077947642339bf 100644 (file)
@@ -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;
index b9006051dd6332ea9d3ac277894c05a70bf5f74d..9e9140578e4a97c8eee6182761557c27f50298fb 100644 (file)
@@ -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);
        }
 
index 6dd8fccf6bf729a95f98a78899a454c1bbacdb4a..15dc05b50db967bb66e1e778446113500e4d76b6 100644 (file)
@@ -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
index 7aef5fcdcc522ac05aa32576f37b972dc3395a17..ba27d73d84ee82b1c40b4cfc8406283b5acab2e0 100644 (file)
@@ -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());
index 7aace806321ca2dd48a080fc201b02c9bf6d3f79..c4e284098b8e8649dca64be23b412746140969b7 100644 (file)
@@ -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);
        }
 
index 6587a6e9d3cd03655c4f6f817a527fd7a9499843..fb3d2468971ea82ae0ea8b98f55c6942b7a6b5c8 100644 (file)
@@ -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
index d655e5a4fee4c600b8d306d8242107663aa7a17e..19a536e3cd40299a3d2f8d64b1c7d78f7f37fa5b 100644 (file)
@@ -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();
index 9f018d3c9004266590a3c93342b6ae7e10bc3cbc..22c5b2ad1fd03eac21fab796e2bbe0c3f1d28390 100644 (file)
@@ -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;
index 9d553740bfc8b64088e4c47127cb7a999b966c99..5d9b347bce4b066d2d7a1023b507c9ab6b3aaa7f 100644 (file)
@@ -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);
        }
 
index 0ac22adf34070624472b2b1a7fc7e21e20a5e457..7c4907f939388a528b1b4fd423f67d2ef321d303 100644 (file)
@@ -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;
@@ -28,6 +29,10 @@ import java.io.OutputStream;
  * @author Nick Burch
  */
 public final class SlidePersistAtom extends RecordAtom {
+
+       //arbitrarily selected; may need to increase
+       private static final int MAX_RECORD_LENGTH = 32;
+
        private byte[] _header;
        private static long _type = 1011l;
 
@@ -92,7 +97,7 @@ public final class SlidePersistAtom extends RecordAtom {
 
                // Finally you have typically 4 or 8 bytes of reserved fields,
                //  all zero running from 24 bytes in to the end
-               reservedFields = new byte[len-24];
+               reservedFields = IOUtils.safelyAllocate(len-24, MAX_RECORD_LENGTH);
                System.arraycopy(source,start+24,reservedFields,0,reservedFields.length);
        }
 
index 32aa9592d39fa8d88a15cba7aa8f02122abd321f..b29f810c1c0c0208d0d823cbf70d493b2771e9a7 100644 (file)
@@ -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;
  */
 public final class SoundData extends RecordAtom {
 
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
     /**
      * Record header.
      */
@@ -64,7 +69,7 @@ public final class SoundData 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);
     }
 
index ea60240518e33853b039a93f5619dda5764fec34..3f1ec4b18aa720024df8e9418f3e367768df3ae6 100644 (file)
@@ -23,12 +23,17 @@ import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.poi.hslf.model.textproperties.TextPFException9;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 
 /**
  * The atom record that specifies additional text formatting.
  */
 public final class StyleTextProp9Atom extends RecordAtom {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private final TextPFException9[] autoNumberSchemes;
     /** Record header. */
     private byte[] header;
@@ -56,7 +61,7 @@ public final class StyleTextProp9Atom extends RecordAtom {
         this.length   = LittleEndian.getInt(header, 4);
         
         // 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);
         for (int i = 0; i < data.length; ) {
             final TextPFException9 item = new TextPFException9(data, i);
index d81b7beca1c5cb0887bbb179155b935bea33b5c0..0c1fc32e0e8fd578e939440f358c4576c08d8d46 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
 import org.apache.poi.util.HexDump;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogger;
 
@@ -46,6 +47,9 @@ import org.apache.poi.util.POILogger;
 
 public final class StyleTextPropAtom extends RecordAtom {
     public static final long _type = RecordTypes.StyleTextPropAtom.typeID;
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
     private byte[] _header;
     private byte[] reserved;
 
@@ -132,7 +136,7 @@ public final class StyleTextPropAtom extends RecordAtom {
 
         // Save the contents of the atom, until we're asked to go and
         //  decode them (via a call to setParentTextSize(int)
-        rawContents = new byte[len-8];
+        rawContents = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
         System.arraycopy(source,start+8,rawContents,0,rawContents.length);
         reserved = new byte[0];
 
@@ -286,7 +290,7 @@ public final class StyleTextPropAtom extends RecordAtom {
 
         // Handle anything left over
         if(pos < rawContents.length) {
-            reserved = new byte[rawContents.length-pos];
+            reserved = IOUtils.safelyAllocate(rawContents.length-pos, rawContents.length);
             System.arraycopy(rawContents,pos,reserved,0,reserved.length);
         }
 
@@ -395,7 +399,7 @@ public final class StyleTextPropAtom extends RecordAtom {
 
         out.append("  original byte stream \n");
         
-        byte buf[] = new byte[rawContents.length+reserved.length];
+        byte buf[] = IOUtils.safelyAllocate(rawContents.length+reserved.length, MAX_RECORD_LENGTH);
         System.arraycopy(rawContents, 0, buf, 0, rawContents.length);
         System.arraycopy(reserved, 0, buf, rawContents.length, reserved.length);
         out.append( HexDump.dump(buf, 0, 0) );
index 0badc3e31dc3749d8b9c1d12f873086539540f41..5e9eeea795ec7ce641f3b338c437bfe81c587507 100644 (file)
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 
 import org.apache.poi.util.HexDump;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;
 
@@ -33,6 +34,9 @@ import org.apache.poi.util.StringUtil;
 
 public final class TextBytesAtom extends RecordAtom {
     public static final long _type = RecordTypes.TextBytesAtom.typeID;
+       //arbitrarily selected; may need to increase
+       private static final int MAX_RECORD_LENGTH = 1_000_000;
+
        private byte[] _header;
 
        /** The bytes that make up the text */
@@ -66,7 +70,7 @@ public final class TextBytesAtom 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);
        }
 
index fa8ff836d137a14161a7073f37607b9488645c0c..570506b719aba9f6bd023f5287749fe7cf475f37 100644 (file)
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 
 import org.apache.poi.util.HexDump;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;
 
@@ -31,6 +32,9 @@ import org.apache.poi.util.StringUtil;
 
 public final class TextCharsAtom extends RecordAtom {
     public static final long _type = RecordTypes.TextCharsAtom.typeID;
+       //arbitrarily selected; may need to increase
+       private static final int MAX_RECORD_LENGTH = 1_000_000;
+
        private byte[] _header;
 
        /** The bytes that make up the text */
@@ -44,7 +48,7 @@ public final class TextCharsAtom extends RecordAtom {
        /** Updates the text in the Atom. */
        public void setText(String text) {
                // Convert to little endian unicode
-               _text = new byte[text.length()*2];
+               _text = IOUtils.safelyAllocate(text.length()*2, MAX_RECORD_LENGTH);
                StringUtil.putUnicodeLE(text,_text,0);
 
                // Update the size (header bytes 5-8)
@@ -65,7 +69,7 @@ public final class TextCharsAtom 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);
        }
        /**
index 7a9ffbeb80c80bb500b1d7a0c97af634305669d1..53666d9184236eb266b6bfcefdbb4369a3508598 100644 (file)
@@ -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.POILogger;
 
@@ -27,6 +28,10 @@ import org.apache.poi.util.POILogger;
  * Ruler of a text as it differs from the style's ruler settings.
  */
 public final class TextRulerAtom extends RecordAtom {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     /**
      * Record header.
      */
@@ -69,7 +74,7 @@ public final class TextRulerAtom 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 {
index dd7076605ec2d8134635113ae3cd08c26b46c9f5..db3eb5ab7a584339e9f3e256b755a11fbf0b9e28 100644 (file)
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndianByteArrayInputStream;
 
@@ -34,6 +35,10 @@ import org.apache.poi.util.LittleEndianByteArrayInputStream;
  * @author Yegor Kozlov
  */
 public final class TextSpecInfoAtom extends RecordAtom {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private static final long _type = RecordTypes.TextSpecInfoAtom.typeID;
     
     /**
@@ -69,7 +74,7 @@ public final class TextSpecInfoAtom 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);
 
     }
index 7ab311ecf2e301251865fdadc01f9d12c47efa93..0a13d32df8fa509b1fe5ab290a22c2dcc5d4c889 100644 (file)
@@ -23,6 +23,10 @@ import java.io.OutputStream;
 import org.apache.poi.util.*;
 
 public class TextSpecInfoRun {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
     /**
      * A enum that specifies the spelling status of a run of text.
      */
@@ -153,7 +157,7 @@ public class TextSpecInfoRun {
         if (smartTagFld.isSet(mask)) {
             // An unsigned integer specifies the count of items in rgSmartTagIndex.
             int count = source.readInt();
-            smartTagsBytes = new byte[4+count*4];
+            smartTagsBytes = IOUtils.safelyAllocate(4+count*4, MAX_RECORD_LENGTH);
             LittleEndian.putInt(smartTagsBytes, 0, count);
             // An array of SmartTagIndex that specifies the indices.
             // The count of items in the array is specified by count.
index eb9dd8e0cac11ccc6a2172dbe7899a63d2d4ba84..66ec91b566ce5216d4c94fd19e29f9d0d599096f 100644 (file)
@@ -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.OutputStream;
@@ -28,6 +29,10 @@ import java.io.IOException;
  * @author Yegor Kozlov
  */
 public final class TxInteractiveInfoAtom extends RecordAtom {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
     /**
      * Record header.
      */
@@ -63,7 +68,7 @@ public final class TxInteractiveInfoAtom 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);
 
     }
index 5c9785f21ceb3b567935b7b647550f7e1715ec50..70b3221df6ce61d77d3b9dc7e0cf1bc56269f36d 100644 (file)
@@ -26,6 +26,7 @@ import java.util.List;
 import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndianOutputStream;
 import org.apache.poi.util.POILogFactory;
@@ -49,6 +50,8 @@ import org.apache.poi.util.POILogger;
  */
 public final class TxMasterStyleAtom extends RecordAtom {
     private static final POILogger LOG = POILogFactory.getLogger(TxMasterStyleAtom.class);
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
     
     /**
      * Maximum number of indentation levels allowed in PowerPoint documents
@@ -66,7 +69,7 @@ public final class TxMasterStyleAtom extends RecordAtom {
         _header = new byte[8];
         System.arraycopy(source,start,_header,0,8);
 
-        _data = new byte[len-8];
+        _data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
         System.arraycopy(source,start+8,_data,0,_data.length);
 
         //read available styles
index 6df2aa9198c3bfe21bb9473c7b224b5c87d2a889..92985f4ff0d48e6130169bc1ccc2d4e9592de792 100644 (file)
@@ -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;
@@ -31,6 +32,10 @@ import java.io.OutputStream;
 
 public final class UnknownRecordPlaceholder extends RecordAtom
 {
+
+       //arbitrarily selected; may need to increase
+       private static final int MAX_RECORD_LENGTH = 1_000_000;
+
        private byte[] _contents;
        private long _type;
 
@@ -43,7 +48,7 @@ public final class UnknownRecordPlaceholder extends RecordAtom
                if(len < 0) { len = 0; }
 
                // Treat as an atom, grab and hold everything
-               _contents = new byte[len];
+               _contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
                System.arraycopy(source,start,_contents,0,len);
                _type = LittleEndian.getUShort(_contents,2);
        }
index a71ebf1249b2058a7ec8b643ae412dacf28296ea..495c29815751624d380a059cc12016b343fd337b 100644 (file)
@@ -90,7 +90,11 @@ import org.apache.poi.util.Units;
  * understanding DocSlideList and DocNotesList) - handle Slide creation cleaner
  */
 public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagraph>, Closeable {
-    /** Powerpoint document entry/stream name */
+
+       //arbitrarily selected; may need to increase
+       private static final int MAX_RECORD_LENGTH = 10_000_000;
+
+       /** Powerpoint document entry/stream name */
     public static final String POWERPOINT_DOCUMENT = "PowerPoint Document";
     
     enum LoadSavePhase {
@@ -867,8 +871,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
            if (format == null || format.nativeId == -1) { // fail early
                throw new IllegalArgumentException("Unsupported picture format: " + format);
            }
-               int length = (int) pict.length();
-               byte[] data = new byte[length];
+               byte[] data = IOUtils.safelyAllocate(pict.length(), MAX_RECORD_LENGTH);
         FileInputStream is = new FileInputStream(pict);
                try {
                        IOUtils.readFully(is, data);
index 5eb222b9007712eff086809200fbdfab6a9c61c0..248fb3b2c5448dddd75d1e73c1162bac5f621b59 100644 (file)
@@ -65,6 +65,9 @@ import org.apache.poi.util.POILogger;
 public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
     public static final int UNSET_OFFSET = -1;
 
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 10_000_000;
+
     // For logging
     private POILogger logger = POILogFactory.getLogger(this.getClass());
 
@@ -412,7 +415,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
                         pict.setSignature(signature);
     
                         // Copy the data, ready to pass to PictureData
-                        byte[] imgdata = new byte[imgsize];
+                        byte[] imgdata = IOUtils.safelyAllocate(imgsize, MAX_RECORD_LENGTH);
                         System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length);
                         pict.setRawData(imgdata);
     
index a64726ad964e790915005e9d51e779eff7278192..0aa6162ac2accf7e15b92ab01a0586ce43925071 100644 (file)
@@ -51,6 +51,9 @@ import org.apache.poi.util.POILogger;
 public abstract class PropertiesChunk extends Chunk {
     public static final String NAME = "__properties_version1.0";
 
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
     /** For logging problems we spot with the file */
     private POILogger logger = POILogFactory.getLogger(PropertiesChunk.class);
 
@@ -223,7 +226,7 @@ public abstract class PropertiesChunk extends Chunk {
                 }
 
                 // Grab the data block
-                byte[] data = new byte[length];
+                byte[] data = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
                 IOUtils.readFully(value, data);
 
                 // Skip over any padding
index 928b31128d2744ba9eaffd7bd35dc0917a2d49ae..9c6ed1e7f4af581557475488a549e7abaf4f043d 100644 (file)
@@ -34,7 +34,7 @@ import org.apache.poi.util.POILogger;
 
 public class HwmfText {
     private static final POILogger logger = POILogFactory.getLogger(HwmfText.class);
-    private static final int MAX_RECORD_LENGTH = 1000000;
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
 
     /**
      * The META_SETTEXTCHAREXTRA record defines inter-character spacing for text justification in the 
index 6b372a3760e6f5787458d6b978b9e5d93f45010b..e41f08a9557e39068a41568d92abf6c1116bc40c 100644 (file)
@@ -72,6 +72,7 @@ import org.apache.poi.poifs.filesystem.Entry;
 import org.apache.poi.poifs.filesystem.EntryUtils;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianByteArrayOutputStream;
 
@@ -83,6 +84,8 @@ import org.apache.poi.util.LittleEndianByteArrayOutputStream;
 public final class HWPFDocument extends HWPFDocumentCore {
     /*package*/ static final String PROPERTY_PRESERVE_BIN_TABLES = "org.apache.poi.hwpf.preserveBinTables";
     private static final String PROPERTY_PRESERVE_TEXT_TABLE = "org.apache.poi.hwpf.preserveTextTable";
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
 
     private static final String STREAM_DATA = "Data";
 
@@ -635,7 +638,7 @@ public final class HWPFDocument extends HWPFDocumentCore {
 
         // preserve space for the FileInformationBlock because we will be writing
         // it after we write everything else.
-        byte[] placeHolder = new byte[fibSize];
+        byte[] placeHolder = IOUtils.safelyAllocate(fibSize, MAX_RECORD_LENGTH);
         wordDocumentStream.write(placeHolder);
         int mainOffset = wordDocumentStream.size();
         int tableOffset = 0;
index 096b04be1c3d364ebaabc3bb8c04dbbf8769e199..1375a4bf5416b21e0efaa3230fb66338ec8642c6 100644 (file)
@@ -66,6 +66,9 @@ public abstract class HWPFDocumentCore extends POIDocument {
     protected static final String STREAM_TABLE_0 = "0Table";
     protected static final String STREAM_TABLE_1 = "1Table";
 
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
     /**
      * Size of the not encrypted part of the FIB
      */
@@ -333,7 +336,7 @@ public abstract class HWPFDocumentCore extends POIDocument {
                     is = dec.getDataStream(dis, streamSize, 0);
                     if (encryptionOffset > 0) {
                         ChunkedCipherInputStream cis = (ChunkedCipherInputStream)is;
-                        byte plain[] = new byte[encryptionOffset];
+                        byte plain[] = IOUtils.safelyAllocate(encryptionOffset, MAX_RECORD_LENGTH);
                         cis.readPlain(plain, 0, encryptionOffset);
                         bos.write(plain);
                     }
index d0da433f2bae06a4776ebbc051256df7736b6772..74220b0de2586667f0076c1e3d362039bddce59b 100644 (file)
@@ -38,6 +38,7 @@ import org.apache.poi.hwpf.usermodel.Range;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.CodePageUtil;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.NotImplemented;
 import org.apache.poi.util.POILogFactory;
@@ -53,6 +54,9 @@ public class HWPFOldDocument extends HWPFDocumentCore {
     private static final POILogger logger = POILogFactory
             .getLogger( HWPFOldDocument.class );
 
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
     private final static Charset DEFAULT_CHARSET = StringUtil.WIN_1252;
 
     private OldTextPieceTable tpt;
@@ -167,7 +171,8 @@ public class HWPFOldDocument extends HWPFDocumentCore {
         // Generate a single Text Piece Table, with a single Text Piece
         //  which covers all the (8 bit only) text in the file
         tpt = new OldTextPieceTable();
-        byte[] textData = new byte[_fib.getFibBase().getFcMac()-_fib.getFibBase().getFcMin()];
+        byte[] textData = IOUtils.safelyAllocate(
+                _fib.getFibBase().getFcMac()-_fib.getFibBase().getFcMin(), MAX_RECORD_LENGTH);
         System.arraycopy(_mainStream, _fib.getFibBase().getFcMin(), textData, 0, textData.length);
 
         int numChars = textData.length;
index d21e54b8dab3263835ba2b0814d0e56f42e398dd..20046ecee53f291488e3be8743f39e5067344f2e 100644 (file)
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.poi.hwpf.sprm.SprmBuffer;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.RecordFormatException;
@@ -46,6 +47,9 @@ import org.apache.poi.util.RecordFormatException;
 public final class CHPFormattedDiskPage extends FormattedDiskPage
 {
     private static final int FC_SIZE = 4;
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
 
     private ArrayList<CHPX> _chpxList = new ArrayList<>();
     private ArrayList<CHPX> _overFlow;
@@ -137,7 +141,7 @@ public final class CHPFormattedDiskPage extends FormattedDiskPage
 
         int size = LittleEndian.getUByte(_fkp, _offset + chpxOffset);
 
-        byte[] chpx = new byte[size];
+        byte[] chpx = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
 
         System.arraycopy(_fkp, _offset + ++chpxOffset, chpx, 0, size);
         return chpx;
index ca7bd0bfd5618679757b6c9b7bf7c35814b0b278..9d62c9c52fd6718a75674c5612a477d1cc664f9e 100644 (file)
@@ -31,6 +31,10 @@ import org.apache.poi.util.StringUtil;
 
 @Internal
 public class ComplexFileTable {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private static final byte GRPPRL_TYPE = 1;
     private static final byte TEXT_PIECE_TABLE_TYPE = 2;
 
@@ -51,7 +55,7 @@ public class ComplexFileTable {
             offset++;
             int size = LittleEndian.getShort(tableStream, offset);
             offset += LittleEndian.SHORT_SIZE;
-            byte[] bs = LittleEndian.getByteArray(tableStream, offset, size);
+            byte[] bs = LittleEndian.getByteArray(tableStream, offset, size, MAX_RECORD_LENGTH);
             offset += size;
 
             SprmBuffer sprmBuffer = new SprmBuffer(bs, false, 0);
index 14c6981e86c8952694b70e121ac1c240e1ddc99a..c9aa4326add91a599a02ea75058e36ec424e9a1e 100644 (file)
@@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 
 import org.apache.poi.hwpf.model.types.DOPAbstractType;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
@@ -33,6 +34,9 @@ import org.apache.poi.util.LittleEndian;
 public final class DocumentProperties extends DOPAbstractType
 {
 
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private byte[] _preserved;
 
     /**
@@ -51,7 +55,7 @@ public final class DocumentProperties extends DOPAbstractType
         if ( length != supportedSize )
         {
             this._preserved = LittleEndian.getByteArray( tableStream, offset
-                    + supportedSize, length - supportedSize );
+                    + supportedSize, length - supportedSize, MAX_RECORD_LENGTH );
         }
         else
         {
index 935d408a8e6b03597ee17b234ec31d56bbd8ebf4..87182333ccb8bc3c24cdce56d73ee403daba6dba 100644 (file)
@@ -21,6 +21,7 @@ import java.util.Arrays;
 
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
@@ -34,6 +35,10 @@ import org.apache.poi.util.LittleEndian;
 @Internal
 public final class Ffn
 {
+
+  //arbitrarily selected; may need to increase
+  private static final int MAX_RECORD_LENGTH = 100_000;
+
   private int _cbFfnM1;//total length of FFN - 1.
   private byte _info;
     private static BitField _prq = BitFieldFactory.getInstance(0x0003);// pitch request
@@ -153,7 +158,7 @@ public final class Ffn
   public byte[] toByteArray()
   {
     int offset = 0;
-    byte[] buf = new byte[this.getSize()];
+    byte[] buf = IOUtils.safelyAllocate(this.getSize(), MAX_RECORD_LENGTH);
 
     buf[offset] = (byte)_cbFfnM1;
     offset += LittleEndian.BYTE_SIZE;
index 36a16f93556e0dc99f6dc9540d37d631487d5dfd..a8503e70ca94856602ced73e7b33498bc60d5079 100644 (file)
@@ -24,6 +24,7 @@ import java.lang.reflect.Modifier;
 import java.util.HashSet;
 import java.util.Locale;
 
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogFactory;
@@ -43,6 +44,10 @@ import org.apache.poi.util.POILogger;
 @Internal
 public final class FileInformationBlock
 {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     public static final POILogger logger = POILogFactory
             .getLogger( FileInformationBlock.class );
 
@@ -121,8 +126,8 @@ public final class FileInformationBlock
             // first short is already read as _nFibNew
             final int fibRgCswNewLength = ( _cswNew - 1 )
                     * LittleEndian.SHORT_SIZE;
-            _fibRgCswNew = new byte[fibRgCswNewLength];
-            LittleEndian.getByteArray( mainDocument, offset, fibRgCswNewLength );
+            _fibRgCswNew = IOUtils.safelyAllocate(fibRgCswNewLength, MAX_RECORD_LENGTH);
+            LittleEndian.getByteArray( mainDocument, offset, fibRgCswNewLength, MAX_RECORD_LENGTH );
             offset += fibRgCswNewLength;
         }
         else
index 0e710a159e9381fa58c4a0a97cb53fe9390a3b57..280b7a9786e0c6dbf3d8b7e972d4bfd593f078fd 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.hwpf.model;
 
 import java.util.Arrays;
 
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -37,6 +38,10 @@ import org.apache.poi.util.POILogger;
 @Internal
 public final class ListLevel
 {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private static final POILogger logger = POILogFactory
             .getLogger( ListLevel.class );
 
@@ -216,10 +221,12 @@ public final class ListLevel
         _lvlf = new LVLF( data, offset );
         offset += LVLF.getSize();
 
+        //short -- no need to safely allocate
         _grpprlPapx = new byte[_lvlf.getCbGrpprlPapx()];
         System.arraycopy( data, offset, _grpprlPapx, 0, _lvlf.getCbGrpprlPapx() );
         offset += _lvlf.getCbGrpprlPapx();
 
+        //short -- no need to safely allocate
         _grpprlChpx = new byte[_lvlf.getCbGrpprlChpx()];
         System.arraycopy( data, offset, _grpprlChpx, 0, _lvlf.getCbGrpprlChpx() );
         offset += _lvlf.getCbGrpprlChpx();
@@ -279,7 +286,7 @@ public final class ListLevel
 
     public byte[] toByteArray()
     {
-        byte[] buf = new byte[getSizeInBytes()];
+        byte[] buf = IOUtils.safelyAllocate(getSizeInBytes(), MAX_RECORD_LENGTH);
         int offset = 0;
 
         _lvlf.setCbGrpprlChpx( (short) _grpprlChpx.length );
index 110a7ef565644c190e965aa6f91260dc37531082..84a02edfd0eaa8be670d852188f4a061684125af 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.hwpf.model;
 
 import java.util.Collections;
 
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
@@ -72,7 +73,7 @@ public final class OldSectionTable extends SectionTable
         //  section properties, and we're trying to decode them as if they
         //  were the new ones, we sometimes "need" more data than we have.
         // As a workaround, have a few extra 0 bytes on the end!
-        byte[] buf = new byte[sepxSize+2];
+        byte[] buf = IOUtils.safelyAllocate(sepxSize+2, Short.MAX_VALUE+2);
         fileOffset += LittleEndian.SHORT_SIZE;
         System.arraycopy(documentStream, fileOffset, buf, 0, buf.length);
         sepx = new SEPX(sed, startAt, endAt, buf);
index 60272cad84da3c9350ff088df96902014004ee96..04c41a3087ddd4692110ae863c72dbc72ac96be5 100644 (file)
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 
 import org.apache.poi.util.CodePageUtil;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -32,6 +33,9 @@ public class OldTextPieceTable extends TextPieceTable {
     private static final POILogger logger = POILogFactory
             .getLogger(OldTextPieceTable.class);
 
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000_000;
+
     public OldTextPieceTable() {
         super();
     }
@@ -85,7 +89,7 @@ public class OldTextPieceTable extends TextPieceTable {
             int textSizeBytes = textSizeChars * multiple;
 
             // Grab the data that makes up the piece
-            byte[] buf = new byte[textSizeBytes];
+            byte[] buf = IOUtils.safelyAllocate(textSizeBytes, MAX_RECORD_LENGTH);
             System.arraycopy(documentStream, start, buf, 0, textSizeBytes);
 
             // And now build the piece
index 2be611a49ca7e37271711d394443c6a77b91eda7..8e535bc6f7ad3ffd356665d88e84652d0a7f6784 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
@@ -167,7 +168,7 @@ public final class PAPFormattedDiskPage extends FormattedDiskPage {
             size--;
         }
 
-        byte[] papx = new byte[size];
+        byte[] papx = IOUtils.safelyAllocate(size, 512);
         System.arraycopy(_fkp, _offset + ++papxOffset, papx, 0, size);
         return papx;
     }
index c729eb2ee53d0a9837972c8721a6b41d5c379a34..ba3293ea6af3ca1673c06ce479d19e1d6bb95eab 100644 (file)
@@ -29,6 +29,9 @@ import org.apache.poi.util.LittleEndian;
 public class PICFAndOfficeArtData
 {
 
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private List<EscherRecord> _blipRecords;
 
     private short _cchPicName;
@@ -52,7 +55,7 @@ public class PICFAndOfficeArtData
             offset += 1;
 
             _stPicName = LittleEndian.getByteArray( dataStream, offset,
-                    _cchPicName );
+                    _cchPicName, MAX_RECORD_LENGTH);
             offset += _cchPicName;
         }
 
index 55e921a4276d6886255ef68957d5b6198321e404..9f71f24595789e3a96305411ced0ebb9db239d34 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.hwpf.model;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
@@ -32,6 +33,10 @@ import org.apache.poi.util.LittleEndian;
  * See page 184 of official documentation for details
  */
 public final class PlexOfCps {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private int _iMac;
     private int _cbStruct;
     private List<GenericPropertyNode> _props;
@@ -99,7 +104,7 @@ public final class PlexOfCps {
         int structBufSize = +(_cbStruct * size);
         int bufSize = cpBufSize + structBufSize;
 
-        byte[] buf = new byte[bufSize];
+        byte[] buf = IOUtils.safelyAllocate(bufSize, MAX_RECORD_LENGTH);
 
         int nodeEnd = 0;
         for (int x = 0; x < size; x++) {
@@ -122,7 +127,7 @@ public final class PlexOfCps {
         int start = LittleEndian.getInt(buf, offset + getIntOffset(index));
         int end = LittleEndian.getInt(buf, offset + getIntOffset(index + 1));
 
-        byte[] struct = new byte[_cbStruct];
+        byte[] struct = IOUtils.safelyAllocate(_cbStruct, MAX_RECORD_LENGTH);
         System.arraycopy(buf, offset + getStructOffset(index), struct, 0,
                 _cbStruct);
 
index b8f5acef9ac255b4589983c42422c0910822dee8..670554ddefe2fb886c62d25ce90f475856bc87c2 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.poi.hwpf.model.io.HWPFFileSystem;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogFactory;
@@ -35,6 +36,10 @@ import org.apache.poi.util.POILogger;
 @Internal
 public class SectionTable
 {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     private final static POILogger _logger = POILogFactory.getLogger(SectionTable.class);
     private static final int SED_SIZE = 12;
 
@@ -79,7 +84,7 @@ public class SectionTable
             {
                 // The first short at the offset is the size of the grpprl.
                 int sepxSize = LittleEndian.getShort(documentStream, fileOffset);
-                byte[] buf = new byte[sepxSize];
+                byte[] buf = IOUtils.safelyAllocate(sepxSize, MAX_RECORD_LENGTH);
                 fileOffset += LittleEndian.SHORT_SIZE;
                 System.arraycopy(documentStream, fileOffset, buf, 0, buf.length);
                 _sections.add(new SEPX(sed, startAt, endAt, buf));
index be419f5f71e69bc24f0f4b5c7e5545c4df17cf55..2312f92d157e296397445afbf4341ccbfeefec63 100644 (file)
@@ -21,6 +21,7 @@ import java.util.Arrays;
 
 import org.apache.poi.hwpf.usermodel.CharacterProperties;
 import org.apache.poi.hwpf.usermodel.ParagraphProperties;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogFactory;
@@ -37,7 +38,9 @@ public final class StyleDescription implements HDFType
 {
 
     private static final POILogger logger = POILogFactory.getLogger( StyleDescription.class );
-    
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
   private final static int PARAGRAPH_STYLE = 1;
   private final static int CHARACTER_STYLE = 2;
   // private final static int TABLE_STYLE = 3;
@@ -118,7 +121,7 @@ public final class StyleDescription implements HDFType
           int upxSize = LittleEndian.getShort(std, varOffset);
           varOffset += LittleEndian.SHORT_SIZE;
 
-          byte[] upx = new byte[upxSize];
+          byte[] upx = IOUtils.safelyAllocate(upxSize, Short.MAX_VALUE);
           System.arraycopy(std, varOffset, upx, 0, upxSize);
           _upxs[x] = new UPX(upx);
           varOffset += upxSize;
index ee14b50e1ec49e47c3bc14ffe6186d2752715c83..80609bdad1126500b8929a228f750d8ff6825168 100644 (file)
@@ -26,6 +26,7 @@ import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -41,6 +42,9 @@ import org.apache.poi.util.POILogger;
 public class TextPieceTable implements CharIndexTranslator {
     private static final POILogger logger = POILogFactory
             .getLogger(TextPieceTable.class);
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000_000;
+
 
     // int _multiple;
     int _cpMin;
@@ -97,7 +101,7 @@ public class TextPieceTable implements CharIndexTranslator {
             int textSizeBytes = textSizeChars * multiple;
 
             // Grab the data that makes up the piece
-            byte[] buf = new byte[textSizeBytes];
+            byte[] buf = IOUtils.safelyAllocate(textSizeBytes, MAX_RECORD_LENGTH);
             System.arraycopy(documentStream, start, buf, 0, textSizeBytes);
 
             // And now build the piece
@@ -424,7 +428,7 @@ public class TextPieceTable implements CharIndexTranslator {
             int mod = (offset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE);
             if (mod != 0) {
                 mod = POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod;
-                byte[] buf = new byte[mod];
+                byte[] buf = IOUtils.safelyAllocate(mod, MAX_RECORD_LENGTH);
                 docStream.write(buf);
             }
 
index 24ef823c4978ef897834b00fe20d93de214431c6..c44e340c158beaa3ae252362130c7c37d7237086 100644 (file)
@@ -19,12 +19,17 @@ package org.apache.poi.hwpf.sprm;
 
 import java.util.Arrays;
 
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
 @Internal
 public final class SprmBuffer implements Cloneable
 {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     byte[] _buf;
     boolean _istd;
     int _offset;
@@ -73,7 +78,7 @@ public final class SprmBuffer implements Cloneable
 
     public SprmBuffer( int sprmsStartOffset )
     {
-        _buf = new byte[sprmsStartOffset + 4];
+        _buf = IOUtils.safelyAllocate(sprmsStartOffset + 4, MAX_RECORD_LENGTH);
         _offset = sprmsStartOffset;
         _sprmsStartOffset = sprmsStartOffset;
     }
@@ -148,7 +153,7 @@ public final class SprmBuffer implements Cloneable
         // commented - buffer shall not contain any additional bytes --
         // sergey
         // byte[] newBuf = new byte[_offset + addition + 6];
-         byte[] newBuf = new byte[_offset + addition];
+         byte[] newBuf = IOUtils.safelyAllocate(_offset + addition, MAX_RECORD_LENGTH);
         System.arraycopy( _buf, 0, newBuf, 0, _buf.length );
         _buf = newBuf;
     }
index 338342788c8888615f352e27a14aec7bf037b0b1..83b9ce488837f6800ed6506906124360328c6377 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.hwpf.sprm;
 
 import java.util.List;
 
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
@@ -26,13 +27,17 @@ import org.apache.poi.util.LittleEndian;
 @Internal
 public final class SprmUtils
 {
+
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+
     public SprmUtils()
     {
     }
 
     public static byte[] shortArrayToByteArray(short[] convert)
     {
-        byte[] buf = new byte[convert.length * LittleEndian.SHORT_SIZE];
+        byte[] buf = IOUtils.safelyAllocate(convert.length * LittleEndian.SHORT_SIZE, MAX_RECORD_LENGTH);
 
         for (int x = 0; x < convert.length; x++)
         {
@@ -107,7 +112,7 @@ public final class SprmUtils
     public static byte[] getGrpprl(List<byte[]> sprmList, int size)
     {
         // spit out the final grpprl
-        byte[] grpprl = new byte[size];
+        byte[] grpprl = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
         int listSize = sprmList.size() - 1;
         int index = 0;
         for (; listSize >= 0; listSize--)
index 3773740a343887d62e045dedb09eb05277b39d0e..875b81b7fecf38ff6942ff670565c8666cd3c958 100644 (file)
@@ -25,12 +25,16 @@ import org.apache.poi.hwpf.usermodel.BorderCode;
 import org.apache.poi.hwpf.usermodel.TableAutoformatLookSpecifier;
 import org.apache.poi.hwpf.usermodel.TableCellDescriptor;
 import org.apache.poi.hwpf.usermodel.TableProperties;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
 
 @Internal
 public final class TableSprmCompressor
 {
+  //arbitrarily selected; may need to increase
+  private static final int MAX_RECORD_LENGTH = 100_000;
+
   public TableSprmCompressor()
   {
   }
@@ -76,7 +80,9 @@ public final class TableSprmCompressor
     if (newTAP.getItcMac() > 0)
     {
       int itcMac = newTAP.getItcMac();
-      byte[] buf = new byte[1 + (LittleEndian.SHORT_SIZE*(itcMac + 1)) + (TableCellDescriptor.SIZE*itcMac)];
+      byte[] buf = IOUtils.safelyAllocate(
+              1 + (LittleEndian.SHORT_SIZE*(itcMac + 1)) + (TableCellDescriptor.SIZE*itcMac),
+              MAX_RECORD_LENGTH);
       buf[0] = (byte)itcMac;
 
       short[] dxaCenters = newTAP.getRgdxaCenter();