tfix use after free in font caching algorithm - st - [fork] customized build of… | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit a8cb8e94547d7e31441d2444e8a196415e3e4c1f | |
parent e85b6b64660214121164ea97fb098eaa4935f7db | |
Author: magras <[email protected]> | |
Date: Thu, 28 Feb 2019 04:56:01 +0300 | |
fix use after free in font caching algorithm | |
Current font caching algorithm contains a use after free error. A font | |
removed from `frc` might be still listed in `wx.specbuf`. It will lead | |
tto a crash inside `XftDrawGlyphFontSpec()`. | |
Steps to reproduce: | |
$ st -f 'Misc Tamsyn:scalable=false' | |
$ curl https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt | |
Of course, result depends on fonts installed on a system and fontconfig. | |
In my case, I'm getting consistent segfaults with different fonts. | |
I replaced a fixed array with a simple unbounded buffer with a constant | |
growth rate. Cache starts with a capacity of 0, gets increments by 16, | |
and never shrinks. On my machine after `cat UTF-8-demo.txt` buffer | |
reaches a capacity of 192. During casual use capacity stays at 0. | |
Diffstat: | |
M x.c | 15 +++++++++------ | |
1 file changed, 9 insertions(+), 6 deletions(-) | |
--- | |
diff --git a/x.c b/x.c | |
t@@ -226,8 +226,9 @@ typedef struct { | |
} Fontcache; | |
/* Fontcache is an array now. A new font will be appended to the array. */ | |
-static Fontcache frc[16]; | |
+static Fontcache *frc = NULL; | |
static int frclen = 0; | |
+static int frccap = 0; | |
static char *usedfont = NULL; | |
static double usedfontsize = 0; | |
static double defaultfontsize = 0; | |
t@@ -1244,12 +1245,14 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Gly… | |
fcpattern, &fcres); | |
/* | |
- * Overwrite or create the new cache entry. | |
+ * Allocate memory for the new cache entry. | |
*/ | |
- if (frclen >= LEN(frc)) { | |
- frclen = LEN(frc) - 1; | |
- XftFontClose(xw.dpy, frc[frclen].font); | |
- frc[frclen].unicodep = 0; | |
+ if (frclen >= frccap) { | |
+ frccap += 16; | |
+ if (!frc) | |
+ frc = xmalloc(frccap * sizeof(Fontcach… | |
+ else | |
+ frc = xrealloc(frc, frccap * sizeof(Fo… | |
} | |
frc[frclen].font = XftFontOpenPattern(xw.dpy, |