You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2022/03/13 15:52:14 UTC

svn commit: r1898901 - /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java

Author: tilman
Date: Sun Mar 13 15:52:13 2022
New Revision: 1898901

URL: http://svn.apache.org/viewvc?rev=1898901&view=rev
Log:
PDFBOX-5283: ignore duplicate object keys when correcting xRefs, as suggested by Oliver Schmidtmer

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

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java?rev=1898901&r1=1898900&r2=1898901&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java Sun Mar 13 15:52:13 2022
@@ -1179,6 +1179,7 @@ public class COSParser extends BaseParse
             return true;
         }
         Map<COSObjectKey, COSObjectKey> correctedKeys = new HashMap<>();
+        HashSet<COSObjectKey> validKeys = new HashSet<>();
         for (Entry<COSObjectKey, Long> objectEntry : xrefOffset.entrySet())
         {
             COSObjectKey objectKey = objectEntry.getKey();
@@ -1199,13 +1200,26 @@ public class COSParser extends BaseParse
                     // Generation was fixed - need to update map later, after iteration
                     correctedKeys.put(objectKey, foundObjectKey);
                 }
+                else
+                {
+                    validKeys.add(objectKey);
+                }
             }
         }
+        Map<COSObjectKey, Long> correctedPointers = new HashMap<>();
         for (Entry<COSObjectKey, COSObjectKey> correctedKeyEntry : correctedKeys.entrySet())
         {
-            xrefOffset.put(correctedKeyEntry.getValue(),
-                    xrefOffset.remove(correctedKeyEntry.getKey()));
+            if (!validKeys.contains(correctedKeyEntry.getValue()))
+            {
+                // Only replace entries, if the original entry does not point to a valid object
+                correctedPointers.put(correctedKeyEntry.getValue(), xrefOffset.get(correctedKeyEntry.getKey()));
+            }
         }
+        correctedKeys.entrySet().forEach(
+                // remove old invalid, as some might not be replaced
+                correctedKeyEntry -> xrefOffset.remove(correctedKeyEntry.getKey()));
+        correctedPointers.entrySet().forEach(
+                pointer -> xrefOffset.put(pointer.getKey(), pointer.getValue()));
         return true;
     }
 
@@ -1255,20 +1269,31 @@ public class COSParser extends BaseParse
         {
             source.seek(offset);
             // try to read the given object/generation number
-            if (objectKey.getNumber() == readObjectNumber())
+            long foundObjectNumber = readObjectNumber();
+            if (objectKey.getNumber() != foundObjectNumber)
             {
-                int genNumber = readGenerationNumber();
-                // finally try to read the object marker
-                readExpectedString(OBJ_MARKER, true);
-                if (genNumber == objectKey.getGeneration())
+                LOG.warn("found wrong object number. expected [" + objectKey.getNumber() + "] found [" + foundObjectNumber + "]");
+                if (!isLenient)
                 {
-                    return objectKey;
+                    return null;
                 }
-                else if (isLenient && genNumber > objectKey.getGeneration())
+                else
                 {
-                    return new COSObjectKey(objectKey.getNumber(), genNumber);
+                    objectKey = new COSObjectKey(foundObjectNumber, objectKey.getGeneration());
                 }
             }
+
+            int genNumber = readGenerationNumber();
+            // finally try to read the object marker
+            readExpectedString(OBJ_MARKER, true);
+            if (genNumber == objectKey.getGeneration())
+            {
+                return objectKey;
+            }
+            else if (isLenient && genNumber > objectKey.getGeneration())
+            {
+                return new COSObjectKey(objectKey.getNumber(), genNumber);
+            }
         }
         catch (IOException exception)
         {