src/fcfreetype.c | 82 ++++++++++--------- src/fchash.c | 234 ++++++++++++------------------------------------------- src/fcint.h | 21 +++- 3 files changed, 111 insertions(+), 226 deletions(-) New commits: commit 58acd993cb13b58c61633174071ef42da3dcac85 Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Fri May 16 15:08:52 2014 -0600 Allow passing NULL for file to FcFreeTypeQueryFace() diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 72da5ca..3dd865a 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -1321,7 +1321,7 @@ FcFreeTypeQueryFace (const FT_Face face, ++nstyle; } - if (!nfamily) + if (!nfamily && file && *file) { FcChar8 *start, *end; FcChar8 *family; @@ -1395,7 +1395,7 @@ FcFreeTypeQueryFace (const FT_Face face, if (!FcPatternAddString (pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)psname)) goto bail1; - if (!FcPatternAddString (pat, FC_FILE, file)) + if (file && *file && !FcPatternAddString (pat, FC_FILE, file)) goto bail1; if (!FcPatternAddInteger (pat, FC_INDEX, id)) commit 3f992254f2a3b7f88df989067785141cbf265037 Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Fri May 16 15:02:58 2014 -0600 Rewrite hashing to use FT_Stream directly This is more robust but introduces a small change in behavior: For .pcf.gz fonts, the new code calculates the hash of the uncompressed font data whereas the original code was calculating the hash of the compressed data. No big deal IMO. diff --git a/src/fcfreetype.c b/src/fcfreetype.c index cd354d5..72da5ca 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -1104,9 +1104,6 @@ FcFreeTypeQueryFace (const FT_Face face, char psname[256]; const char *tmp; - FcChar8 *hashstr = NULL; - FT_Error err; - FT_ULong len = 0, alen; FcRange *r = NULL; double lower_size = 0.0L, upper_size = DBL_MAX; @@ -1699,46 +1696,55 @@ FcFreeTypeQueryFace (const FT_Face face, if (!FcPatternAddBool (pat, FC_DECORATIVE, decorative)) goto bail1; - err = FT_Load_Sfnt_Table (face, 0, 0, NULL, &len); - if (err == FT_Err_Ok) + + /* + * Compute hash digest for the font + */ { - char *fontdata; - - alen = (len + 63) & ~63; - fontdata = malloc (alen); - if (!fontdata) - goto bail3; - err = FT_Load_Sfnt_Table (face, 0, 0, (FT_Byte *)fontdata, &len); - if (err != FT_Err_Ok) + FcChar8 *hashstr = NULL; + FcHashDigest digest; + + FcHashInitDigest (digest); + + if (face->stream->read == NULL) { - free (fontdata); - goto bail3; + const char *data = (const char *) face->stream->base; + size_t total_len = face->stream->size; + size_t len = total_len; + + while (len >= 64) + { + FcHashDigestAddBlock (digest, data); + data += 64; + len -= 64; + } + FcHashDigestFinish (digest, data, total_len); + } else { + char data[64]; + size_t total_len = 0; + size_t len = 0; + + while ((len = face->stream->read (face->stream, total_len, (unsigned char *) data, sizeof(data))) == 64) + { + FcHashDigestAddBlock (digest, data); + total_len += 64; + } + total_len += len; + FcHashDigestFinish (digest, data, total_len); } - memset (&fontdata[len], 0, alen - len); - hashstr = FcHashGetDigestFromMemory (fontdata, len); - free (fontdata); - } - else if (err == FT_Err_Invalid_Face_Handle) - { - /* font may not support SFNT. falling back to - * read the font data from file directly - */ - hashstr = FcHashGetDigestFromFile (file); - } - else - { - goto bail3; - } - if (hashstr) - { - if (!FcPatternAddString (pat, FC_HASH, hashstr)) + + hashstr = FcHashToString (digest); + if (hashstr) { + if (!FcPatternAddString (pat, FC_HASH, hashstr)) + { + free (hashstr); + goto bail1; + } free (hashstr); - goto bail1; } - free (hashstr); } -bail3: + /* * Compute the unicode coverage for the font diff --git a/src/fchash.c b/src/fchash.c index 3fc51f7..1526cfd 100644 --- a/src/fchash.c +++ b/src/fchash.c @@ -43,9 +43,8 @@ #define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10)) -typedef FcChar32 FcHashDigest[8]; -static void +void FcHashInitDigest (FcHashDigest digest) { static const FcHashDigest init = { @@ -56,7 +55,7 @@ FcHashInitDigest (FcHashDigest digest) memcpy (digest, init, sizeof (FcHashDigest)); } -static void +void FcHashDigestAddBlock (FcHashDigest digest, const char block[64]) { @@ -129,7 +128,7 @@ FcHashDigestAddBlock (FcHashDigest digest, #undef H } -static void +void FcHashDigestFinish (FcHashDigest digest, const char *residual, /* < 64 bytes */ size_t total_len) @@ -164,7 +163,7 @@ FcHashDigestFinish (FcHashDigest digest, FcHashDigestAddBlock (digest, ibuf); } -static FcChar8 * +FcChar8 * FcHashToString (const FcHashDigest digest) { FcChar8 *ret = NULL; @@ -188,69 +187,3 @@ FcHashToString (const FcHashDigest digest) return ret; } - -FcChar8 * -FcHashGetDigestFromFile (const FcChar8 *filename) -{ - FcHashDigest digest; - FILE *fp; - char ibuf[64]; - size_t len; - struct stat st; - - fp = fopen ((const char *)filename, "rb"); - if (!fp) - return NULL; - - FcHashInitDigest (digest); - - if (FcStat (filename, &st)) - goto bail0; - - while (!feof (fp)) - { - if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64) - { - FcHashDigestFinish (digest, ibuf, st.st_size); - break; - } - else - { - FcHashDigestAddBlock (digest, ibuf); - } - } - fclose (fp); - - return FcHashToString (digest); - -bail0: - fclose (fp); - - return NULL; -} - -FcChar8 * -FcHashGetDigestFromMemory (const char *fontdata, - size_t length) -{ - FcHashDigest digest; - size_t i = 0; - - FcHashInitDigest (digest); - - while (i <= length) - { - if ((length - i) < 64) - { - FcHashDigestFinish (digest, fontdata+i, length); - break; - } - else - { - FcHashDigestAddBlock (digest, &fontdata[i]); - } - i += 64; - } - - return FcHashToString (digest); -} diff --git a/src/fcint.h b/src/fcint.h index b15123b..3d41b0c 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -867,12 +867,23 @@ FcPrivate FcFontSet * FcFontSetDeserialize (const FcFontSet *set); /* fchash.c */ -FcPrivate FcChar8 * -FcHashGetDigestFromFile (const FcChar8 *filename); + +typedef FcChar32 FcHashDigest[8]; + +FcPrivate void +FcHashInitDigest (FcHashDigest digest); + +FcPrivate void +FcHashDigestAddBlock (FcHashDigest digest, + const char block[64]); + +FcPrivate void +FcHashDigestFinish (FcHashDigest digest, + const char *residual, /* < 64 bytes */ + size_t total_len); FcPrivate FcChar8 * -FcHashGetDigestFromMemory (const char *fontdata, - size_t length); +FcHashToString (const FcHashDigest digest); /* fcinit.c */ FcPrivate FcConfig * commit 8284df49ef45678781fc6e05d18cc04acf04cf3c Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Fri May 16 14:17:45 2014 -0600 Further simplify hash code diff --git a/src/fchash.c b/src/fchash.c index 66e73f0..3fc51f7 100644 --- a/src/fchash.c +++ b/src/fchash.c @@ -129,6 +129,41 @@ FcHashDigestAddBlock (FcHashDigest digest, #undef H } +static void +FcHashDigestFinish (FcHashDigest digest, + const char *residual, /* < 64 bytes */ + size_t total_len) +{ + char ibuf[64]; + unsigned int len = total_len % 64; + uint64_t v; + + if (!len) + return; + + memcpy (ibuf, residual, len); + memset (ibuf + len, 0, 64 - len); + ibuf[len] = 0x80; + + if ((64 - len) < 9) + { + FcHashDigestAddBlock (digest, ibuf); + memset (ibuf, 0, 64); + } + + /* set input size at the end */ + v = (uint64_t) total_len * 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; + FcHashDigestAddBlock (digest, ibuf); +} + static FcChar8 * FcHashToString (const FcHashDigest digest) { @@ -176,28 +211,7 @@ FcHashGetDigestFromFile (const FcChar8 *filename) { if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64) { - uint64_t v; - - /* add a padding */ - memset (&ibuf[len], 0, 64 - len); - ibuf[len] = 0x80; - if ((64 - len) < 9) - { - /* process a block once */ - FcHashDigestAddBlock (digest, ibuf); - memset (ibuf, 0, 64); - } - /* set input size at the end */ - v = (long)st.st_size * 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; - FcHashDigestAddBlock (digest, ibuf); + FcHashDigestFinish (digest, ibuf, st.st_size); break; } else @@ -217,10 +231,9 @@ bail0: FcChar8 * FcHashGetDigestFromMemory (const char *fontdata, - size_t length) + size_t length) { FcHashDigest digest; - char ibuf[64]; size_t i = 0; FcHashInitDigest (digest); @@ -229,32 +242,7 @@ FcHashGetDigestFromMemory (const char *fontdata, { if ((length - i) < 64) { - uint64_t 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 */ - FcHashDigestAddBlock (digest, 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; - FcHashDigestAddBlock (digest, ibuf); + FcHashDigestFinish (digest, fontdata+i, length); break; } else commit 748e77e89f8f6ba297ce9d206ac3834ae087201d Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Fri May 16 14:03:19 2014 -0600 Simplify hash code diff --git a/src/fcfreetype.c b/src/fcfreetype.c index d0932b3..cd354d5 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -1715,7 +1715,7 @@ FcFreeTypeQueryFace (const FT_Face face, goto bail3; } memset (&fontdata[len], 0, alen - len); - hashstr = FcHashGetSHA256DigestFromMemory (fontdata, len); + hashstr = FcHashGetDigestFromMemory (fontdata, len); free (fontdata); } else if (err == FT_Err_Invalid_Face_Handle) @@ -1723,7 +1723,7 @@ FcFreeTypeQueryFace (const FT_Face face, /* font may not support SFNT. falling back to * read the font data from file directly */ - hashstr = FcHashGetSHA256DigestFromFile (file); + hashstr = FcHashGetDigestFromFile (file); } else { diff --git a/src/fchash.c b/src/fchash.c index ede41d2..66e73f0 100644 --- a/src/fchash.c +++ b/src/fchash.c @@ -3,7 +3,9 @@ * * Copyright © 2003 Keith Packard * Copyright © 2013 Red Hat, Inc. + * Copyright © 2014 Google, Inc. * Red Hat Author(s): Akira TAGOH + * Google Author(s): Behdad Esfahbod * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +29,9 @@ #include <stdio.h> #include <string.h> +/* SHA256 */ + + #define ROTRN(w, v, n) ((((FcChar32)v) >> n) | (((FcChar32)v) << (w - n))) #define ROTR32(v, n) ROTRN(32, v, n) #define SHR(v, n) (v >> n) @@ -38,28 +43,22 @@ #define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10)) -static FcChar32 * -FcHashInitSHA256Digest (void) +typedef FcChar32 FcHashDigest[8]; + +static void +FcHashInitDigest (FcHashDigest digest) { - int i; - static const FcChar32 h[] = { + static const FcHashDigest init = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }; - FcChar32 *ret = malloc (sizeof (FcChar32) * 8); - - if (!ret) - return NULL; - - for (i = 0; i < 8; i++) - ret[i] = h[i]; - return ret; + memcpy (digest, init, sizeof (FcHashDigest)); } static void -FcHashComputeSHA256Digest (FcChar32 *hash, - const char *block) +FcHashDigestAddBlock (FcHashDigest digest, + const char block[64]) { static const FcChar32 k[] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, @@ -82,7 +81,7 @@ FcHashComputeSHA256Digest (FcChar32 *hash, FcChar32 w[64], i, j, t1, t2; FcChar32 a, b, c, d, e, f, g, h; -#define H(n) (hash[n]) +#define H(n) (digest[n]) a = H(0); b = H(1); @@ -131,51 +130,46 @@ FcHashComputeSHA256Digest (FcChar32 *hash, } static FcChar8 * -FcHashSHA256ToString (FcChar32 *hash) +FcHashToString (const FcHashDigest digest) { FcChar8 *ret = NULL; static const char hex[] = "0123456789abcdef"; int i, j; - if (hash) + ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1)); + if (!ret) + return NULL; + memcpy (ret, "sha256:", 7); +#define H(n) digest[n] + for (i = 0; i < 8; i++) { - ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1)); - if (!ret) - return NULL; - memcpy (ret, "sha256:", 7); -#define H(n) hash[n] - for (i = 0; i < 8; i++) - { - FcChar32 v = H(i); + FcChar32 v = H(i); - for (j = 0; j < 8; j++) - ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf]; - } - ret[7 + i * 8] = 0; -#undef H - free (hash); + for (j = 0; j < 8; j++) + ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf]; } + ret[7 + i * 8] = 0; +#undef H return ret; } FcChar8 * -FcHashGetSHA256DigestFromFile (const FcChar8 *filename) +FcHashGetDigestFromFile (const FcChar8 *filename) { - FILE *fp = fopen ((const char *)filename, "rb"); + FcHashDigest digest; + FILE *fp; char ibuf[64]; - FcChar32 *ret; size_t len; struct stat st; + fp = fopen ((const char *)filename, "rb"); if (!fp) return NULL; - if (FcStat (filename, &st)) - goto bail0; + FcHashInitDigest (digest); - ret = FcHashInitSHA256Digest (); - if (!ret) + if (FcStat (filename, &st)) goto bail0; while (!feof (fp)) @@ -190,7 +184,7 @@ FcHashGetSHA256DigestFromFile (const FcChar8 *filename) if ((64 - len) < 9) { /* process a block once */ - FcHashComputeSHA256Digest (ret, ibuf); + FcHashDigestAddBlock (digest, ibuf); memset (ibuf, 0, 64); } /* set input size at the end */ @@ -203,17 +197,17 @@ FcHashGetSHA256DigestFromFile (const FcChar8 *filename) ibuf[63 - 5] = (v >> 40) & 0xff; ibuf[63 - 6] = (v >> 48) & 0xff; ibuf[63 - 7] = (v >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, ibuf); + FcHashDigestAddBlock (digest, ibuf); break; } else { - FcHashComputeSHA256Digest (ret, ibuf); + FcHashDigestAddBlock (digest, ibuf); } } fclose (fp); - return FcHashSHA256ToString (ret); + return FcHashToString (digest); bail0: fclose (fp); @@ -222,16 +216,14 @@ bail0: } FcChar8 * -FcHashGetSHA256DigestFromMemory (const char *fontdata, +FcHashGetDigestFromMemory (const char *fontdata, size_t length) { + FcHashDigest digest; char ibuf[64]; - FcChar32 *ret; size_t i = 0; - ret = FcHashInitSHA256Digest (); - if (!ret) - return NULL; + FcHashInitDigest (digest); while (i <= length) { @@ -249,7 +241,7 @@ FcHashGetSHA256DigestFromMemory (const char *fontdata, if ((64 - n) < 9) { /* process a block once */ - FcHashComputeSHA256Digest (ret, ibuf); + FcHashDigestAddBlock (digest, ibuf); memset (ibuf, 0, 64); } /* set input size at the end */ @@ -262,15 +254,15 @@ FcHashGetSHA256DigestFromMemory (const char *fontdata, ibuf[63 - 5] = (v >> 40) & 0xff; ibuf[63 - 6] = (v >> 48) & 0xff; ibuf[63 - 7] = (v >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, ibuf); + FcHashDigestAddBlock (digest, ibuf); break; } else { - FcHashComputeSHA256Digest (ret, &fontdata[i]); + FcHashDigestAddBlock (digest, &fontdata[i]); } i += 64; } - return FcHashSHA256ToString (ret); + return FcHashToString (digest); } diff --git a/src/fcint.h b/src/fcint.h index 094e6e0..b15123b 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -868,11 +868,11 @@ FcFontSetDeserialize (const FcFontSet *set); /* fchash.c */ FcPrivate FcChar8 * -FcHashGetSHA256DigestFromFile (const FcChar8 *filename); +FcHashGetDigestFromFile (const FcChar8 *filename); FcPrivate FcChar8 * -FcHashGetSHA256DigestFromMemory (const char *fontdata, - size_t length); +FcHashGetDigestFromMemory (const char *fontdata, + size_t length); /* fcinit.c */ FcPrivate FcConfig * commit e4d8847eee14ddfa9632057bca36cb60dfa1b35f Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Fri May 16 13:45:44 2014 -0600 Remove unused code diff --git a/src/fchash.c b/src/fchash.c index 3830002..ede41d2 100644 --- a/src/fchash.c +++ b/src/fchash.c @@ -160,47 +160,6 @@ FcHashSHA256ToString (FcChar32 *hash) } FcChar8 * -FcHashGetSHA256Digest (const FcChar8 *input_strings, - size_t len) -{ - size_t i, round_len = len / 64; - char block[64]; - FcChar32 *ret = FcHashInitSHA256Digest (); - - if (!ret) - return NULL; - - for (i = 0; i < round_len; i++) - { - FcHashComputeSHA256Digest (ret, (const char *)&input_strings[i * 64]); - } - /* padding */ - if ((len % 64) != 0) - memcpy (block, &input_strings[len / 64], len % 64); - memset (&block[len % 64], 0, 64 - (len % 64)); - block[len % 64] = 0x80; - if ((64 - (len % 64)) < 9) - { - /* process a block once */ - FcHashComputeSHA256Digest (ret, block); - memset (block, 0, 64); - } - /* set input size at the end */ - len *= 8; - block[63 - 0] = (uint64_t)len & 0xff; - block[63 - 1] = ((uint64_t)len >> 8) & 0xff; - block[63 - 2] = ((uint64_t)len >> 16) & 0xff; - block[63 - 3] = ((uint64_t)len >> 24) & 0xff; - block[63 - 4] = ((uint64_t)len >> 32) & 0xff; - block[63 - 5] = ((uint64_t)len >> 40) & 0xff; - block[63 - 6] = ((uint64_t)len >> 48) & 0xff; - block[63 - 7] = ((uint64_t)len >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, block); - - return FcHashSHA256ToString (ret); -} - -FcChar8 * FcHashGetSHA256DigestFromFile (const FcChar8 *filename) { FILE *fp = fopen ((const char *)filename, "rb"); diff --git a/src/fcint.h b/src/fcint.h index 3950e01..094e6e0 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -868,10 +868,6 @@ FcFontSetDeserialize (const FcFontSet *set); /* fchash.c */ FcPrivate FcChar8 * -FcHashGetSHA256Digest (const FcChar8 *input_strings, - size_t len); - -FcPrivate FcChar8 * FcHashGetSHA256DigestFromFile (const FcChar8 *filename); FcPrivate FcChar8 *
_______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig