You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ms...@apache.org on 2021/09/14 19:35:02 UTC

svn commit: r1893341 - in /pdfbox/trunk/pdfbox/src: main/java/org/apache/pdfbox/cos/COSBase.java main/java/org/apache/pdfbox/cos/COSUpdateInfoObserver.java test/java/org/apache/pdfbox/cos/TestCOSUpdateInfoObserver.java

Author: msahyoun
Date: Tue Sep 14 19:35:02 2021
New Revision: 1893341

URL: http://svn.apache.org/viewvc?rev=1893341&view=rev
Log:
PDFBOX-5263: fix for ConcurrentModificationException; fix for method as suggested by Christian Appl

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSBase.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSUpdateInfoObserver.java
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSUpdateInfoObserver.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSBase.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSBase.java?rev=1893341&r1=1893340&r2=1893341&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSBase.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSBase.java Tue Sep 14 19:35:02 2021
@@ -22,8 +22,8 @@ import org.apache.pdfbox.cos.observer.CO
 import org.apache.pdfbox.pdmodel.common.COSObjectable;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * The base object that all objects in the PDF document will extend.
@@ -33,7 +33,7 @@ import java.util.List;
 public abstract class COSBase implements COSObjectable
 {
 
-    private final List<COSObserver> cosChangeObservers = new ArrayList<>();
+    private final List<COSObserver> cosChangeObservers = new CopyOnWriteArrayList<>();
     private boolean direct;
     private COSObjectKey key;
 

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSUpdateInfoObserver.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSUpdateInfoObserver.java?rev=1893341&r1=1893340&r2=1893341&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSUpdateInfoObserver.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSUpdateInfoObserver.java Tue Sep 14 19:35:02 2021
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.pdfbox.cos.observer.COSIncrementObserver;
 import org.apache.pdfbox.cos.observer.COSObserver;
@@ -69,7 +70,7 @@ public class COSUpdateInfoObserver imple
     /**
      * A map mapping monitored {@link COSUpdateInfo} to a list of structures, that hold a reference to said object.
      */
-    private final Map<COSUpdateInfo, List<COSUpdateInfo>> referenceHolders = new HashMap<>();
+    private final Map<COSUpdateInfo, List<COSUpdateInfo>> referenceHolders = new ConcurrentHashMap<>();
 
     /**
      * Instantiates a new {@link COSUpdateInfoObserver} for the given {@link COSDocument}.
@@ -425,12 +426,14 @@ public class COSUpdateInfoObserver imple
     /**
      * <p>
      * Remove the given {@link COSUpdateInfo} as a referenceHolder for the given {@link COSBase}.<br>
-     * If the reference holder had been the last referenceHolder of that object, remove the object from the increment
-     * and monitored objects all together.
+     * If the reference holder had been the last referenceHolder of that object, remove the object
+     * from the increment and monitored objects all together.
      * </p>
      *
-     * @param referencedObject        The {@link COSBase}, that shall no longer be included in the given reference holder.
-     * @param previousReferenceHolder The {@link COSUpdateInfo} reference holder, that shall no longer include the object.
+     * @param referencedObject        The {@link COSBase}, that shall no longer be included
+     *                                in the given reference holder.
+     * @param previousReferenceHolder The {@link COSUpdateInfo} reference holder, that shall no
+     *                                longer include the object.
      */
     private void removeReferenceHolder(COSBase referencedObject, COSUpdateInfo previousReferenceHolder)
     {
@@ -451,7 +454,7 @@ public class COSUpdateInfoObserver imple
         else
         {
             List<COSUpdateInfo> actualReferenceHolders = referenceHolders.get((COSUpdateInfo) referencedObject);
-            actualReferenceHolders.remove((COSUpdateInfo) referencedObject);
+            actualReferenceHolders.remove(previousReferenceHolder);
 
             // The object is no longer referenced and must not be part of the increment,
             // it shall no longer be monitored.

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSUpdateInfoObserver.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSUpdateInfoObserver.java?rev=1893341&r1=1893340&r2=1893341&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSUpdateInfoObserver.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/TestCOSUpdateInfoObserver.java Tue Sep 14 19:35:02 2021
@@ -43,6 +43,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.net.URL;
+import java.util.ConcurrentModificationException;
 
 public class TestCOSUpdateInfoObserver
 {
@@ -52,7 +53,7 @@ public class TestCOSUpdateInfoObserver
      * Create a document from scratch - incrementally making changes - checking results of previous steps.
      */
     @Test
-    public void testIncrementallyCreateDocument()
+    void testIncrementallyCreateDocument()
     {
         byte[] documentData = new byte[0];
 
@@ -244,6 +245,34 @@ public class TestCOSUpdateInfoObserver
         }*/
     }
 
+    /**
+     * PDFBOX-5263: There was a ConcurrentModificationException with
+     * YTW2VWJQTDAE67PGJT6GS7QSKW3GNUQR.pdf - test that this issues has been resolved.
+     * 
+     * @throws IOException
+     */
+    @Test
+    void testConcurrentModification() throws IOException
+    {
+        URL pdfLocation = 
+            new URL("https://issues.apache.org/jira/secure/attachment/12891316/YTW2VWJQTDAE67PGJT6GS7QSKW3GNUQR.pdf");
+        
+        try (PDDocument document = Loader.loadPDF(pdfLocation.openStream()))
+        {
+            document.setAllSecurityToBeRemoved(true);
+            try
+            {
+                document.save(new ByteArrayOutputStream());
+            }
+            catch (ConcurrentModificationException e)
+            {
+                fail("There shouldn't be a ConcurrentModificationException", e.getCause());
+            }
+        }
+    }
+
+
+
     private PDDocument loadDocument(byte[] documentData) {
         return assertDoesNotThrow(() -> Loader.loadPDF(documentData), "Loading the document failed.");
     }