You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2020/02/16 11:05:54 UTC

svn commit: r1874074 - /pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java

Author: lehmi
Date: Sun Feb 16 11:05:54 2020
New Revision: 1874074

URL: http://svn.apache.org/viewvc?rev=1874074&view=rev
Log:
PDFBOX-4777: backport code from trunk for reading object numbers of an object stream to avoid an OOM exception if the object stream  uses a huge/wrong "First" value

Modified:
    pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java?rev=1874074&r1=1874073&r2=1874074&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java Sun Feb 16 11:05:54 2020
@@ -1996,9 +1996,9 @@ public class COSParser extends BaseParse
                 int stmGenNumber = readGenerationNumber();
                 readExpectedString(OBJ_MARKER, true);
                 int nrOfObjects = 0;
-                byte[] numbersBytes = null;
                 COSStream stream = null;
                 COSInputStream is = null;
+                List<Long> objectNumbers = null;
                 try
                 {
                     COSDictionary dict = parseCOSDictionary();
@@ -2014,9 +2014,13 @@ public class COSParser extends BaseParse
                     {
                         securityHandler.decryptStream(stream, stmObjNumber, stmGenNumber);
                     }
-                    is = stream.createInputStream();
-                    numbersBytes = new byte[offsetFirstStream];
-                    is.read(numbersBytes);
+                    PDFObjectStreamParser strmParser = new PDFObjectStreamParser(stream, document);
+                    objectNumbers = new ArrayList<Long>(nrOfObjects);
+                    for (int i = 0; i < nrOfObjects; i++)
+                    {
+                        objectNumbers.add(strmParser.readObjectNumber());
+                        strmParser.readLong();
+                    }
                 }
                 catch (IOException exception)
                 {
@@ -2035,45 +2039,27 @@ public class COSParser extends BaseParse
                         stream.close();
                     }
                 }
-                int start = 0;
-                // skip spaces
-                while (start < numbersBytes.length && numbersBytes[start] == 32)
-                {
-                    start++;
-                }
-                String numbersStr = new String(numbersBytes, start, numbersBytes.length - start,
-                        "ISO-8859-1");
-                numbersStr = numbersStr.replace('\n', ' ').replace("  ", " ");
-                String[] numbers = numbersStr.split(" ");
-                if (numbers.length < nrOfObjects * 2)
+                if (objectNumbers.size() < nrOfObjects)
                 {
                     LOG.debug(
                             "Skipped corrupt stream: (" + stmObjNumber + " 0 at offset " + offset);
                     continue;
                 }
                 Map<COSObjectKey, Long> xrefOffset = xrefTrailerResolver.getXrefTable();
-                for (int i = 0; i < nrOfObjects; i++)
+                for (Long objNumber : objectNumbers)
                 {
-                    try
+                    COSObjectKey objKey = new COSObjectKey(objNumber, 0);
+                    Long existingOffset = bfSearchCOSObjectKeyOffsets.get(objKey);
+                    if (existingOffset != null && existingOffset < 0)
                     {
-                        long objNumber = Long.parseLong(numbers[i * 2]);
-                        COSObjectKey objKey = new COSObjectKey(objNumber, 0);
-                        Long existingOffset = bfSearchCOSObjectKeyOffsets.get(objKey);
-                        if (existingOffset != null && existingOffset < 0)
-                        {
-                            // translate stream object key to its offset
-                            COSObjectKey objStmKey = new COSObjectKey(Math.abs(existingOffset), 0);
-                            existingOffset = bfSearchCOSObjectKeyOffsets.get(objStmKey);
-                        }
-                        if (existingOffset == null || offset > existingOffset)
-                        {
-                            bfSearchCOSObjectKeyOffsets.put(objKey, -stmObjNumber);
-                            xrefOffset.put(objKey, -stmObjNumber);
-                        }
+                        // translate stream object key to its offset
+                        COSObjectKey objStmKey = new COSObjectKey(Math.abs(existingOffset), 0);
+                        existingOffset = bfSearchCOSObjectKeyOffsets.get(objStmKey);
                     }
-                    catch (NumberFormatException exception)
+                    if (existingOffset == null || offset > existingOffset)
                     {
-                        LOG.debug("Skipped corrupt object key in stream: " + stmObjNumber);
+                        bfSearchCOSObjectKeyOffsets.put(objKey, -stmObjNumber);
+                        xrefOffset.put(objKey, -stmObjNumber);
                     }
                 }
             }