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 2021/01/30 13:58:40 UTC

svn commit: r1886053 - /pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java

Author: lehmi
Date: Sat Jan 30 13:58:40 2021
New Revision: 1886053

URL: http://svn.apache.org/viewvc?rev=1886053&view=rev
Log:
PDFBOX-5090: strict mode with overflow detection is limited to CMaps within PDFs

Modified:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java?rev=1886053&r1=1886052&r2=1886053&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cmap/CMapParser.java Sat Jan 30 13:58:40 2021
@@ -42,6 +42,8 @@ public class CMapParser
 
     private final byte[] tokenParserByteBuffer = new byte[512];
 
+    private boolean strictMode = false;
+
     /**
      * Creates a new instance of CMapParser.
      */
@@ -50,6 +52,16 @@ public class CMapParser
     }
 
     /**
+     * Creates a new instance of CMapParser.
+     * 
+     * @param strictMode activates the strict mode used for inline CMaps
+     */
+    public CMapParser(boolean strictMode)
+    {
+        this.strictMode = strictMode;
+    }
+
+    /**
      * Parse a CMAP file on the file system.
      * 
      * @param file The file to parse.
@@ -75,6 +87,8 @@ public class CMapParser
     {
         try (InputStream input = new BufferedInputStream(getExternalCMap(name)))
         {
+            // deactivate strict mode
+            strictMode = false;
             return parse(input);
         }
     }
@@ -401,10 +415,7 @@ public class CMapParser
                     }
                     else
                     {
-                        // PDFBOX-4661: avoid overflow of the last byte, all following values are undefined
-                        int values = Math.min(end - start,
-                                255 - (tokenBytes[tokenBytes.length - 1] & 0xFF)) + 1;
-                        addMappingFrombfrange(result, startCode, values, tokenBytes);
+                        addMappingFrombfrange(result, startCode, end - start + 1, tokenBytes);
                     }
                 }
             }
@@ -417,7 +428,7 @@ public class CMapParser
         {
             String value = createStringFromBytes(tokenBytes);
             cmap.addCharMapping(startCode, value);
-            increment(startCode);
+            increment(startCode, startCode.length - 1, false);
         }
     }
 
@@ -428,8 +439,12 @@ public class CMapParser
         {
             String value = createStringFromBytes(tokenBytes);
             cmap.addCharMapping(startCode, value);
-            increment(startCode);
-            increment(tokenBytes);
+            increment(startCode, startCode.length - 1, false);
+            if (!increment(tokenBytes, tokenBytes.length - 1, strictMode))
+            {
+                // overflow detected -> stop adding further mappings
+                break;
+            }
         }
     }
 
@@ -705,22 +720,24 @@ public class CMapParser
         }
     }
 
-    private void increment(byte[] data)
-    {
-        increment(data, data.length - 1);
-    }
-
-    private void increment(byte[] data, int position)
+    private boolean increment(byte[] data, int position, boolean useStrictMode)
     {
         if (position > 0 && (data[position] & 0xFF) == 255)
         {
+            // PDFBOX-4661: avoid overflow of the last byte, all following values are undefined
+            // PDFBOX-5090: strict mode has to be used for CMaps within pdfs
+            if (useStrictMode)
+            {
+                return false;
+            }
             data[position] = 0;
-            increment(data, position - 1);
+            increment(data, position - 1, useStrictMode);
         }
         else
         {
             data[position] = (byte) (data[position] + 1);
         }
+        return true;
     }
 
     private String createStringFromBytes(byte[] bytes)