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:
parent
516b96387b
commit
19b3b1fd8f
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
typedef struct _Glyph {
|
||||
CARD32 refcnt;
|
||||
DevUnion *devPrivates;
|
||||
unsigned char sha1[20];
|
||||
CARD32 size; /* info + bitmap */
|
||||
xGlyphInfo info;
|
||||
/* bits follow */
|
||||
|
@ -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,
|
||||
FindGlyphByHash (unsigned char sha1[20], int format);
|
||||
|
||||
int
|
||||
HashGlyph (xGlyphInfo *gi,
|
||||
CARD8 *bits,
|
||||
int format);
|
||||
|
||||
CARD32
|
||||
HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size);
|
||||
|
||||
CARD32
|
||||
HashGlyph (GlyphPtr glyph);
|
||||
unsigned long size,
|
||||
unsigned char sha1[20]);
|
||||
|
||||
void
|
||||
FreeGlyph (GlyphPtr glyph, int format);
|
||||
|
|
|
@ -1083,7 +1083,7 @@ typedef struct _GlyphNew {
|
|||
Glyph id;
|
||||
GlyphPtr glyph;
|
||||
Bool found;
|
||||
CARD32 hash;
|
||||
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];
|
||||
|
|
Loading…
Reference in New Issue
Block a user