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/12/27 15:00:22 UTC

svn commit: r1884846 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: pdfparser/COSParser.java pdfwriter/COSWriter.java

Author: lehmi
Date: Sun Dec 27 15:00:22 2020
New Revision: 1884846

URL: http://svn.apache.org/viewvc?rev=1884846&view=rev
Log:
PDFBOX-4952: take all object keys into account when calculating the highest object number of a pdf, refactor the usage of the highest object number within COSWriter

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.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=1884846&r1=1884845&r2=1884846&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 Dec 27 15:00:22 2020
@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -46,6 +47,7 @@ import org.apache.pdfbox.io.IOUtils;
 import org.apache.pdfbox.io.RandomAccessRead;
 import org.apache.pdfbox.io.RandomAccessReadView;
 import org.apache.pdfbox.pdfparser.XrefTrailerResolver.XRefType;
+import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
 import org.apache.pdfbox.pdmodel.encryption.DecryptionMaterial;
 import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
@@ -415,6 +417,13 @@ public class COSParser extends BaseParse
         checkXrefOffsets();
         // copy xref table
         document.addXRefTable(xrefTrailerResolver.getXrefTable());
+
+        // remember the highest XRef object number to avoid it being reused in incremental saving
+        Optional<Long> maxValue = document.getXrefTable().keySet().stream() //
+                .map(COSObjectKey::getNumber) //
+                .reduce(Long::max);
+        document.setHighestXRefObjectNumber(maxValue.isPresent() ? maxValue.get() : 0);
+
         return trailer;
     }
 
@@ -426,12 +435,7 @@ public class COSParser extends BaseParse
     private long parseXrefObjStream(long objByteOffset, boolean isStandalone) throws IOException
     {
         // ---- parse indirect object head
-        long objectNumber = readObjectNumber();
-
-        // remember the highest XRef object number to avoid it being reused in incremental saving
-        long currentHighestXRefObjectNumber = document.getHighestXRefObjectNumber();
-        document.setHighestXRefObjectNumber(Math.max(currentHighestXRefObjectNumber, objectNumber));
-
+        readObjectNumber();
         readGenerationNumber();
         readExpectedString(OBJ_MARKER, true);
 

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java?rev=1884846&r1=1884845&r2=1884846&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java Sun Dec 27 15:00:22 2020
@@ -39,6 +39,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -322,36 +323,19 @@ public class COSWriter implements ICOSVi
 
     private void prepareIncrement(PDDocument doc)
     {
-        if (doc != null)
+        COSDocument cosDoc = doc.getDocument();
+        Set<COSObjectKey> keySet = cosDoc.getXrefTable().keySet();
+        for (COSObjectKey cosObjectKey : keySet)
         {
-          COSDocument cosDoc = doc.getDocument();
-          
-          Map<COSObjectKey, Long> xrefTable = cosDoc.getXrefTable();
-          Set<COSObjectKey> keySet = xrefTable.keySet();
-          long highestNumber = doc.getDocument().getHighestXRefObjectNumber();
-          for ( COSObjectKey cosObjectKey : keySet ) 
-          {
             COSBase object = cosDoc.getObjectFromPool(cosObjectKey).getObject();
-            if (object != null && cosObjectKey!= null && !(object instanceof COSNumber))
+            if (object != null && cosObjectKey != null && !(object instanceof COSNumber))
             {
-                //FIXME see PDFBOX-4997: objectKeys is (theoretically) risky because a COSName in
+                // FIXME see PDFBOX-4997: objectKeys is (theoretically) risky because a COSName in
                 // different objects would appear only once. Rev 1092855 considered this
                 // but only for COSNumber.
-
                 objectKeys.put(object, cosObjectKey);
-                keyObject.put(cosObjectKey,object);
-            }
-
-            if (cosObjectKey != null)
-            {
-                long num = cosObjectKey.getNumber();
-                if (num > highestNumber)
-                {
-                    highestNumber = num;
-                }
+                keyObject.put(cosObjectKey, object);
             }
-          }
-          number = highestNumber;
         }
     }
     
@@ -529,20 +513,18 @@ public class COSWriter implements ICOSVi
             for (COSObjectKey key : compressionPool.getTopLevelObjects())
             {
                 currentObjectKey = key;
-                number = this.currentObjectKey.getNumber();
                 doWriteObject(key, keyObject.get(key));
             }
             // Append object streams to document.
-            long highestXRefObjectNumber = compressionPool.getHighestXRefObjectNumber();
+            number = compressionPool.getHighestXRefObjectNumber();
             for (COSWriterObjectStream finalizedObjectStream : compressionPool
                     .createObjectStreams())
             {
-                highestXRefObjectNumber++;
                 // Create new COSObject for object stream.
                 COSStream stream = finalizedObjectStream
                         .writeObjectsToStream(document.createCOSStream());
                 // Determine key for object stream.
-                COSObjectKey objectStreamKey = new COSObjectKey(highestXRefObjectNumber, 0);
+                COSObjectKey objectStreamKey = new COSObjectKey(++number, 0);
                 // Create new COSObject for object stream.
                 COSObject objectStream = new COSObject(stream, objectStreamKey);
                 // Add object stream entries to xref - stream.
@@ -555,16 +537,13 @@ public class COSWriter implements ICOSVi
                 }
                 // Include object stream in document.
                 currentObjectKey = objectStreamKey;
-                number = objectStreamKey.getNumber();
                 doWriteObject(objectStreamKey, objectStream);
             }
             willEncrypt = false;
             if (encrypt != null)
             {
-                highestXRefObjectNumber++;
-                COSObjectKey encryptKey = new COSObjectKey(highestXRefObjectNumber, 0);
+                COSObjectKey encryptKey = new COSObjectKey(++number, 0);
                 currentObjectKey = encryptKey;
-                number = currentObjectKey.getNumber();
                 writtenObjects.add(encrypt);
                 keyObject.put(encryptKey, encrypt);
                 objectKeys.put(encrypt, encryptKey);
@@ -1473,7 +1452,8 @@ public class COSWriter implements ICOSVi
 
         pdDocument = doc;
         signatureInterface = signInterface;
-        
+        number = pdDocument.getDocument().getHighestXRefObjectNumber();
+
         if(incrementalUpdate)
         {
             prepareIncrement(doc);