Bug Summary

File:font.c
Location:line 298, column 9
Description:Access to field 'x_name' results in a dereference of a null pointer (loaded from field 'font_map')

Annotated Source Code

1/*
2 * font.c
3 *
4 * map dvi fonts to X fonts
5 */
6
7#include <X11/Xos.h>
8#include <X11/IntrinsicP.h>
9#include <X11/StringDefs.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <ctype.h>
13#include "DviP.h"
14#include "XFontName.h"
15
16static char *
17savestr (const char *s)
18{
19 char *n;
20
21 if (!s)
22 return NULL((void*)0);
23 n = XtMalloc (strlen (s) + 1);
24 if (n)
25 strcpy (n, s)__builtin___strcpy_chk (n, s, __builtin_object_size (n, 2 >
1 ? 1 : 0))
;
26 return n;
27}
28
29static DviFontList *
30LookupFontByPosition (DviWidget dw, int position)
31{
32 DviFontList *f;
33
34 for (f = dw->dvi.fonts; f; f=f->next)
35 if (f->dvi_number == position)
36 break;
37 return f;
38}
39
40static DviFontSizeList *
41LookupFontSizeBySize (DviWidget dw, DviFontList *f, int size)
42{
43 DviFontSizeList *fs, *best = NULL((void*)0);
44 int bestdist;
45 char fontNameString[2048];
46 XFontName fontName;
47 unsigned int fontNameAttributes;
48 int dist;
49
50 if (f->scalable)
51 {
52 for (best = f->sizes; best; best = best->next)
53 if (best->size == size)
54 return best;
55 best = (DviFontSizeList *) XtMalloc (sizeof *best);
56 best->next = f->sizes;
57 best->size = size;
58 XParseFontName (f->x_name, &fontName, &fontNameAttributes);
59 fontNameAttributes &= ~(FontNamePixelSize(1<<7)|FontNameAverageWidth(1<<12));
60 fontNameAttributes |= FontNameResolutionX(1<<9);
61 fontNameAttributes |= FontNameResolutionY(1<<10);
62 fontNameAttributes |= FontNamePointSize(1<<8);
63 fontName.ResolutionX = dw->dvi.screen_resolution;
64 fontName.ResolutionY = dw->dvi.screen_resolution;
65 fontName.PointSize = size * 10 / dw->dvi.size_scale;
66 XFormatFontName (&fontName, fontNameAttributes, fontNameString);
67 best->x_name = savestr (fontNameString);
68#ifdef USE_XFT
69 /*
70 * Force a match of a core font for adobe-fontspecific
71 * encodings; we dont have a scalable font in
72 * the right encoding
73 */
74 best->core = False0;
75 if (!strcmp (fontName.CharSetRegistry, "adobe") &&
76 !strcmp (fontName.CharSetEncoding, "fontspecific"))
77 {
78 best->core = True1;
79 }
80#endif
81 best->doesnt_exist = 0;
82 best->font = NULL((void*)0);
83 f->sizes = best;
84 }
85 else
86 {
87 bestdist = 65536;
88 for (fs = f->sizes; fs; fs=fs->next) {
89 dist = size - fs->size;
90 if (dist < 0)
91 dist = -dist * 16;
92 if (dist < bestdist)
93 {
94 best = fs;
95 bestdist = dist;
96 }
97 }
98 }
99 return best;
100}
101
102static char *
103SkipFontNameElement (char *n)
104{
105 while (*n != '-')
106 if (!*++n)
107 return NULL((void*)0);
108 return n+1;
109}
110
111# define SizePosition8 8
112# define EncodingPosition13 13
113
114#ifndef USE_XFT
115static int
116ConvertFontNameToSize (char *n)
117{
118 int i, size;
119
120 for (i = 0; i < SizePosition8; i++) {
121 n = SkipFontNameElement (n);
122 if (!n)
123 return -1;
124 }
125 size = atoi (n);
126 return size/10;
127}
128#endif
129
130static char *
131ConvertFontNameToEncoding (char *n)
132{
133 int i;
134 for (i = 0; i < EncodingPosition13; i++) {
135 n = SkipFontNameElement (n);
136 if (!n)
137 return NULL((void*)0);
138 }
139 return n;
140}
141
142static void
143DisposeFontSizes (DviWidget dw, DviFontSizeList *fs)
144{
145 DviFontSizeList *next;
146
147 for (; fs; fs=next) {
148 next = fs->next;
149 if (fs->x_name)
150 XtFree (fs->x_name);
151 if (fs->font)
152 {
153#ifdef USE_XFT
154 XftFontClose (XtDisplay (dw)(((dw)->core.screen)->display), fs->font);
155#else
156 XUnloadFont (XtDisplay (dw)(((dw)->core.screen)->display), fs->font->fid);
157 XFree ((char *)fs->font);
158#endif
159 }
160 XtFree ((char *) fs);
161 }
162}
163
164void
165ResetFonts (DviWidget dw)
166{
167 DviFontList *f;
168
169 for (f = dw->dvi.fonts; f; f = f->next)
170 {
171 if (f->initialized)
172 {
173 DisposeFontSizes (dw, f->sizes);
174 f->sizes = NULL((void*)0);
175 f->initialized = FALSE0;
176 f->scalable = FALSE0;
177 }
178 }
179 /*
180 * force requery of fonts
181 */
182 dw->dvi.font = NULL((void*)0);
183 dw->dvi.font_number = -1;
184 dw->dvi.cache.font = NULL((void*)0);
185 dw->dvi.cache.font_number = -1;
186}
187
188static DviFontSizeList *
189InstallFontSizes (DviWidget dw, char *x_name, Boolean *scalablep)
190{
191#ifndef USE_XFT
192 char fontNameString[2048];
193 char **fonts;
194 int i, count;
195 int size;
196 DviFontSizeList *new;
197 XFontName fontName;
198 unsigned int fontNameAttributes;
199#endif
200 DviFontSizeList *sizes;
201
202 sizes = NULL((void*)0);
203#ifdef USE_XFT
204 *scalablep = TRUE1;
205#else
206 *scalablep = FALSE0;
207 if (!XParseFontName (x_name, &fontName, &fontNameAttributes))
208 return NULL((void*)0);
209
210 fontNameAttributes &= ~(FontNamePixelSize(1<<7)|FontNamePointSize(1<<8));
211 fontNameAttributes |= FontNameResolutionX(1<<9);
212 fontNameAttributes |= FontNameResolutionY(1<<10);
213 fontName.ResolutionX = dw->dvi.screen_resolution;
214 fontName.ResolutionY = dw->dvi.screen_resolution;
215 XFormatFontName (&fontName, fontNameAttributes, fontNameString);
216 fonts = XListFonts (XtDisplay (dw)(((dw)->core.screen)->display), fontNameString, 10000000, &count);
217 for (i = 0; i < count; i++) {
218 size = ConvertFontNameToSize (fonts[i]);
219 if (size == 0)
220 {
221 DisposeFontSizes (dw, sizes);
222 *scalablep = TRUE1;
223 sizes = NULL((void*)0);
224 break;
225 }
226 if (size != -1) {
227 new = (DviFontSizeList *) XtMalloc (sizeof *new);
228 new->next = sizes;
229 new->size = size;
230 new->x_name = savestr (fonts[i]);
231 new->doesnt_exist = 0;
232 new->font = NULL((void*)0);
233 sizes = new;
234 }
235 }
236 XFreeFontNames (fonts);
237#endif
238 return sizes;
239}
240
241static DviFontList *
242InstallFont (DviWidget dw, int position, const char *dvi_name, const char *x_name)
243{
244 DviFontList *f;
245 const char *encoding;
246
247 f = LookupFontByPosition (dw, position);
248 if (f) {
249 /*
250 * ignore gratuitous font loading
251 */
252 if (!strcmp (f->dvi_name, dvi_name) && !strcmp (f->x_name, x_name))
253 return f;
254
255 DisposeFontSizes (dw, f->sizes);
256 if (f->dvi_name)
257 XtFree (f->dvi_name);
258 if (f->x_name)
259 XtFree (f->x_name);
260 } else {
261 f = (DviFontList *) XtMalloc (sizeof (*f));
262 f->next = dw->dvi.fonts;
263 dw->dvi.fonts = f;
264 }
265 f->initialized = FALSE0;
266 f->dvi_name = savestr (dvi_name);
267 f->x_name = savestr (x_name);
268 f->dvi_number = position;
269 f->sizes = NULL((void*)0);
270 f->scalable = FALSE0;
271 if (f->x_name) {
272 encoding = ConvertFontNameToEncoding (f->x_name);
273 f->char_map = DviFindMap (encoding);
274 } else
275 f->char_map = NULL((void*)0);
276 /*
277 * force requery of fonts
278 */
279 dw->dvi.font = NULL((void*)0);
280 dw->dvi.font_number = -1;
281 dw->dvi.cache.font = NULL((void*)0);
282 dw->dvi.cache.font_number = -1;
283 return f;
284}
285
286static const char *
287MapDviNameToXName (DviWidget dw, const char *dvi_name)
288{
289 DviFontMap *fm;
290
291 for (fm = dw->dvi.font_map; fm; fm=fm->next)
2
Assuming pointer value is null
3
Loop condition is false. Execution continues on line 294
292 if (!strcmp (fm->dvi_name, dvi_name))
293 return fm->x_name;
294 ++dvi_name;
295 for (fm = dw->dvi.font_map; fm; fm=fm->next)
4
Loop condition is false. Execution continues on line 298
296 if (!strcmp (fm->dvi_name, "R"))
297 return fm->x_name;
298 if (dw->dvi.font_map->x_name)
5
Access to field 'x_name' results in a dereference of a null pointer (loaded from field 'font_map')
299 return dw->dvi.font_map->x_name;
300 return "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1";
301}
302
303
304void
305ParseFontMap (DviWidget dw)
306{
307 char dvi_name[1024];
308 char x_name[2048];
309 char *m, *s;
310 DviFontMap *fm, *new;
311
312 if (dw->dvi.font_map)
313 DestroyFontMap (dw->dvi.font_map);
314 fm = NULL((void*)0);
315 m = dw->dvi.font_map_string;
316 while (*m) {
317 s = m;
318 while (*m && !isspace (*m))
319 ++m;
320 strncpy (dvi_name, s, m-s)__builtin___strncpy_chk (dvi_name, s, m-s, __builtin_object_size
(dvi_name, 2 > 1 ? 1 : 0))
;
321 dvi_name[m-s] = '\0';
322 while (isspace (*m))
323 ++m;
324 s = m;
325 while (*m && *m != '\n')
326 ++m;
327 strncpy (x_name, s, m-s)__builtin___strncpy_chk (x_name, s, m-s, __builtin_object_size
(x_name, 2 > 1 ? 1 : 0))
;
328 x_name[m-s] = '\0';
329 new = (DviFontMap *) XtMalloc (sizeof *new);
330 new->x_name = savestr (x_name);
331 new->dvi_name = savestr (dvi_name);
332 new->next = fm;
333 fm = new;
334 ++m;
335 }
336 dw->dvi.font_map = fm;
337}
338
339void
340DestroyFontMap (DviFontMap *font_map)
341{
342 DviFontMap *next;
343
344 for (; font_map; font_map = next) {
345 next = font_map->next;
346 if (font_map->x_name)
347 XtFree (font_map->x_name);
348 if (font_map->dvi_name)
349 XtFree (font_map->dvi_name);
350 XtFree ((char *) font_map);
351 }
352}
353
354/*ARGSUSED*/
355void
356SetFontPosition (DviWidget dw, int position, const char *dvi_name, const char *extra)
357{
358 const char *x_name;
359
360 x_name = MapDviNameToXName (dw, dvi_name);
1
Calling 'MapDviNameToXName'
361 (void) InstallFont (dw, position, dvi_name, x_name);
362}
363
364#ifdef USE_XFT
365XftFont *
366#else
367XFontStruct *
368#endif
369QueryFont (DviWidget dw, int position, int size)
370{
371 DviFontList *f;
372 DviFontSizeList *fs;
373
374 f = LookupFontByPosition (dw, position);
375 if (!f)
376 return dw->dvi.default_font;
377 if (!f->initialized) {
378 f->sizes = InstallFontSizes (dw, f->x_name, &f->scalable);
379 f->initialized = TRUE1;
380 }
381 fs = LookupFontSizeBySize (dw, f, size);
382 if (!fs)
383 return dw->dvi.default_font;
384 if (!fs->font) {
385 if (fs->x_name)
386 {
387#ifdef USE_XFT
388 XftPattern *pat;
389 XftPattern *match;
390 XftResult result;
391
392 pat = XftXlfdParse (fs->x_name, False0, False0);
393 XftPatternAddBool (pat, XFT_CORE, fs->core);
394 match = XftFontMatch (XtDisplay (dw)(((dw)->core.screen)->display),
395 XScreenNumberOfScreen(dw->core.screen),
396 pat, &result);
397 XftPatternDestroy (pat);
398 if (match)
399 {
400 fs->font = XftFontOpenPattern (XtDisplay (dw)(((dw)->core.screen)->display),
401 match);
402 if (!fs->font)
403 XftPatternDestroy (match);
404 }
405 else
406 fs->font = 0;
407#else
408 fs->font = XLoadQueryFont (XtDisplay (dw)(((dw)->core.screen)->display), fs->x_name);
409#endif
410 }
411 if (!fs->font)
412 fs->font = dw->dvi.default_font;
413 }
414 return fs->font;
415}
416
417DviCharNameMap *
418QueryFontMap (DviWidget dw, int position)
419{
420 DviFontList *f;
421
422 f = LookupFontByPosition (dw, position);
423 if (f)
424 return f->char_map;
425 else
426 return NULL((void*)0);
427}
428
429unsigned char *
430DviCharIsLigature (DviCharNameMap *map, const char *name)
431{
432 int i;
433
434 for (i = 0; i < DVI_MAX_LIGATURES16; i++) {
435 if (!map->ligatures[i][0])
436 break;
437 if (!strcmp (name, map->ligatures[i][0]))
438 return (unsigned char *) map->ligatures[i][1];
439 }
440 return NULL((void*)0);
441}