Author: lehmi
Date: Thu May 16 17:41:02 2024
New Revision: 1917767

URL: http://svn.apache.org/viewvc?rev=1917767&view=rev
Log:
PDFBOX-5819: added test to ensure the thread safety of Type2CharStringParser as 
provided by Patrick Corless

Modified:
    
pdfbox/branches/3.0/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java

Modified: 
pdfbox/branches/3.0/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java
URL: 
http://svn.apache.org/viewvc/pdfbox/branches/3.0/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java?rev=1917767&r1=1917766&r2=1917767&view=diff
==============================================================================
--- 
pdfbox/branches/3.0/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java
 (original)
+++ 
pdfbox/branches/3.0/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java
 Thu May 16 17:41:02 2024
@@ -23,6 +23,8 @@ import static org.junit.jupiter.api.Asse
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.fontbox.util.BoundingBox;
 import org.apache.pdfbox.io.RandomAccessReadBufferedFile;
@@ -201,6 +203,64 @@ class CFFParserTest
                 new int[]{146, 150}, stemSnapV);
     }
 
+    /**
+     * PDFBOX-5819: ensure thread safety of Type2CharStringParser when parsing 
the path of a glyph.
+     * 
+     * @throws InterruptedException
+     */
+    @Test
+    void testMultiThreadParse() throws InterruptedException
+    {
+        CountDownLatch latch = new CountDownLatch(2);
+        PathRunner pathRunner1 = new PathRunner(latch);
+        PathRunner pathRunner2 = new PathRunner(latch);
+
+        AtomicBoolean wasCalled = new AtomicBoolean(false);
+
+        Thread.UncaughtExceptionHandler handler = (t, e) -> 
wasCalled.set(true);
+
+        Thread thread1 = new Thread(pathRunner1);
+        thread1.setUncaughtExceptionHandler(handler);
+        Thread thread2 = new Thread(pathRunner2);
+        thread2.setUncaughtExceptionHandler(handler);
+
+        thread1.start();
+        thread2.start();
+
+        latch.await();
+        assertFalse(wasCalled.get());
+    }
+
+    private class PathRunner implements Runnable
+    {
+        private final CountDownLatch latch;
+
+        public PathRunner(CountDownLatch latch)
+        {
+            this.latch = latch;
+        }
+
+        @Override
+        public void run()
+        {
+            try
+            {
+                for (char i = 33; i < 126; i++)
+                {
+                    testCFFType1Font.getPath(String.valueOf(i));
+                }
+            }
+            catch (Exception e)
+            {
+                throw new IllegalStateException(e);
+            }
+            finally
+            {
+                latch.countDown();
+            }
+        }
+    }
+
     private static List<CFFFont> readFont(String filename) throws IOException
     {
         RandomAccessReadBufferedFile randomAccessRead = new 
RandomAccessReadBufferedFile(filename);


Reply via email to