summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2022-07-03 20:53:23 -0400
committerThomas E. Dickey <dickey@invisible-island.net>2022-07-06 04:27:49 -0400
commit33c1e1e3a5c08b690e145cc193d52fc13869af7b (patch)
tree9e2cf966df37b99763a4ce8f3f89a505c63a001b
parent114db90eac2c0f32f6b662d916a5af6a8990bf36 (diff)
downloadxorg-lib-libXft-33c1e1e3a5c08b690e145cc193d52fc13869af7b.tar.gz
validate linked-list updates with _XftValidateGlyphUsage
Signed-off-by: Thomas E. Dickey <dickey@invisible-island.net>
-rw-r--r--src/xftfreetype.c2
-rw-r--r--src/xftglyphs.c106
-rw-r--r--src/xftint.h1
3 files changed, 92 insertions, 17 deletions
diff --git a/src/xftfreetype.c b/src/xftfreetype.c
index fd0c483..8504ce0 100644
--- a/src/xftfreetype.c
+++ b/src/xftfreetype.c
@@ -1052,7 +1052,7 @@ XftFontDestroy (Display *dpy, XftFont *public)
{
XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False);
XftFontInt *font = (XftFontInt *) public;
- int i;
+ FT_UInt i;
/* note reduction in memory use */
if (info)
diff --git a/src/xftglyphs.c b/src/xftglyphs.c
index de78918..7e238b3 100644
--- a/src/xftglyphs.c
+++ b/src/xftglyphs.c
@@ -52,6 +52,68 @@ _XftFontValidateMemory (Display *dpy _X_UNUSED, XftFont *public)
font->glyph_memory, glyph_memory);
}
+/*
+ * Validate the glyph usage-links for a font.
+ */
+static void
+_XftValidateGlyphUsage(XftFontInt *font)
+{
+ if (font->newest != FT_UINT_MAX) {
+ FT_UInt forward;
+ FT_UInt reverse;
+ FT_UInt next;
+ XftGlyphUsage *x1st = (XftGlyphUsage *) font->glyphs[font->newest];
+ XftGlyphUsage *xuse = x1st;
+ for (forward = 1,
+ next = x1st->newer;
+ xuse != NULL &&
+ next != font->newest;
+ next = xuse->newer) {
+ if (next >= font->num_glyphs) {
+ printf("Xft: out of range; %d\n", next);
+ break;
+ }
+ if (++forward > font->total_inuse) {
+ printf("Xft: too many in-use glyphs (%d vs %d)\n",
+ forward, font->total_inuse);
+ if (forward > font->total_inuse + 10)
+ break;
+ }
+ xuse = (XftGlyphUsage *) font->glyphs[next];
+ }
+ if (forward < font->total_inuse) {
+ printf("Xft: too few in-use glyphs (%u vs %d)\n",
+ forward, font->total_inuse);
+ }
+ for (reverse = 1,
+ next = x1st->older;
+ xuse != NULL &&
+ next != font->newest;
+ next = xuse->older) {
+ if (next >= font->num_glyphs) {
+ printf("Xft out of range; %d\n", next);
+ break;
+ }
+ if (++reverse > font->total_inuse) {
+ printf("Xft: too many in-use glyphs (%d vs %d)\n",
+ reverse, font->total_inuse);
+ if (reverse > font->total_inuse + 10)
+ break;
+ }
+ xuse = (XftGlyphUsage *) font->glyphs[next];
+ }
+ if (reverse < font->total_inuse) {
+ printf("Xft: too few in-use glyphs (%u vs %d)\n",
+ reverse, font->total_inuse);
+ }
+ if (forward != reverse) {
+ printf("Xft: forward %d vs reverse %d\n",
+ forward, reverse);
+ exit(1);
+ }
+ }
+}
+
/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
* into a different format. For example, we want to convert a
* FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
@@ -716,28 +778,37 @@ XftFontLoadGlyphs (Display *dpy,
xftg->glyph_memory);
if (font->track_mem_usage) {
- XftGlyphUsage *xnew = (XftGlyphUsage *) xftg;
+ XftGlyphUsage *xuse = (XftGlyphUsage *) xftg;
if (font->newest == FT_UINT_MAX) {
- xnew->older = glyphindex;
- xnew->newer = glyphindex;
+ xuse->older = glyphindex;
+ xuse->newer = glyphindex;
+ if (XftDebug() & XFT_DBG_USAGE)
+ printf("alloc %d: %p USE %d.%d\n", glyphindex,
+ (void *) xuse, xuse->older, xuse->newer);
} else {
+ XftGlyphUsage *xnew;
XftGlyphUsage *xold;
- xold = (XftGlyphUsage *) font->glyphs[font->newest];
-
- xnew->older = font->newest;
- xnew->newer = xold->newer;
- xold->newer = glyphindex;
- if (XftDebug() & XFT_DBG_CACHEV)
- printf("alloc %p NEW %d.%d, OLD %d.%d\n", xnew,
- xnew->older, xnew->newer,
- xold->older, xold->newer);
+ xnew = (XftGlyphUsage *) font->glyphs[font->newest];
+ xold = (XftGlyphUsage *) font->glyphs[xnew->newer];
+
+ xuse->older = font->newest;
+ xuse->newer = xnew->newer;
+ xnew->newer = glyphindex;
+ xold->older = glyphindex;
+ if (XftDebug() & XFT_DBG_USAGE)
+ printf("alloc %d: %p USE %d.%d, %p NEW %d.%d %p OLD %d.%d\n",
+ glyphindex,
+ (void *) xuse, xuse->older, xuse->newer,
+ (void *) xnew, xnew->older, xnew->newer,
+ (void *) xold, xold->older, xold->newer);
}
font->newest = glyphindex;
font->total_inuse++;
- // FIXME - validate
+ if (XftDebug() & XFT_DBG_USAGE)
+ _XftValidateGlyphUsage(font);
}
}
if (bufBitmap != bufLocal)
@@ -794,7 +865,8 @@ XftFontUnloadGlyphs (Display *dpy,
XftGlyphUsage *xtmp;
if (XftDebug() & XFT_DBG_CACHEV)
- printf("free %p USE %d.%d\n", xuse, xuse->older, xuse->newer);
+ printf("free %p USE %d.%d\n",
+ (void *) xuse, xuse->older, xuse->newer);
if (xuse->older != FT_UINT_MAX) {
xtmp = (XftGlyphUsage *) font->glyphs[xuse->older];
@@ -802,8 +874,9 @@ XftFontUnloadGlyphs (Display *dpy,
/* update link around to oldest glyph */
xtmp->newer = xuse->newer;
}
- if (font->newest == glyphindex)
+ if (font->newest == glyphindex) {
font->newest = xuse->older;
+ }
}
if (xuse->newer != FT_UINT_MAX) {
xtmp = (XftGlyphUsage *) font->glyphs[xuse->newer];
@@ -817,7 +890,8 @@ XftFontUnloadGlyphs (Display *dpy,
} else {
fprintf (stderr, "Xft: glyph count error\n");
}
- // FIXME - validate
+ if (XftDebug() & XFT_DBG_USAGE)
+ _XftValidateGlyphUsage(font);
}
free (xftg);
diff --git a/src/xftint.h b/src/xftint.h
index 3304217..1e292d7 100644
--- a/src/xftint.h
+++ b/src/xftint.h
@@ -301,6 +301,7 @@ extern XftDisplayInfo *_XftDisplayInfo;
#define XFT_DBG_CACHE 128
#define XFT_DBG_CACHEV 256
#define XFT_DBG_MEMORY 512
+#define XFT_DBG_USAGE 1024
/*
* Categories for memory allocation.