]> git.wh0rd.org Git - fontconfig.git/commitdiff
Rework GSUB/GPOS script parsing to survive broken fonts. Thanks for the
authorKeith Packard <keithp@keithp.com>
Sat, 5 Mar 2005 23:34:57 +0000 (23:34 +0000)
committerKeith Packard <keithp@keithp.com>
Sat, 5 Mar 2005 23:34:57 +0000 (23:34 +0000)
    broken font go to Manish Singh

ChangeLog
src/fcfreetype.c

index d1c80286e5eccd7c87875571f17edc284529f729..12182a32a162a7179de33bf949946840e60a1903 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-03-05  Keith Packard  <keithp@keithp.com>
+
+       * src/fcfreetype.c: (addtag), (GetScriptTags),
+       (FcFontCapabilities):
+       Rework GSUB/GPOS script parsing to survive broken fonts.
+       Thanks for the broken font go to Manish Singh
+
 2005-03-05  Keith Packard  <keithp@keithp.com>
 
        Josselin Mouette:
index 39aaa794da7ff85953b8c6a5f1ebef7d563c280b..7f6ca3769bf0ab2d29595171465717a6bbf1db36 100644 (file)
@@ -2643,17 +2643,38 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
 #define TTO_Err_Empty_Script              0x1005
 #define TTO_Err_Invalid_SubTable          0x1001
 
-
+#define OTLAYOUT_HEAD      "otlayout:"
+#define OTLAYOUT_HEAD_LEN   9
+#define OTLAYOUT_ID_LEN            4
+/* space + head + id */
+#define OTLAYOUT_LEN       (1 + OTLAYOUT_HEAD_LEN + OTLAYOUT_ID_LEN)
+
+#define FcIsNumber(x)      (060 <= (x) && (x) <= 071)
+#define FcIsAlNum(x)       (FcIsLower(x) || FcIsUpper (x) || FcIsNumber (x))
 static void
 addtag(FcChar8 *complex, FT_ULong tag)
 {
-    FcChar8 tagstring[15];
-    sprintf (tagstring, "otlayout:%c%c%c%c ",
-       (unsigned char)(tag >> 24),
-       (unsigned char)((tag & 0xff0000) >> 16),
-       (unsigned char)((tag & 0xff00) >> 8),
-       (unsigned char)(tag & 0xff));
-    strncat(complex, tagstring, 14);
+    FcChar8 tagstring[OTLAYOUT_ID_LEN + 1];
+
+    tagstring[0] = (FcChar8)(tag >> 24),
+    tagstring[1] = (FcChar8)(tag >> 16),
+    tagstring[2] = (FcChar8)(tag >> 8),
+    tagstring[3] = (FcChar8)(tag);
+    tagstring[4] = '\0';
+    
+    /* skip tags which aren't alphanumeric, under the assumption that
+     * they're probably broken
+     */
+    if (!FcIsAlNum(tagstring[0]) ||
+       !FcIsAlNum(tagstring[1]) ||
+       !FcIsAlNum(tagstring[2]) ||
+       !FcIsAlNum(tagstring[3]))
+       return;
+
+    if (*complex != '\0')
+       strcat (complex, " ");
+    strcat (complex, "otlayout:");
+    strcat (complex, tagstring);
 }
 
 static int
@@ -2745,6 +2766,7 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
     return TT_Err_Ok;
 
 Fail:
+    *script_count = 0;
     FT_FREE( *stags );
     return error;
 }
@@ -2756,7 +2778,8 @@ FcFontCapabilities(FT_Face face)
     FT_Error err;
     FT_ULong len = 0;
     FT_ULong *gsubtags=NULL, *gpostags=NULL;
-    FT_UShort gsub_count=0, gpos_count=0, maxsize;
+    FT_UShort gsub_count=0, gpos_count=0;
+    FT_ULong maxsize;
     FT_Memory  memory = face->stream->memory;
     FcChar8 *complex = NULL;
     int indx1 = 0, indx2 = 0;
@@ -2764,25 +2787,26 @@ FcFontCapabilities(FT_Face face)
     err = FT_Load_Sfnt_Table(face, TTAG_SILF, 0, 0, &len);
     issilgraphitefont = ( err == FT_Err_Ok);
 
-    err = GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count);
-    err = GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count);
+    if (GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count) != FT_Err_Ok)
+       gpos_count = 0;
+    if (GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count) != FT_Err_Ok)
+       gsub_count = 0;
+    
     if (!issilgraphitefont && !gsub_count && !gpos_count)
-    {
        goto bail;
-    }
 
-    maxsize = ((gpos_count + gsub_count) * 15) + (issilgraphitefont ? 13 : 0);
+    maxsize = (((FT_ULong) gpos_count + (FT_ULong) gsub_count) * OTLAYOUT_LEN + 
+              (issilgraphitefont ? 13 : 0));
     complex = malloc (sizeof (FcChar8) * maxsize);
+    if (!complex)
+       goto bail;
+
+    complex[0] = '\0';
     if (issilgraphitefont)
-    {
         strcpy(complex, "ttable:Silf ");
-    }
-    else
-    {
-        strcpy(complex, "");
-    }
 
     while ((indx1 < gsub_count) || (indx2 < gpos_count)) {
+       int len = strlen (complex);
        if (indx1 == gsub_count) {
            addtag(complex, gpostags[indx2]);
            indx2++;