From 33c1e1e3a5c08b690e145cc193d52fc13869af7b Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 3 Jul 2022 20:53:23 -0400 Subject: validate linked-list updates with _XftValidateGlyphUsage Signed-off-by: Thomas E. Dickey --- src/xftfreetype.c | 2 +- src/xftglyphs.c | 106 +++++++++++++++++++++++++++++++++++++++++++++--------- src/xftint.h | 1 + 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. -- cgit v1.2.3