Commit 0a6b6ff7c662cbec5564641b580a04fffbe10a2d

Werner Lemberg 2015-05-17T22:54:48

[truetype] Fix loading of composite glyphs. * src/truetype/ttgload.c (TT_Load_Composite_Glyph): If the ARGS_ARE_XY_VALUES flag is not set, handle argument values as unsigned. I trust `ttx' (which has exactly such code) that it does the right thing here... The reason that noone has ever noticed this bug is probably the fact that point-aligned subglyphs are rare, as are subglyphs with a number of points in the range [128;255], which is quite large (or even in the range [32768;65535], which is extremely unlikely).

diff --git a/ChangeLog b/ChangeLog
index 3cbd45d..122082e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2015-05-17  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Fix loading of composite glyphs.
+
+	* src/truetype/ttgload.c (TT_Load_Composite_Glyph): If the
+	ARGS_ARE_XY_VALUES flag is not set, handle argument values as
+	unsigned.  I trust `ttx' (which has exactly such code) that it does
+	the right thing here...
+
+	The reason that noone has ever noticed this bug is probably the fact
+	that point-aligned subglyphs are rare, as are subglyphs with a
+	number of points in the range [128;255], which is quite large (or
+	even in the range [32768;65535], which is extremely unlikely).
+
 2015-05-12  Chris Liddell  <chris.liddell@artifex.com>
 
 	[cff] Make the `*curveto' operators more tolerant.
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index b380271..fd97009 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -621,15 +621,31 @@
         goto Invalid_Composite;
 
       /* read arguments */
-      if ( subglyph->flags & ARGS_ARE_WORDS )
+      if ( subglyph->flags & ARGS_ARE_XY_VALUES )
       {
-        subglyph->arg1 = FT_NEXT_SHORT( p );
-        subglyph->arg2 = FT_NEXT_SHORT( p );
+        if ( subglyph->flags & ARGS_ARE_WORDS )
+        {
+          subglyph->arg1 = FT_NEXT_SHORT( p );
+          subglyph->arg2 = FT_NEXT_SHORT( p );
+        }
+        else
+        {
+          subglyph->arg1 = FT_NEXT_CHAR( p );
+          subglyph->arg2 = FT_NEXT_CHAR( p );
+        }
       }
       else
       {
-        subglyph->arg1 = FT_NEXT_CHAR( p );
-        subglyph->arg2 = FT_NEXT_CHAR( p );
+        if ( subglyph->flags & ARGS_ARE_WORDS )
+        {
+          subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p );
+          subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p );
+        }
+        else
+        {
+          subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p );
+          subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p );
+        }
       }
 
       /* read transform */