Bug Summary

File:xftdpy.c
Location:line 54, column 13
Description:Access to field 'next' results in a dereference of a null pointer (loaded from variable 'info')

Annotated Source Code

1/*
2 * Copyright © 2000 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include "xftint.h"
24
25_X_HIDDEN__attribute__((visibility("hidden"))) XftDisplayInfo *_XftDisplayInfo;
26
27static int
28_XftCloseDisplay (Display *dpy, XExtCodes *codes)
29{
30 XftDisplayInfo *info, **prev;
31
32 info = _XftDisplayInfoGet (dpy, FcFalse0);
33 if (!info)
1
Assuming 'info' is non-null
2
Taking false branch
34 return 0;
35
36 /*
37 * Get rid of any dangling unreferenced fonts
38 */
39 info->max_unref_fonts = 0;
40 XftFontManageMemory (dpy);
41
42 /*
43 * Clean up the default values
44 */
45 if (info->defaults)
3
Taking false branch
46 FcPatternDestroy (info->defaults);
47
48 /*
49 * Unhook from the global list
50 */
51 for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
4
Loop condition is false. Execution continues on line 54
52 if (info->display == dpy)
53 break;
54 *prev = info->next;
5
Access to field 'next' results in a dereference of a null pointer (loaded from variable 'info')
55
56 free (info);
57 return 0;
58}
59
60
61_X_HIDDEN__attribute__((visibility("hidden"))) XftDisplayInfo *
62_XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary)
63{
64 XftDisplayInfo *info, **prev;
65 XRenderPictFormat pf;
66 int i;
67 int event_base, error_base;
68
69 for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
70 {
71 if (info->display == dpy)
72 {
73 /*
74 * MRU the list
75 */
76 if (prev != &_XftDisplayInfo)
77 {
78 *prev = info->next;
79 info->next = _XftDisplayInfo;
80 _XftDisplayInfo = info;
81 }
82 return info;
83 }
84 }
85 if (!createIfNecessary)
86 return NULL((void*)0);
87
88 info = (XftDisplayInfo *) malloc (sizeof (XftDisplayInfo));
89 if (!info)
90 goto bail0;
91 info->codes = XAddExtension (dpy);
92 if (!info->codes)
93 goto bail1;
94 (void) XESetCloseDisplay (dpy, info->codes->extension, _XftCloseDisplay);
95
96 info->display = dpy;
97 info->defaults = NULL((void*)0);
98 info->solidFormat = NULL((void*)0);
99 info->hasRender = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
100 (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))((&((_XPrivDisplay)dpy)->screens[(((_XPrivDisplay)dpy)
->default_screen)])->root_visual)
) != NULL((void*)0)));
101 info->use_free_glyphs = FcTrue1;
102 if (info->hasRender)
103 {
104 int major, minor;
105 XRenderQueryVersion (dpy, &major, &minor);
106 if (major < 0 || (major == 0 && minor <= 2))
107 info->use_free_glyphs = FcFalse0;
108
109 pf.type = PictTypeDirect1;
110 pf.depth = 32;
111 pf.direct.redMask = 0xff;
112 pf.direct.greenMask = 0xff;
113 pf.direct.blueMask = 0xff;
114 pf.direct.alphaMask = 0xff;
115 info->solidFormat = XRenderFindFormat (dpy,
116 (PictFormatType(1 << 1)|
117 PictFormatDepth(1 << 2)|
118 PictFormatRedMask(1 << 4)|
119 PictFormatGreenMask(1 << 6)|
120 PictFormatBlueMask(1 << 8)|
121 PictFormatAlphaMask(1 << 10)),
122 &pf,
123 0);
124 }
125 if (XftDebug () & XFT_DBG_RENDER4)
126 {
127 Visual *visual = DefaultVisual (dpy, DefaultScreen (dpy))((&((_XPrivDisplay)dpy)->screens[(((_XPrivDisplay)dpy)
->default_screen)])->root_visual)
;
128 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
129
130 printf ("XftDisplayInfoGet Default visual 0x%x ",
131 (int) visual->visualid);
132 if (format)
133 {
134 if (format->type == PictTypeDirect1)
135 {
136 printf ("format %d,%d,%d,%d\n",
137 format->direct.alpha,
138 format->direct.red,
139 format->direct.green,
140 format->direct.blue);
141 }
142 else
143 {
144 printf ("format indexed\n");
145 }
146 }
147 else
148 printf ("No Render format for default visual\n");
149
150 printf ("XftDisplayInfoGet initialized, hasRender set to \"%s\"\n",
151 info->hasRender ? "True" : "False");
152 }
153 for (i = 0; i < XFT_NUM_SOLID_COLOR16; i++)
154 {
155 info->colors[i].screen = -1;
156 info->colors[i].pict = 0;
157 }
158 info->fonts = NULL((void*)0);
159
160 info->next = _XftDisplayInfo;
161 _XftDisplayInfo = info;
162
163 info->glyph_memory = 0;
164 info->max_glyph_memory = XftDefaultGetInteger (dpy,
165 XFT_MAX_GLYPH_MEMORY"maxglyphmemory", 0,
166 XFT_DPY_MAX_GLYPH_MEMORY(4 * 1024 * 1024));
167 if (XftDebug () & XFT_DBG_CACHE128)
168 printf ("global max cache memory %ld\n", info->max_glyph_memory);
169
170
171 info->num_unref_fonts = 0;
172 info->max_unref_fonts = XftDefaultGetInteger (dpy,
173 XFT_MAX_UNREF_FONTS"maxunreffonts", 0,
174 XFT_DPY_MAX_UNREF_FONTS16);
175 if (XftDebug() & XFT_DBG_CACHE128)
176 printf ("global max unref fonts %d\n", info->max_unref_fonts);
177
178 memset (info->fontHash, '\0', sizeof (XftFont *) * XFT_NUM_FONT_HASH127);
179 return info;
180
181bail1:
182 free (info);
183bail0:
184 if (XftDebug () & XFT_DBG_RENDER4)
185 {
186 printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n");
187 }
188 return NULL((void*)0);
189}
190
191/*
192 * Reduce memory usage in X server
193 */
194
195static void
196_XftDisplayValidateMemory (XftDisplayInfo *info)
197{
198 XftFont *public;
199 XftFontInt *font;
200 unsigned long glyph_memory;
201
202 glyph_memory = 0;
203 for (public = info->fonts; public; public = font->next)
204 {
205 font = (XftFontInt *) public;
206 glyph_memory += font->glyph_memory;
207 }
208 if (glyph_memory != info->glyph_memory)
209 printf ("Display glyph cache incorrect has %ld bytes, should have %ld\n",
210 info->glyph_memory, glyph_memory);
211}
212
213_X_HIDDEN__attribute__((visibility("hidden"))) void
214_XftDisplayManageMemory (Display *dpy)
215{
216 XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False0);
217 unsigned long glyph_memory;
218 XftFont *public;
219 XftFontInt *font;
220
221 if (!info || !info->max_glyph_memory)
222 return;
223 if (XftDebug () & XFT_DBG_CACHE128)
224 {
225 if (info->glyph_memory > info->max_glyph_memory)
226 printf ("Reduce global memory from %ld to %ld\n",
227 info->glyph_memory, info->max_glyph_memory);
228 _XftDisplayValidateMemory (info);
229 }
230 while (info->glyph_memory > info->max_glyph_memory)
231 {
232 glyph_memory = rand () % info->glyph_memory;
233 public = info->fonts;
234 while (public)
235 {
236 font = (XftFontInt *) public;
237
238 if (font->glyph_memory > glyph_memory)
239 {
240 _XftFontUncacheGlyph (dpy, public);
241 break;
242 }
243 public = font->next;
244 glyph_memory -= font->glyph_memory;
245 }
246 }
247 if (XftDebug () & XFT_DBG_CACHE128)
248 _XftDisplayValidateMemory (info);
249}
250
251_X_EXPORT__attribute__((visibility("default"))) Boolint
252XftDefaultHasRender (Display *dpy)
253{
254 XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True1);
255
256 if (!info)
257 return False0;
258 return info->hasRender;
259}
260
261_X_EXPORT__attribute__((visibility("default"))) Boolint
262XftDefaultSet (Display *dpy, FcPattern *defaults)
263{
264 XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True1);
265
266 if (!info)
267 return False0;
268 if (info->defaults)
269 FcPatternDestroy (info->defaults);
270 info->defaults = defaults;
271 if (!info->max_glyph_memory)
272 info->max_glyph_memory = XFT_DPY_MAX_GLYPH_MEMORY(4 * 1024 * 1024);
273 info->max_glyph_memory = XftDefaultGetInteger (dpy,
274 XFT_MAX_GLYPH_MEMORY"maxglyphmemory", 0,
275 info->max_glyph_memory);
276 if (!info->max_unref_fonts)
277 info->max_unref_fonts = XFT_DPY_MAX_UNREF_FONTS16;
278 info->max_unref_fonts = XftDefaultGetInteger (dpy,
279 XFT_MAX_UNREF_FONTS"maxunreffonts", 0,
280 info->max_unref_fonts);
281 return True1;
282}
283
284_X_HIDDEN__attribute__((visibility("hidden"))) int
285XftDefaultParseBool (const char *v)
286{
287 char c0, c1;
288
289 c0 = *v;
290 if (isupper ((int)c0)((*__ctype_b_loc ())[(int) (((int)c0))] & (unsigned short
int) _ISupper)
)
291 c0 = tolower (c0);
292 if (c0 == 't' || c0 == 'y' || c0 == '1')
293 return 1;
294 if (c0 == 'f' || c0 == 'n' || c0 == '0')
295 return 0;
296 if (c0 == 'o')
297 {
298 c1 = v[1];
299 if (isupper ((int)c1)((*__ctype_b_loc ())[(int) (((int)c1))] & (unsigned short
int) _ISupper)
)
300 c1 = tolower (c1);
301 if (c1 == 'n')
302 return 1;
303 if (c1 == 'f')
304 return 0;
305 }
306 return -1;
307}
308
309static Boolint
310_XftDefaultInitBool (Display *dpy, FcPattern *pat, const char *option)
311{
312 char *v;
313 int i;
314
315 v = XGetDefault (dpy, "Xft", option);
316 if (v && (i = XftDefaultParseBool (v)) >= 0)
317 return FcPatternAddBool (pat, option, i != 0);
318 return True1;
319}
320
321static Boolint
322_XftDefaultInitDouble (Display *dpy, FcPattern *pat, const char *option)
323{
324 char *v, *e;
325 double d;
326
327 v = XGetDefault (dpy, "Xft", option);
328 if (v)
329 {
330 d = strtod (v, &e);
331 if (e != v)
332 return FcPatternAddDouble (pat, option, d);
333 }
334 return True1;
335}
336
337static Boolint
338_XftDefaultInitInteger (Display *dpy, FcPattern *pat, const char *option)
339{
340 char *v, *e;
341 int i;
342
343 v = XGetDefault (dpy, "Xft", option);
344 if (v)
345 {
346 if (FcNameConstant ((FcChar8 *) v, &i))
347 return FcPatternAddInteger (pat, option, i);
348 i = strtol (v, &e, 0);
349 if (e != v)
350 return FcPatternAddInteger (pat, option, i);
351 }
352 return True1;
353}
354
355static FcPattern *
356_XftDefaultInit (Display *dpy)
357{
358 FcPattern *pat;
359
360 pat = FcPatternCreate ();
361 if (!pat)
362 goto bail0;
363
364 if (!_XftDefaultInitDouble (dpy, pat, FC_SCALE"scale"))
365 goto bail1;
366 if (!_XftDefaultInitDouble (dpy, pat, FC_DPI"dpi"))
367 goto bail1;
368 if (!_XftDefaultInitBool (dpy, pat, XFT_RENDER"render"))
369 goto bail1;
370 if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA"rgba"))
371 goto bail1;
372 if (!_XftDefaultInitInteger (dpy, pat, FC_LCD_FILTER"lcdfilter"))
373 goto bail1;
374 if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS"antialias"))
375 goto bail1;
376 if (!_XftDefaultInitBool (dpy, pat, FC_EMBOLDEN"embolden"))
377 goto bail1;
378 if (!_XftDefaultInitBool (dpy, pat, FC_AUTOHINT"autohint"))
379 goto bail1;
380 if (!_XftDefaultInitInteger (dpy, pat, FC_HINT_STYLE"hintstyle"))
381 goto bail1;
382 if (!_XftDefaultInitBool (dpy, pat, FC_HINTING"hinting"))
383 goto bail1;
384 if (!_XftDefaultInitBool (dpy, pat, FC_MINSPACE"minspace"))
385 goto bail1;
386 if (!_XftDefaultInitInteger (dpy, pat, XFT_MAX_GLYPH_MEMORY"maxglyphmemory"))
387 goto bail1;
388
389 return pat;
390
391bail1:
392 FcPatternDestroy (pat);
393bail0:
394 return NULL((void*)0);
395}
396
397static FcResult
398_XftDefaultGet (Display *dpy, const char *object, int screen, FcValue *v)
399{
400 XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True1);
401 FcResult r;
402
403 if (!info)
404 return FcResultNoMatch;
405
406 if (!info->defaults)
407 {
408 info->defaults = _XftDefaultInit (dpy);
409 if (!info->defaults)
410 return FcResultNoMatch;
411 }
412 r = FcPatternGet (info->defaults, object, screen, v);
413 if (r == FcResultNoId && screen > 0)
414 r = FcPatternGet (info->defaults, object, 0, v);
415 return r;
416}
417
418_X_HIDDEN__attribute__((visibility("hidden"))) Boolint
419XftDefaultGetBool (Display *dpy, const char *object, int screen, Boolint def)
420{
421 FcResult r;
422 FcValue v;
423
424 r = _XftDefaultGet (dpy, object, screen, &v);
425 if (r != FcResultMatch || v.type != FcTypeBool)
426 return def;
427 return v.u.b;
428}
429
430_X_HIDDEN__attribute__((visibility("hidden"))) int
431XftDefaultGetInteger (Display *dpy, const char *object, int screen, int def)
432{
433 FcResult r;
434 FcValue v;
435
436 r = _XftDefaultGet (dpy, object, screen, &v);
437 if (r != FcResultMatch || v.type != FcTypeInteger)
438 return def;
439 return v.u.i;
440}
441
442_X_HIDDEN__attribute__((visibility("hidden"))) double
443XftDefaultGetDouble (Display *dpy, const char *object, int screen, double def)
444{
445 FcResult r;
446 FcValue v;
447
448 r = _XftDefaultGet (dpy, object, screen, &v);
449 if (r != FcResultMatch || v.type != FcTypeDouble)
450 return def;
451 return v.u.d;
452}
453
454_X_EXPORT__attribute__((visibility("default"))) void
455XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
456{
457 FcValue v;
458 double dpi;
459
460 if (FcPatternGet (pattern, XFT_RENDER"render", 0, &v) == FcResultNoMatch)
461 {
462 FcPatternAddBool (pattern, XFT_RENDER"render",
463 XftDefaultGetBool (dpy, XFT_RENDER"render", screen,
464 XftDefaultHasRender (dpy)));
465 }
466 if (FcPatternGet (pattern, FC_ANTIALIAS"antialias", 0, &v) == FcResultNoMatch)
467 {
468 FcPatternAddBool (pattern, FC_ANTIALIAS"antialias",
469 XftDefaultGetBool (dpy, FC_ANTIALIAS"antialias", screen,
470 True1));
471 }
472 if (FcPatternGet (pattern, FC_EMBOLDEN"embolden", 0, &v) == FcResultNoMatch)
473 {
474 FcPatternAddBool (pattern, FC_EMBOLDEN"embolden",
475 XftDefaultGetBool (dpy, FC_EMBOLDEN"embolden", screen,
476 False0));
477 }
478 if (FcPatternGet (pattern, FC_HINTING"hinting", 0, &v) == FcResultNoMatch)
479 {
480 FcPatternAddBool (pattern, FC_HINTING"hinting",
481 XftDefaultGetBool (dpy, FC_HINTING"hinting", screen,
482 True1));
483 }
484 if (FcPatternGet (pattern, FC_HINT_STYLE"hintstyle", 0, &v) == FcResultNoMatch)
485 {
486 FcPatternAddInteger (pattern, FC_HINT_STYLE"hintstyle",
487 XftDefaultGetInteger (dpy, FC_HINT_STYLE"hintstyle", screen,
488 FC_HINT_FULL3));
489 }
490 if (FcPatternGet (pattern, FC_AUTOHINT"autohint", 0, &v) == FcResultNoMatch)
491 {
492 FcPatternAddBool (pattern, FC_AUTOHINT"autohint",
493 XftDefaultGetBool (dpy, FC_AUTOHINT"autohint", screen,
494 False0));
495 }
496 if (FcPatternGet (pattern, FC_RGBA"rgba", 0, &v) == FcResultNoMatch)
497 {
498 int subpixel = FC_RGBA_UNKNOWN0;
499#if RENDER_MAJOR0 > 0 || RENDER_MINOR11 >= 6
500 if (XftDefaultHasRender (dpy))
501 {
502 int render_order = XRenderQuerySubpixelOrder (dpy, screen);
503 switch (render_order) {
504 default:
505 case SubPixelUnknown0: subpixel = FC_RGBA_UNKNOWN0; break;
506 case SubPixelHorizontalRGB1: subpixel = FC_RGBA_RGB1; break;
507 case SubPixelHorizontalBGR2: subpixel = FC_RGBA_BGR2; break;
508 case SubPixelVerticalRGB3: subpixel = FC_RGBA_VRGB3; break;
509 case SubPixelVerticalBGR4: subpixel = FC_RGBA_VBGR4; break;
510 case SubPixelNone5: subpixel = FC_RGBA_NONE5; break;
511 }
512 }
513#endif
514 FcPatternAddInteger (pattern, FC_RGBA"rgba",
515 XftDefaultGetInteger (dpy, FC_RGBA"rgba", screen,
516 subpixel));
517 }
518 if (FcPatternGet (pattern, FC_LCD_FILTER"lcdfilter", 0, &v) == FcResultNoMatch)
519 {
520 FcPatternAddInteger (pattern, FC_LCD_FILTER"lcdfilter",
521 XftDefaultGetInteger (dpy, FC_LCD_FILTER"lcdfilter", screen,
522 FC_LCD_DEFAULT1));
523 }
524 if (FcPatternGet (pattern, FC_MINSPACE"minspace", 0, &v) == FcResultNoMatch)
525 {
526 FcPatternAddBool (pattern, FC_MINSPACE"minspace",
527 XftDefaultGetBool (dpy, FC_MINSPACE"minspace", screen,
528 False0));
529 }
530 if (FcPatternGet (pattern, FC_DPI"dpi", 0, &v) == FcResultNoMatch)
531 {
532 dpi = (((double) DisplayHeight (dpy, screen)((&((_XPrivDisplay)dpy)->screens[screen])->height) * 25.4) /
533 (double) DisplayHeightMM (dpy, screen)((&((_XPrivDisplay)dpy)->screens[screen])->mheight));
534 FcPatternAddDouble (pattern, FC_DPI"dpi",
535 XftDefaultGetDouble (dpy, FC_DPI"dpi", screen,
536 dpi));
537 }
538 if (FcPatternGet (pattern, FC_SCALE"scale", 0, &v) == FcResultNoMatch)
539 {
540 FcPatternAddDouble (pattern, FC_SCALE"scale",
541 XftDefaultGetDouble (dpy, FC_SCALE"scale", screen, 1.0));
542 }
543 if (FcPatternGet (pattern, XFT_MAX_GLYPH_MEMORY"maxglyphmemory", 0, &v) == FcResultNoMatch)
544 {
545 FcPatternAddInteger (pattern, XFT_MAX_GLYPH_MEMORY"maxglyphmemory",
546 XftDefaultGetInteger (dpy, XFT_MAX_GLYPH_MEMORY"maxglyphmemory",
547 screen,
548 XFT_FONT_MAX_GLYPH_MEMORY(1024 * 1024)));
549 }
550 FcDefaultSubstitute (pattern);
551}
552