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/26 12:29:03 UTC

svn commit: r1884814 - in /pdfbox/trunk/pdfbox/src: main/java/org/apache/pdfbox/pdfwriter/COSWriter.java main/java/org/apache/pdfbox/pdfwriter/compress/COSWriterCompressionPool.java test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java

Author: lehmi
Date: Sat Dec 26 12:29:02 2020
New Revision: 1884814

URL: http://svn.apache.org/viewvc?rev=1884814&view=rev
Log:
PDFBOX-4952: use COSObject to preserve origin object key, don't write indirect objects as direct if part of an COSArray, support compression for encrypted pdfs

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/compress/COSWriterCompressionPool.java
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java

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=1884814&r1=1884813&r2=1884814&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 Sat Dec 26 12:29:02 2020
@@ -351,7 +351,7 @@ public class COSWriter implements ICOSVi
                 }
             }
           }
-          setNumber(highestNumber);
+          number = highestNumber;
         }
     }
     
@@ -384,16 +384,6 @@ public class COSWriter implements ICOSVi
     }
 
     /**
-     * This will get the current object number.
-     *
-     * @return The current object number.
-     */
-    protected long getNumber()
-    {
-        return number;
-    }
-
-    /**
      * This will get all available object keys.
      *
      * @return A map of all object keys.
@@ -443,16 +433,6 @@ public class COSWriter implements ICOSVi
     }
 
     /**
-     * This will set the current object number.
-     *
-     * @param newNumber The new object number.
-     */
-    protected void setNumber(long newNumber)
-    {
-        number = newNumber;
-    }
-
-    /**
      * This will set the output stream.
      *
      * @param newOutput The new output stream.
@@ -581,7 +561,6 @@ public class COSWriter implements ICOSVi
             {
                 highestXRefObjectNumber++;
                 COSObjectKey encryptKey = new COSObjectKey(highestXRefObjectNumber, 0);
-                setNumber(encryptKey.getNumber());
                 currentObjectKey = encryptKey;
                 number = currentObjectKey.getNumber();
                 writtenObjects.add(encrypt);
@@ -590,7 +569,7 @@ public class COSWriter implements ICOSVi
 
                 doWriteObject(encryptKey, encrypt);
             }
-            this.blockAddingObject = false;
+            blockAddingObject = false;
         }
     }
 
@@ -804,7 +783,7 @@ public class COSWriter implements ICOSVi
             pdfxRefStream.addTrailerInfo(trailer);
             // the size is the highest object number+1. we add one more
             // for the xref stream object we are going to write
-            pdfxRefStream.setSize(getNumber() + 2);
+            pdfxRefStream.setSize(number + 2);
 
             setStartxref(getStandardOutput().getPos());
             COSStream stream2 = pdfxRefStream.getStream();
@@ -1093,8 +1072,7 @@ public class COSWriter implements ICOSVi
         }
         if (key == null)
         {
-            setNumber(getNumber()+1);
-            key = new COSObjectKey(getNumber(),0);
+            key = new COSObjectKey(++number, 0);
             objectKeys.put(obj, key);
             if( actual != null )
             {
@@ -1127,7 +1105,10 @@ public class COSWriter implements ICOSVi
             else if( current instanceof COSObject )
             {
                 COSBase subValue = ((COSObject)current).getObject();
-                if (willEncrypt || incrementalUpdate || subValue instanceof COSDictionary || subValue == null)
+                if (willEncrypt || incrementalUpdate //
+                        || subValue instanceof COSDictionary //
+                        || subValue instanceof COSArray //
+                        || subValue == null)
                 {
                     // PDFBOX-4308: added willEncrypt to prevent an object
                     // that is referenced several times from being written
@@ -1229,7 +1210,10 @@ public class COSWriter implements ICOSVi
                 else if( value instanceof COSObject )
                 {
                     COSBase subValue = ((COSObject)value).getObject();
-                    if (willEncrypt || incrementalUpdate || subValue instanceof COSDictionary || subValue == null)
+                    if (willEncrypt || incrementalUpdate //
+                            || subValue instanceof COSDictionary //
+                            || subValue instanceof COSArray //
+                            || subValue == null)
                     {
                         // PDFBOX-4308: added willEncrypt to prevent an object
                         // that is referenced several times from being written

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/compress/COSWriterCompressionPool.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/compress/COSWriterCompressionPool.java?rev=1884814&r1=1884813&r2=1884814&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/compress/COSWriterCompressionPool.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/compress/COSWriterCompressionPool.java Sat Dec 26 12:29:02 2020
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map.Entry;
 
 /**
  * An instance of this class compresses the contents of a given {@link PDDocument}.
@@ -72,10 +73,8 @@ public class COSWriterCompressionPool
         COSDocument cosDocument = document.getDocument();
 
         COSDictionary trailer = cosDocument.getTrailer();
-        addStructure(
-                new TraversedCOSElement(new COSObject(trailer.getCOSDictionary(COSName.ROOT))));
-        addStructure(
-                new TraversedCOSElement(new COSObject(trailer.getCOSDictionary(COSName.INFO))));
+        addStructure(new TraversedCOSElement(trailer.getItem(COSName.ROOT)));
+        addStructure(new TraversedCOSElement(trailer.getItem(COSName.INFO)));
 
         Collections.sort(objectStreamObjects);
         Collections.sort(topLevelObjects);
@@ -153,7 +152,7 @@ public class COSWriterCompressionPool
         else if (current instanceof COSObject)
         {
             base = ((COSObject) current).getObject();
-            if (base instanceof COSDictionary)
+            if (base instanceof COSDictionary || base instanceof COSArray)
             {
                 base = addObjectToPool(current.getKey(), traversedObject);
             }
@@ -165,46 +164,41 @@ public class COSWriterCompressionPool
 
         if (base instanceof COSArray)
         {
-            COSArray array = (COSArray) base;
-            for (int i = 0; i < array.size(); i++)
-            {
-                COSBase value = array.get(i);
-                if ((value instanceof COSDictionary || value instanceof COSObject
-                        || value instanceof COSArray)
-                        && !traversedObject.getAllTraversedObjects().contains(value))
-                {
-                    COSBase writtenValue = addStructure(
-                            traversedObject.appendTraversedElement(value));
-                    if ((value instanceof COSStream || value instanceof COSObject)
-                            && !value.equals(writtenValue))
-                    {
-                        array.set(i, writtenValue);
-                    }
-                }
-            }
+            addCOSArray(traversedObject, (COSArray) base);
         }
         else if (base instanceof COSDictionary)
         {
-            COSDictionary dictionary = (COSDictionary) base;
-            for (COSName name : dictionary.keySet())
+            addCOSDictionary(traversedObject, (COSDictionary) base);
+        }
+        return retVal;
+    }
+
+    private void addCOSArray(TraversedCOSElement traversedObject, COSArray array) throws IOException
+    {
+        for (COSBase value : array)
+        {
+            if ((value instanceof COSDictionary || value instanceof COSObject
+                    || value instanceof COSArray)
+                    && !traversedObject.getAllTraversedObjects().contains(value))
             {
-                COSBase value = dictionary.getItem(name);
-                if ((value instanceof COSDictionary || value instanceof COSObject
-                        || value instanceof COSArray)
-                        && !traversedObject.getAllTraversedObjects().contains(value))
-                {
-                    COSBase writtenValue = addStructure(
-                            traversedObject.appendTraversedElement(value));
-                    if ((value instanceof COSStream || value instanceof COSObject)
-                            && !value.equals(writtenValue))
-                    {
-                        dictionary.setItem(name, writtenValue);
-                    }
-                }
+                addStructure(traversedObject.appendTraversedElement(value));
             }
         }
+    }
 
-        return retVal;
+    private void addCOSDictionary(TraversedCOSElement traversedObject, COSDictionary dictionary)
+            throws IOException
+    {
+        for (Entry<COSName, COSBase> entry : dictionary.entrySet())
+        {
+            COSBase value = entry.getValue();
+            if ((value instanceof COSDictionary || value instanceof COSObject
+                    || value instanceof COSArray)
+                    && !traversedObject.getAllTraversedObjects().contains(value))
+            {
+                addStructure(traversedObject.appendTraversedElement(value));
+            }
+        }
     }
 
     /**

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java?rev=1884814&r1=1884813&r2=1884814&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java Sat Dec 26 12:29:02 2020
@@ -44,7 +44,6 @@ import org.apache.pdfbox.Loader;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.io.IOUtils;
-import org.apache.pdfbox.pdfwriter.compress.CompressParameters;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
 import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
@@ -388,7 +387,7 @@ class TestSymmetricKeyEncryption
 
         File pdfFile = new File(testResultsDir, prefix + keyLength + "-bit-" + (preferAES ? "AES" : "RC4") + "-encrypted.pdf");
 
-        doc.save(pdfFile, CompressParameters.NO_COMPRESSION);
+        doc.save(pdfFile);
         doc.close();
         long sizeEncrypted = pdfFile.length();
         assertNotEquals(sizeEncrypted, sizePriorToEncr,