Source

m0e-vabs / var / vabs / fontconfig / src / patches / fontconfig-2.10.92-fix-woff.patch

Full commit
diff --git a/src/fcfreetype.c b/src/fcfreetype.c
index 8a037c0..5e8990d 100644
--- a/src/fcfreetype.c
+++ b/src/fcfreetype.c
@@ -1104,7 +1104,10 @@ FcFreeTypeQueryFace (const FT_Face  face,
     char	    psname[256];
     const char	    *tmp;
 
-    FcChar8	    *hashstr;
+    FcChar8	    *hashstr = NULL;
+    char	    *fontdata = NULL;
+    FT_Error	    err;
+    FT_ULong	    len = 0, alen;
 
     pat = FcPatternCreate ();
     if (!pat)
@@ -1662,12 +1665,34 @@ FcFreeTypeQueryFace (const FT_Face  face,
     if (!FcPatternAddBool (pat, FC_DECORATIVE, decorative))
 	goto bail1;
 
-    hashstr = FcHashGetSHA256DigestFromFile (file);
+    err = FT_Load_Sfnt_Table (face, 0, 0, NULL, &len);
+    if (err == FT_Err_Ok)
+    {
+	alen = (len + 63) & ~63;
+	fontdata = malloc (alen);
+	if (!fontdata)
+	    goto bail1;
+	err = FT_Load_Sfnt_Table (face, 0, 0, (FT_Byte *)fontdata, &len);
+	if (err != FT_Err_Ok)
+	    goto bail1;
+	memset (&fontdata[len], 0, alen - len);
+	hashstr = FcHashGetSHA256DigestFromMemory (fontdata, len);
+    }
+    else if (err == FT_Err_Invalid_Face_Handle)
+    {
+	/* font may not support SFNT. falling back to
+	 * read the font data from file directly
+	 */
+	hashstr = FcHashGetSHA256DigestFromFile (file);
+    }
+    else
+    {
+	goto bail1;
+    }
     if (!hashstr)
 	goto bail1;
     if (!FcPatternAddString (pat, FC_HASH, hashstr))
 	goto bail1;
-    free (hashstr);
 
     /*
      * Compute the unicode coverage for the font
@@ -1756,6 +1781,10 @@ FcFreeTypeQueryFace (const FT_Face  face,
 bail2:
     FcCharSetDestroy (cs);
 bail1:
+    if (hashstr)
+	free (hashstr);
+    if (fontdata)
+	free (fontdata);
     FcPatternDestroy (pat);
 bail0:
     return NULL;
diff --git a/src/fchash.c b/src/fchash.c
index 827b20f..92585a6 100644
--- a/src/fchash.c
+++ b/src/fchash.c
@@ -220,7 +220,7 @@ FcHashGetSHA256DigestFromFile (const FcChar8 *filename)
 
     ret = FcHashInitSHA256Digest ();
     if (!ret)
-	return NULL;
+	goto bail0;
 
     while (!feof (fp))
     {
@@ -261,5 +261,60 @@ FcHashGetSHA256DigestFromFile (const FcChar8 *filename)
 
 bail0:
     fclose (fp);
+
     return NULL;
 }
+
+FcChar8 *
+FcHashGetSHA256DigestFromMemory (const char *fontdata,
+				 size_t      length)
+{
+    char ibuf[64];
+    FcChar32 *ret;
+    size_t i = 0;
+
+    ret = FcHashInitSHA256Digest ();
+    if (!ret)
+	return NULL;
+
+    while (i <= length)
+    {
+	if ((length - i) < 64)
+	{
+	    long v;
+	    size_t n;
+
+	    /* add a padding */
+	    n = length - i;
+	    if (n > 0)
+		memcpy (ibuf, &fontdata[i], n);
+	    memset (&ibuf[n], 0, 64 - n);
+	    ibuf[n] = 0x80;
+	    if ((64 - n) < 9)
+	    {
+		/* process a block once */
+		FcHashComputeSHA256Digest (ret, ibuf);
+		memset (ibuf, 0, 64);
+	    }
+	    /* set input size at the end */
+	    v = length * 8;
+	    ibuf[63 - 0] =  v        & 0xff;
+	    ibuf[63 - 1] = (v >>  8) & 0xff;
+	    ibuf[63 - 2] = (v >> 16) & 0xff;
+	    ibuf[63 - 3] = (v >> 24) & 0xff;
+	    ibuf[63 - 4] = (v >> 32) & 0xff;
+	    ibuf[63 - 5] = (v >> 40) & 0xff;
+	    ibuf[63 - 6] = (v >> 48) & 0xff;
+	    ibuf[63 - 7] = (v >> 56) & 0xff;
+	    FcHashComputeSHA256Digest (ret, ibuf);
+	    break;
+	}
+	else
+	{
+	    FcHashComputeSHA256Digest (ret, &fontdata[i]);
+	}
+	i += 64;
+    }
+
+    return FcHashSHA256ToString (ret);
+}
diff --git a/src/fcint.h b/src/fcint.h
index c45075e..8919958 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -818,9 +818,14 @@ FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s);
 FcPrivate FcChar8 *
 FcHashGetSHA256Digest (const FcChar8 *input_strings,
 		       size_t         len);
+
 FcPrivate FcChar8 *
 FcHashGetSHA256DigestFromFile (const FcChar8 *filename);
 
+FcPrivate FcChar8 *
+FcHashGetSHA256DigestFromMemory (const char *fontdata,
+				 size_t      length);
+
 /* fcinit.c */
 FcPrivate FcConfig *
 FcInitLoadOwnConfig (FcConfig *config);