Commit 6b290fd21c269932611b32bdf27d42ede1aa8426

Werner Lemberg 2014-02-19T09:26:54

Fix Savannah bug #32902. Patch taken from https://code.google.com/p/sumatrapdf/source/browse/trunk/ext/_patches/freetype2.patch?spec=svn8620&r=8620#87 with slight modifications. * src/type1/t1parse.c (T1_Get_Private_Dict): Add heuristic test to handle fonts that incorrectly use \r at the beginning of an eexec block.

diff --git a/ChangeLog b/ChangeLog
index c1d5aea..46a2766 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,21 @@
 
 	* src/autofit/hbshim.c: Include `afglobal.h' and `aftypes.h'.
 
+2014-02-19  Werner Lemberg  <wl@gnu.org>
+	    Simon Bünzli  <zeniko@gmail.com>
+
+	Fix Savannah bug #32902.
+
+	Patch taken from
+
+	  https://code.google.com/p/sumatrapdf/source/browse/trunk/ext/_patches/freetype2.patch?spec=svn8620&r=8620#87
+
+	with slight modifications.
+
+	* src/type1/t1parse.c (T1_Get_Private_Dict): Add heuristic test to
+	handle fonts that incorrectly use \r at the beginning of an eexec
+	block.
+
 2014-02-19  Simon Bünzli  <zeniko@gmail.com>
 
 	Fix Savannah bug #41590.
diff --git a/src/type1/t1parse.c b/src/type1/t1parse.c
index 106e4e7..ccf9f4c 100644
--- a/src/type1/t1parse.c
+++ b/src/type1/t1parse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 parser (body).                                                */
 /*                                                                         */
-/*  Copyright 1996-2005, 2008, 2009, 2012, 2013 by                         */
+/*  Copyright 1996-2005, 2008, 2009, 2012-2014 by                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -332,9 +332,11 @@
       /* dictionary block in the heap.                                 */
 
       /* first of all, look at the `eexec' keyword */
-      FT_Byte*  cur   = parser->base_dict;
-      FT_Byte*  limit = cur + parser->base_len;
-      FT_Byte   c;
+      FT_Byte*    cur   = parser->base_dict;
+      FT_Byte*    limit = cur + parser->base_len;
+      FT_Byte     c;
+      FT_Pointer  pos_lf;
+      FT_Bool     test_cr;
 
 
     Again:
@@ -400,15 +402,24 @@
       cur   = parser->root.cursor;
       limit = parser->root.limit;
 
-      /* according to the Type1 spec, the first cipher byte must not be  */
+      /* According to the Type 1 spec, the first cipher byte must not be */
       /* an ASCII whitespace character code (blank, tab, carriage return */
       /* or line feed).  We have seen Type 1 fonts with two line feed    */
       /* characters...  So skip now all whitespace character codes.      */
-      while ( cur < limit       &&
-              ( *cur == ' '  ||
-                *cur == '\t' ||
-                *cur == '\r' ||
-                *cur == '\n' ) )
+      /*                                                                 */
+      /* On the other hand, Adobe's Type 1 parser handles fonts just     */
+      /* fine that are violating this limitation, so we add a heuristic  */
+      /* test to stop at \r only if it is not used for EOL.              */
+
+      pos_lf  = ft_memchr( cur, '\n', limit - cur );
+      test_cr = FT_BOOL( !pos_lf                                      ||
+                         pos_lf > ft_memchr( cur, '\r', limit - cur ) );
+
+      while ( cur < limit                    &&
+              ( *cur == ' '                ||
+                *cur == '\t'               ||
+                (test_cr && *cur == '\r' ) ||
+                *cur == '\n'               ) )
         ++cur;
       if ( cur >= limit )
       {