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.
This commit is contained in:
Carl Worth 2007-07-31 17:04:13 -07:00
parent 516b96387b
commit 19b3b1fd8f
4 changed files with 65 additions and 66 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);
FindGlyphByHash (unsigned char sha1[20], int format);
CARD32
HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size);
CARD32
HashGlyph (GlyphPtr glyph);
int
HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
unsigned char sha1[20]);
void
FreeGlyph (GlyphPtr glyph, int format);

View File

@ -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];