diff options
author | Carl Worth <cworth@cworth.org> | 2007-07-31 17:04:13 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2007-08-02 22:49:56 -0700 |
commit | 19b3b1fd8feb343a690331cafe88ef10b34b9d98 (patch) | |
tree | c67ab7ef05242b88aaf484a903766c9fe87aba13 | |
parent | 516b96387b0e57b524a37a96da22dbeeeb041712 (diff) |
Use strong hash (SHA1) for glyphs
Using a cryptographically strong hash means that comparing the
hash alone is sufficient for determining glyph equality (no need
to compare the glyph bits directly). This will allow us to replace
system-memory copies of the glyph bits, (which we've only been
holding onto for comparisons), with Pixmaps.
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | render/glyph.c | 84 | ||||
-rw-r--r-- | render/glyphstr.h | 29 | ||||
-rw-r--r-- | render/render.c | 16 |
4 files changed, 65 insertions, 66 deletions
diff --git a/configure.ac b/configure.ac index 518f332a8..89c6b55b1 100644 --- a/configure.ac +++ b/configure.ac @@ -621,7 +621,7 @@ PIXMAN="[pixman >= 0.9.2]" dnl Core modules for most extensions, et al. REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]" -REQUIRED_LIBS="xfont xau fontenc $PIXMAN" +REQUIRED_LIBS="xfont xau fontenc $PIXMAN openssl" dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config diff --git a/render/glyph.c b/render/glyph.c index 1204c3b79..7dbdda2d9 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -26,6 +26,8 @@ #include <dix-config.h> #endif +#include <openssl/sha.h> + #include "misc.h" #include "scrnintstr.h" #include "os.h" @@ -412,7 +414,10 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr) } GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]) { CARD32 elt, step, s; GlyphPtr glyph; @@ -443,7 +448,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) } else if (s == signature && (!match || - memcmp (&compare->info, &glyph->info, compare->size) == 0)) + memcmp (glyph->sha1, sha1, 20) == 0)) { break; } @@ -460,54 +465,42 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) return gr; } -CARD32 -HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size) +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]) { - CARD32 *bits; - CARD32 hash; - int n; + SHA_CTX ctx; + int success; - hash = 0; + success = SHA1_Init (&ctx); + if (! success) + return BadAlloc; - bits = (CARD32 *) gi; - n = sizeof (xGlyphInfo) / sizeof (CARD32); - while (n--) - hash ^= *bits++; + success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo)); + if (! success) + return BadAlloc; - bits = (CARD32 *) data; - n = size / sizeof (CARD32); - while (n--) - hash ^= *bits++; + success = SHA1_Update (&ctx, bits, size); + if (! success) + return BadAlloc; - return hash; -} + success = SHA1_Final (sha1, &ctx); + if (! success) + return BadAlloc; -CARD32 -HashGlyph (GlyphPtr glyph) -{ - return HashGlyphInfoAndBits (&glyph->info, - (CARD8 *) (&glyph->info + 1), - glyph->size - sizeof (xGlyphInfo)); + return Success; } GlyphPtr -FindGlyphByHash (CARD32 hash, - xGlyphInfo *gi, - CARD8 *bits, - int format) +FindGlyphByHash (unsigned char sha1[20], int format) { GlyphRefPtr gr; - GlyphPtr template; - - /* XXX: Should handle out-of-memory here */ - template = AllocateGlyph (gi, format); - memcpy ((CARD8 *) (template + 1), bits, - template->size - sizeof (xGlyphInfo)); + CARD32 signature = *(CARD32 *) sha1; gr = FindGlyphRef (&globalGlyphs[format], - hash, TRUE, template); - - xfree (template); + signature, TRUE, sha1); if (gr->glyph && gr->glyph != DeletedGlyph) return gr->glyph; @@ -553,6 +546,7 @@ FreeGlyph (GlyphPtr glyph, int format) GlyphRefPtr gr; int i; int first; + CARD32 signature; first = -1; for (i = 0; i < globalGlyphs[format].hashSet->size; i++) @@ -563,8 +557,9 @@ FreeGlyph (GlyphPtr glyph, int format) first = i; } - gr = FindGlyphRef (&globalGlyphs[format], - HashGlyph (glyph), TRUE, glyph); + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[format], signature, + TRUE, glyph->sha1); if (gr - globalGlyphs[format].table != first) DuplicateRef (glyph, "Found wrong one"); if (gr->glyph && gr->glyph != DeletedGlyph) @@ -591,12 +586,13 @@ void AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) { GlyphRefPtr gr; - CARD32 hash; + CARD32 signature; CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); /* Locate existing matching glyph */ - hash = HashGlyph (glyph); - gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { PictureScreenPtr ps; @@ -616,7 +612,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) else if (gr->glyph != glyph) { gr->glyph = glyph; - gr->signature = hash; + gr->signature = signature; globalGlyphs[glyphSet->fdepth].tableEntries++; } @@ -753,7 +749,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global) if (glyph && glyph != DeletedGlyph) { s = hash->table[i].signature; - gr = FindGlyphRef (&newHash, s, global, glyph); + gr = FindGlyphRef (&newHash, s, global, glyph->sha1); gr->signature = s; gr->glyph = glyph; ++newHash.tableEntries; diff --git a/render/glyphstr.h b/render/glyphstr.h index 37462f744..d47dfecfc 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -39,10 +39,11 @@ #define GlyphFormatNum 5 typedef struct _Glyph { - CARD32 refcnt; - DevUnion *devPrivates; - CARD32 size; /* info + bitmap */ - xGlyphInfo info; + CARD32 refcnt; + DevUnion *devPrivates; + unsigned char sha1[20]; + CARD32 size; /* info + bitmap */ + xGlyphInfo info; /* bits follow */ } GlyphRec, *GlyphPtr; @@ -127,19 +128,19 @@ GlyphHashSetPtr FindGlyphHashSet (CARD32 filled); GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]); GlyphPtr -FindGlyphByHash (CARD32 hash, - xGlyphInfo *gi, - CARD8 *bits, - int format); - -CARD32 -HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size); +FindGlyphByHash (unsigned char sha1[20], int format); -CARD32 -HashGlyph (GlyphPtr glyph); +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]); void FreeGlyph (GlyphPtr glyph, int format); diff --git a/render/render.c b/render/render.c index 831c98417..c7a6dcb44 100644 --- a/render/render.c +++ b/render/render.c @@ -1080,10 +1080,10 @@ ProcRenderFreeGlyphSet (ClientPtr client) } typedef struct _GlyphNew { - Glyph id; - GlyphPtr glyph; - Bool found; - CARD32 hash; + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; } GlyphNewRec, *GlyphNewPtr; static int @@ -1143,10 +1143,11 @@ ProcRenderAddGlyphs (ClientPtr client) if (remain < size) break; - glyph_new->hash = HashGlyphInfoAndBits (&gi[i], bits, size); + err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; - glyph_new->glyph = FindGlyphByHash (glyph_new->hash, - &gi[i], bits, + glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, glyphSet->fdepth); if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) @@ -1164,6 +1165,7 @@ ProcRenderAddGlyphs (ClientPtr client) } memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size); + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); } glyph_new->id = gids[i]; |