summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2007-07-31 17:04:13 -0700
committerCarl Worth <cworth@cworth.org>2007-08-02 22:49:56 -0700
commit19b3b1fd8feb343a690331cafe88ef10b34b9d98 (patch)
treec67ab7ef05242b88aaf484a903766c9fe87aba13 /render
parent516b96387b0e57b524a37a96da22dbeeeb041712 (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.
Diffstat (limited to 'render')
-rw-r--r--render/glyph.c84
-rw-r--r--render/glyphstr.h29
-rw-r--r--render/render.c16
3 files changed, 64 insertions, 65 deletions
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];