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:
		
							parent
							
								
									e85b6b6466
								
							
						
					
					
						commit
						a8cb8e9454
					
				
							
								
								
									
										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,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue