Author: tilman
Date: Thu May 23 15:20:03 2024
New Revision: 1917926

URL: http://svn.apache.org/viewvc?rev=1917926&view=rev
Log:
PDFBOX-5827: avoid stack overflow by tracking the depth up to 
maxp.MaxComponentDepth

Modified:
    
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
    
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java
    
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java

Modified: 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
URL: 
http://svn.apache.org/viewvc/pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java?rev=1917926&r1=1917925&r2=1917926&view=diff
==============================================================================
--- 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
 (original)
+++ 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
 Thu May 23 15:20:03 2024
@@ -56,9 +56,10 @@ public class GlyfCompositeDescript exten
      * 
      * @param bais the stream to be read
      * @param glyphTable the Glyphtable containing all glyphs
+     * @param level current level
      * @throws IOException is thrown if something went wrong
      */
-    GlyfCompositeDescript(TTFDataStream bais, GlyphTable glyphTable) throws 
IOException
+    GlyfCompositeDescript(TTFDataStream bais, GlyphTable glyphTable, int 
level) throws IOException
     {
         super((short) -1, bais);
 
@@ -78,7 +79,7 @@ public class GlyfCompositeDescript exten
         {
             readInstructions(bais, (bais.readUnsignedShort()));
         }
-        initDescriptions();
+        initDescriptions(level);
     }
 
     /**
@@ -293,14 +294,14 @@ public class GlyfCompositeDescript exten
         return null;
     }
 
-    private void initDescriptions()
+    private void initDescriptions(int level)
     {
         for (GlyfCompositeComp component : components)
         {
             try
             {
                 int index = component.getGlyphIndex();
-                GlyphData glyph = glyphTable.getGlyph(index);
+                GlyphData glyph = glyphTable.getGlyph(index, level);
                 if (glyph != null)
                 {
                     descriptions.put(index, glyph.getDescription());

Modified: 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java
URL: 
http://svn.apache.org/viewvc/pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java?rev=1917926&r1=1917925&r2=1917926&view=diff
==============================================================================
--- 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java 
(original)
+++ 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java 
Thu May 23 15:20:03 2024
@@ -42,9 +42,11 @@ public class GlyphData
      * @param glyphTable The glyph table this glyph belongs to.
      * @param data The stream to read the data from.
      * @param leftSideBearing The left side bearing for this glyph.
+     * @param level composite level
      * @throws IOException If there is an error reading the data.
      */
-    void initData( GlyphTable glyphTable, TTFDataStream data, int 
leftSideBearing ) throws IOException
+    void initData( GlyphTable glyphTable, TTFDataStream data, int 
leftSideBearing, int level)
+            throws IOException
     {
         numberOfContours = data.readSignedShort();
         xMin = data.readSignedShort();
@@ -62,7 +64,7 @@ public class GlyphData
         else 
         {
             // create a composite glyph
-            glyphDescription = new GlyfCompositeDescript(data, glyphTable);
+            glyphDescription = new GlyfCompositeDescript(data, glyphTable, 
level + 1);
         }
     }
 

Modified: 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java
URL: 
http://svn.apache.org/viewvc/pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java?rev=1917926&r1=1917925&r2=1917926&view=diff
==============================================================================
--- 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java
 (original)
+++ 
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java
 Thu May 23 15:20:03 2024
@@ -40,6 +40,7 @@ public class GlyphTable extends TTFTable
     private int cached = 0;
     
     private HorizontalMetricsTable hmt = null;
+    private MaximumProfileTable maxp = null;
     
     /**
      * Don't even bother to cache huge fonts.
@@ -83,6 +84,8 @@ public class GlyphTable extends TTFTable
         // locks TrueTypeFont and then tries to lock "data"
         hmt = font.getHorizontalMetrics();
 
+        maxp = ttf.getMaximumProfile();
+
         initialized = true;
     }
 
@@ -139,7 +142,7 @@ public class GlyphTable extends TTFTable
                 {
                     ++cached;
                 }
-                glyphs[gid] = getGlyphData(gid);
+                glyphs[gid] = getGlyphData(gid, 0);
             }
             initialized = true;
             return glyphs;
@@ -162,6 +165,11 @@ public class GlyphTable extends TTFTable
      */
     public GlyphData getGlyph(int gid) throws IOException
     {
+        return getGlyph(gid, 0);
+    }
+
+    GlyphData getGlyph(int gid, int level) throws IOException
+    {
         if (gid < 0 || gid >= numGlyphs)
         {
             return null;
@@ -196,7 +204,7 @@ public class GlyphTable extends TTFTable
 
                 data.seek(getOffset() + offsets[gid]);
 
-                glyph = getGlyphData(gid);
+                glyph = getGlyphData(gid, level);
 
                 // restore
                 data.seek(currentPosition);
@@ -212,11 +220,15 @@ public class GlyphTable extends TTFTable
         }
     }
 
-    private GlyphData getGlyphData(int gid) throws IOException
+    private GlyphData getGlyphData(int gid, int level) throws IOException
     {
+        if (level > maxp.getMaxComponentDepth())
+        {
+            throw new IOException("composite glyph maximum level reached");
+        }
         GlyphData glyph = new GlyphData();
         int leftSideBearing = hmt == null ? 0 : hmt.getLeftSideBearing(gid);
-        glyph.initData(this, data, leftSideBearing);
+        glyph.initData(this, data, leftSideBearing, level);
         // resolve composite glyph
         if (glyph.getDescription().isComposite())
         {


Reply via email to