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 2021/05/14 06:16:13 UTC

svn commit: r1889878 - in /pdfbox/trunk/pdfbox: pom.xml src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java

Author: tilman
Date: Fri May 14 06:16:13 2021
New Revision: 1889878

URL: http://svn.apache.org/viewvc?rev=1889878&view=rev
Log:
PDFBOX-5191: fix bug that made isEmbeddingPermitted() too restrictive, by Larry Lynn

Modified:
    pdfbox/trunk/pdfbox/pom.xml
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java

Modified: pdfbox/trunk/pdfbox/pom.xml
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/pom.xml?rev=1889878&r1=1889877&r2=1889878&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/pom.xml (original)
+++ pdfbox/trunk/pdfbox/pom.xml Fri May 14 06:16:13 2021
@@ -75,6 +75,12 @@
             <artifactId>jbig2-imageio</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>3.3.3</version>
+            <scope>test</scope>
+        </dependency>
         <!-- For legal reasons (incompatible license), these three dependencies below
         are to be used only in the tests and may not be distributed. 
         See also LEGAL-195 -->

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java?rev=1889878&r1=1889877&r2=1889878&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/TrueTypeEmbedder.java Fri May 14 06:16:13 2021
@@ -136,13 +136,14 @@ abstract class TrueTypeEmbedder implemen
     /**
      * Returns true if the fsType in the OS/2 table permits embedding.
      */
-    private boolean isEmbeddingPermitted(TrueTypeFont ttf) throws IOException
+    boolean isEmbeddingPermitted(TrueTypeFont ttf) throws IOException
     {
         if (ttf.getOS2Windows() != null)
         {
             int fsType = ttf.getOS2Windows().getFsType();
-            if ((fsType & OS2WindowsMetricsTable.FSTYPE_RESTRICTED) ==
-                             OS2WindowsMetricsTable.FSTYPE_RESTRICTED)
+            int maskedFsType = fsType & 0x000F;
+            // PDFBOX-5191: don't check the bit because permissions are exclusive
+            if (maskedFsType == OS2WindowsMetricsTable.FSTYPE_RESTRICTED)
             {
                 // restricted License embedding
                 return false;

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java?rev=1889878&r1=1889877&r2=1889878&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java Fri May 14 06:16:13 2021
@@ -17,16 +17,18 @@
 
 package org.apache.pdfbox.pdmodel.font;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
+import org.apache.fontbox.ttf.OS2WindowsMetricsTable;
+import org.apache.fontbox.ttf.TTFParser;
+import org.apache.fontbox.ttf.TrueTypeFont;
+
 import org.apache.pdfbox.Loader;
 import org.apache.pdfbox.cos.COSArray;
 import org.apache.pdfbox.cos.COSDictionary;
@@ -38,11 +40,19 @@ import org.apache.pdfbox.pdmodel.PDPageC
 import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
 import org.apache.pdfbox.rendering.TestPDFToImage;
 import org.apache.pdfbox.text.PDFTextStripper;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.Execution;
 import org.junit.jupiter.api.parallel.ExecutionMode;
 
+import org.mockito.Mockito;
+import static org.mockito.BDDMockito.given;
+
 /**
  * Tests font embedding.
  *
@@ -371,4 +381,115 @@ class TestFontEmbedding
             assertEquals(text1 + " " + text2, extractedText.trim());
         }
     }
+
+    private class TrueTypeEmbedderTester extends TrueTypeEmbedder
+    {
+
+        /**
+         * Common functionality for testing the TrueTypeFontEmbedder
+         *
+         */
+        TrueTypeEmbedderTester(PDDocument document, COSDictionary dict, TrueTypeFont ttf, boolean embedSubset)
+                throws IOException
+        {
+            super(document, dict, ttf, embedSubset);
+        }
+
+        @Override
+        protected void buildSubset(InputStream ttfSubset, String tag, Map<Integer, Integer> gidToCid)
+                throws IOException
+        {
+            // no-op.  Need to define method to extend abstract class, but
+            // this method is not currently needed for testing
+        }
+    }
+
+    /**
+     * Test that we validate embedding permissions properly for all legal permissions combinations
+     *
+     * @throws IOException
+     */
+    @Test
+    void testIsEmbeddingPermittedMultipleVersons() throws IOException
+    {
+        // SETUP
+        PDDocument doc = new PDDocument();
+        COSDictionary cosDictionary = new COSDictionary();
+        InputStream input = PDFont.class.getResourceAsStream("/org/apache/pdfbox/resources/ttf/LiberationSans-Regular.ttf");
+        TrueTypeFont ttf = new TTFParser().parseEmbedded(input);
+        TrueTypeEmbedderTester tester = new TrueTypeEmbedderTester(doc, cosDictionary, ttf, true);
+        TrueTypeFont mockTtf = Mockito.mock(TrueTypeFont.class);
+        OS2WindowsMetricsTable mockOS2 = Mockito.mock(OS2WindowsMetricsTable.class);
+        given(mockTtf.getOS2Windows()).willReturn(mockOS2);
+        Boolean embeddingIsPermitted;
+
+        // TEST 1: 0000 -- Installable embedding versions 0-3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x0000);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertTrue(embeddingIsPermitted);
+
+        // no test for 0001, since bit 0 is permanently reserved, and its use is deprecated
+        // TEST 2: 0010 -- Restricted License embedding versions 0-3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x0002);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertFalse(embeddingIsPermitted);
+
+        // no test for 0011
+        // TEST 3: 0100 -- Preview & Print embedding versions 0-3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x0004);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertTrue(embeddingIsPermitted);
+
+        // no test for 0101
+        // TEST 4: 0110 -- Restricted License embedding AND Preview & Print embedding versions 0-2
+        //              -- illegal permissions combination for versions 3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x0006);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertTrue(embeddingIsPermitted);
+
+        // no test for 0111
+        // TEST 5: 1000 -- Editable embedding versions 0-3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x0008);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertTrue(embeddingIsPermitted);
+
+        // no test for 1001
+        // TEST 6: 1010 -- Restricted License embedding AND Editable embedding versions 0-2
+        //              -- illegal permissions combination for versions 3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x000A);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertTrue(embeddingIsPermitted);
+
+        // no test for 1011
+        // TEST 7: 1100 -- Editable embedding AND Preview & Print embedding versions 0-2
+        //              -- illegal permissions combination for versions 3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x000C);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertTrue(embeddingIsPermitted);
+
+        // no test for 1101
+        // TEST 8: 1110 Editable embedding AND Preview & Print embedding AND Restricted License embedding versions 0-2
+        //              -- illegal permissions combination for versions 3+
+        given(mockTtf.getOS2Windows().getFsType()).willReturn((short) 0x000E);
+        embeddingIsPermitted = tester.isEmbeddingPermitted(mockTtf);
+
+        // VERIFY
+        assertTrue(embeddingIsPermitted);
+
+        // no test for 1111
+    }
 }