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 to 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.
This commit is contained in:
		
							
								
								
									
										15
									
								
								x.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								x.c
									
									
									
									
									
								
							| @@ -226,8 +226,9 @@ typedef struct { | |||||||
| } Fontcache; | } Fontcache; | ||||||
|  |  | ||||||
| /* Fontcache is an array now. A new font will be appended to the array. */ | /* 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 frclen = 0; | ||||||
|  | static int frccap = 0; | ||||||
| static char *usedfont = NULL; | static char *usedfont = NULL; | ||||||
| static double usedfontsize = 0; | static double usedfontsize = 0; | ||||||
| static double defaultfontsize = 0; | static double defaultfontsize = 0; | ||||||
| @@ -1244,12 +1245,14 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x | |||||||
| 					fcpattern, &fcres); | 					fcpattern, &fcres); | ||||||
|  |  | ||||||
| 			/* | 			/* | ||||||
| 			 * Overwrite or create the new cache entry. | 			 * Allocate memory for the new cache entry. | ||||||
| 			 */ | 			 */ | ||||||
| 			if (frclen >= LEN(frc)) { | 			if (frclen >= frccap) { | ||||||
| 				frclen = LEN(frc) - 1; | 				frccap += 16; | ||||||
| 				XftFontClose(xw.dpy, frc[frclen].font); | 				if (!frc) | ||||||
| 				frc[frclen].unicodep = 0; | 					frc = xmalloc(frccap * sizeof(Fontcache)); | ||||||
|  | 				else | ||||||
|  | 					frc = xrealloc(frc, frccap * sizeof(Fontcache)); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			frc[frclen].font = XftFontOpenPattern(xw.dpy, | 			frc[frclen].font = XftFontOpenPattern(xw.dpy, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user