pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From le...@apache.org
Subject svn commit: r1813367 - /pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java
Date Thu, 26 Oct 2017 05:22:34 GMT
Author: lehmi
Date: Thu Oct 26 05:22:34 2017
New Revision: 1813367

URL: http://svn.apache.org/viewvc?rev=1813367&view=rev
Log:
PDFBOX-3959: retrieve the encryption dictionary when performing a brute force search for the
trailer

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=1813367&r1=1813366&r2=1813367&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 Thu
Oct 26 05:22:34 2017
@@ -1627,9 +1627,9 @@ public class COSParser extends BaseParse
      * 
      * @throws IOException if something went wrong
      */
-    private List<COSObjectKey[]> bfSearchForTrailer() throws IOException
+    private boolean bfSearchForTrailer(COSDictionary trailer) throws IOException
     {
-        List<COSObjectKey[]> trailerDicts = new ArrayList<COSObjectKey[]>();
+        Map<String, COSDictionary> trailerDicts = new HashMap<String, COSDictionary>();
         long originOffset = source.getPosition();
         source.seek(MINIMUM_SEARCH_OFFSET);
         while (!source.isEOF())
@@ -1640,9 +1640,11 @@ public class COSParser extends BaseParse
                 source.seek(source.getPosition() + TRAILER_MARKER.length);
                 try
                 {
+                    boolean rootFound = false;
+                    boolean infoFound = false;
                     skipSpaces();
                     COSDictionary trailerDict = parseCOSDictionary();
-                    COSObjectKey[] trailerKeys = new COSObjectKey[2];
+                    StringBuilder trailerKeys = new StringBuilder();
                     if (trailerDict.containsKey(COSName.ROOT))
                     {
                         COSBase rootObj = trailerDict.getItem(COSName.ROOT);
@@ -1650,7 +1652,9 @@ public class COSParser extends BaseParse
                         {
                             long objNumber = ((COSObject) rootObj).getObjectNumber();
                             int genNumber = ((COSObject) rootObj).getGenerationNumber();
-                            trailerKeys[0] = new COSObjectKey(objNumber, genNumber);
+                            trailerKeys.append(objNumber).append(" ");
+                            trailerKeys.append(genNumber).append(" ");
+                            rootFound = true;
                         }
                     }
                     if (trailerDict.containsKey(COSName.INFO))
@@ -1658,11 +1662,13 @@ public class COSParser extends BaseParse
                         COSBase infoObj = trailerDict.getItem(COSName.INFO);
                         long objNumber = ((COSObject) infoObj).getObjectNumber();
                         int genNumber = ((COSObject) infoObj).getGenerationNumber();
-                        trailerKeys[1] = new COSObjectKey(objNumber, genNumber);
+                        trailerKeys.append(objNumber).append(" ");
+                        trailerKeys.append(genNumber).append(" ");
+                        infoFound = true;
                     }
-                    if (trailerKeys[0] != null && trailerKeys[1] != null)
+                    if (rootFound && infoFound)
                     {
-                        trailerDicts.add(trailerKeys);
+                        trailerDicts.put(trailerKeys.toString(), trailerDict);
                     }
                 }
                 catch (IOException exception)
@@ -1675,19 +1681,76 @@ public class COSParser extends BaseParse
         source.seek(originOffset);
         // eliminate double entries
         int trailerdictsSize = trailerDicts.size();
-        if (trailerdictsSize > 1)
+        String firstEntry = null;
+        if (trailerdictsSize > 0)
         {
-            COSObjectKey[] first = trailerDicts.get(0);
-            for (int i = trailerdictsSize - 1; i > 0; i--)
+            String[] keys = new String[trailerdictsSize];
+            trailerDicts.keySet().toArray(keys);
+            firstEntry = keys[0];
+            for (int i = 1; i < trailerdictsSize; i++)
+            {
+                if (firstEntry.equals(keys[i]))
+                {
+                    trailerDicts.remove(keys[i]);
+                }
+            }
+        }
+        // continue if one entry is left only
+        if (trailerDicts.size() == 1)
+        {
+            boolean rootFound = false;
+            boolean infoFound = false;
+            COSDictionary trailerDict = trailerDicts.get(firstEntry);
+            COSBase rootObj = trailerDict.getItem(COSName.ROOT);
+            if (rootObj instanceof COSObject)
+            {
+                // check if the dictionary can be dereferenced and is the one we are looking
for
+                COSDictionary rootDict = retrieveCOSDictionary((COSObject) rootObj);
+                if (rootDict != null && isCatalog(rootDict))
+                {
+                    rootFound = true;
+                }
+            }
+            COSBase infoObj = trailerDict.getItem(COSName.INFO);
+            if (infoObj instanceof COSObject)
+            {
+                // check if the dictionary can be dereferenced and is the one we are looking
for
+                COSDictionary infoDict = retrieveCOSDictionary((COSObject) infoObj);
+                if (infoDict != null && isInfo(infoDict))
+                {
+                    infoFound = true;
+                }
+            }
+            if (rootFound && infoFound)
             {
-                COSObjectKey[] other = trailerDicts.get(i);
-                if (first[0].equals(other[0]) && first[1].equals(other[1]))
+                trailer.setItem(COSName.ROOT, rootObj);
+                trailer.setItem(COSName.INFO, infoObj);
+                if (trailerDict.containsKey(COSName.ENCRYPT))
+                {
+                    COSBase encObj = trailerDict.getItem(COSName.ENCRYPT);
+                    if (encObj instanceof COSObject)
+                    {
+                        // check if the dictionary can be dereferenced
+                        // TODO check if the dictionary is an encryption dictionary?
+                        COSDictionary encDict = retrieveCOSDictionary((COSObject) encObj);
+                        if (encDict != null)
+                        {
+                            trailer.setItem(COSName.ENCRYPT, encObj);
+                        }
+                    }
+                }
+                if (trailerDict.containsKey(COSName.ID))
                 {
-                    trailerDicts.remove(other);
+                    COSBase idObj = trailerDict.getItem(COSName.ID);
+                    if (idObj instanceof COSArray)
+                    {
+                        trailer.setItem(COSName.ID, idObj);
+                    }
                 }
+                return true;
             }
         }
-        return trailerDicts;
+        return false;
     }
 
     /**
@@ -2039,36 +2102,7 @@ public class COSParser extends BaseParse
             xrefTrailerResolver.setStartxref(0);
             trailer = xrefTrailerResolver.getTrailer();
             getDocument().setTrailer(trailer);
-            List<COSObjectKey[]> trailerObjects = bfSearchForTrailer();
-            boolean rootFound = false;
-            boolean infoFound = false;
-            if (trailerObjects.size() == 1)
-            {
-                COSObjectKey[] trailerObj = trailerObjects.get(0);
-                COSObjectKey rootKey = trailerObj[0];
-                Long rootOffset = rootKey != null ? bfSearchCOSObjectKeyOffsets.get(rootKey)
: null;
-                COSObjectKey infoKey = trailerObj[1];
-                Long infoOffset = infoKey != null ? bfSearchCOSObjectKeyOffsets.get(infoKey)
: null;
-                if (rootKey != null && rootOffset != null)
-                {
-                    COSDictionary rootDict = retrieveCOSDictionary(rootKey, rootOffset);
-                    if (rootDict != null && isCatalog(rootDict))
-                    {
-                        trailer.setItem(COSName.ROOT, document.getObjectFromPool(rootKey));
-                        rootFound = true;
-                    }
-                }
-                if (infoKey != null && infoOffset != null)
-                {
-                    COSDictionary infoDict = retrieveCOSDictionary(infoKey, infoOffset);
-                    if (infoDict != null && isInfo(infoDict))
-                    {
-                        trailer.setItem(COSName.INFO, document.getObjectFromPool(infoKey));
-                        infoFound = true;
-                    }
-                }
-            }
-            if (!rootFound || !infoFound)
+            if (!bfSearchForTrailer(trailer))
             {
                 // search for the different parts of the trailer dictionary
                 for (Entry<COSObjectKey, Long> entry : bfSearchCOSObjectKeyOffsets.entrySet())
@@ -2098,7 +2132,18 @@ public class COSParser extends BaseParse
         return trailer;
     }
 
-    private COSDictionary retrieveCOSDictionary(COSObjectKey key, Long offset) throws IOException
+    private COSDictionary retrieveCOSDictionary(COSObject object) throws IOException
+    {
+        COSObjectKey key = new COSObjectKey((COSObject) object);
+        Long offset = bfSearchCOSObjectKeyOffsets.get(key);
+        if (offset != null)
+        {
+            return retrieveCOSDictionary(key, offset);
+        }
+        return null;
+    }
+
+    private COSDictionary retrieveCOSDictionary(COSObjectKey key, long offset) throws IOException
     {
         COSDictionary dictionary = null;
         // handle compressed objects
@@ -2137,6 +2182,7 @@ public class COSParser extends BaseParse
         }
         return dictionary;
     }
+
     /**
      * Check if all entries of the pages dictionary are present. Those which can't be dereferenced
are removed.
      * 



Mime
View raw message