Bug Summary

File:fontfile/catalogue.c
Location:line 330, column 2
Description:Value stored to 'dir' is never read

Annotated Source Code

1/*
2 * Copyright © 2007 Red Hat, Inc
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Author:
24 * Kristian Høgsberg <krh@redhat.com>
25 */
26
27#ifdef HAVE_CONFIG_H1
28#include <config.h>
29#endif
30#include <X11/fonts/fntfilst.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <dirent.h>
34#include <unistd.h>
35
36static const char CataloguePrefix[] = "catalogue:";
37
38static int CatalogueFreeFPE (FontPathElementPtr fpe);
39
40static int
41CatalogueNameCheck (char *name)
42{
43 return strncmp(name, CataloguePrefix, sizeof(CataloguePrefix) - 1) == 0;
44}
45
46typedef struct _CatalogueRec {
47 time_t mtime;
48 int fpeCount, fpeAlloc;
49 FontPathElementPtr *fpeList;
50} CatalogueRec, *CataloguePtr;
51
52static int
53CatalogueAddFPE (CataloguePtr cat, FontPathElementPtr fpe)
54{
55 FontPathElementPtr *new;
56
57 if (cat->fpeCount >= cat->fpeAlloc)
58 {
59 if (cat->fpeAlloc == 0)
60 cat->fpeAlloc = 16;
61 else
62 cat->fpeAlloc *= 2;
63
64 new = realloc(cat->fpeList, cat->fpeAlloc * sizeof(FontPathElementPtr));
65 if (new == NULL((void*)0))
66 return AllocError80;
67
68 cat->fpeList = new;
69 }
70
71 cat->fpeList[cat->fpeCount++] = fpe;
72
73 return Successful85;
74}
75
76static const char PriorityAttribute[] = "pri=";
77
78static int
79ComparePriority(const void *p1, const void *p2)
80{
81 FontDirectoryPtr dir1 = (*(FontPathElementPtr*) p1)->private;
82 FontDirectoryPtr dir2 = (*(FontPathElementPtr*) p2)->private;
83 const char *pri1 = NULL((void*)0);
84 const char *pri2 = NULL((void*)0);
85
86 if (dir1->attributes != NULL((void*)0))
87 pri1 = strstr(dir1->attributes, PriorityAttribute);
88 if (dir2->attributes != NULL((void*)0))
89 pri2 = strstr(dir2->attributes, PriorityAttribute);
90
91 if (pri1 == NULL((void*)0) && pri2 == NULL((void*)0))
92 return 0;
93 else if (pri1 == NULL((void*)0))
94 return 1;
95 else if (pri2 == NULL((void*)0))
96 return -1;
97 else
98 return
99 atoi(pri1 + strlen(PriorityAttribute)) -
100 atoi(pri2 + strlen(PriorityAttribute));
101}
102
103static void
104CatalogueUnrefFPEs (FontPathElementPtr fpe)
105{
106 CataloguePtr cat = fpe->private;
107 FontPathElementPtr subfpe;
108 int i;
109
110 for (i = 0; i < cat->fpeCount; i++)
111 {
112 subfpe = cat->fpeList[i];
113 subfpe->refcount--;
114 if (subfpe->refcount == 0)
115 {
116 FontFileFreeFPE (subfpe);
117 free(subfpe->name);
118 free(subfpe);
119 }
120 }
121
122 cat->fpeCount = 0;
123}
124
125/* Rescan catalogue directory if modified timestamp has changed or
126 * the forceScan argument says to do it anyway (like on first load). */
127static int
128CatalogueRescan (FontPathElementPtr fpe, Bool forceScan)
129{
130 CataloguePtr cat = fpe->private;
131 char link[MAXFONTFILENAMELEN1024];
132 char dest[MAXFONTFILENAMELEN1024];
133 char *attrib;
134 FontPathElementPtr subfpe;
135 struct stat statbuf;
136 const char *path;
137 DIR *dir;
138 struct dirent *entry;
139 int len;
140 int pathlen;
141
142 path = fpe->name + strlen(CataloguePrefix);
143 if (stat(path, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)((((statbuf.st_mode)) & 0170000) == (0040000)))
144 return BadFontPath86;
145
146 if ((forceScan == FALSE0) && (statbuf.st_mtimest_mtim.tv_sec <= cat->mtime))
147 return Successful85;
148
149 dir = opendir(path);
150 if (dir == NULL((void*)0))
151 {
152 free(cat);
153 return BadFontPath86;
154 }
155
156 CatalogueUnrefFPEs (fpe);
157 while (entry = readdir(dir), entry != NULL((void*)0))
158 {
159 snprintf(link, sizeof link, "%s/%s", path, entry->d_name);
160 len = readlink(link, dest, sizeof dest - 1);
161 if (len < 0)
162 continue;
163
164 dest[len] = '\0';
165
166 if (dest[0] != '/')
167 {
168 pathlen = strlen(path);
169 memmove(dest + pathlen + 1, dest, sizeof dest - pathlen - 1);
170 memcpy(dest, path, pathlen);
171 memcpy(dest + pathlen, "/", 1);
172 len += pathlen + 1;
173 }
174
175 attrib = strchr(link, ':');
176 if (attrib && len + strlen(attrib) < sizeof dest)
177 {
178 memcpy(dest + len, attrib, strlen(attrib));
179 len += strlen(attrib);
180 }
181
182 subfpe = malloc(sizeof *subfpe);
183 if (subfpe == NULL((void*)0))
184 continue;
185
186 /* The fonts returned by OpenFont will point back to the
187 * subfpe they come from. So set the type of the subfpe to
188 * what the catalogue fpe was assigned, so calls to CloseFont
189 * (which uses font->fpe->type) goes to CatalogueCloseFont. */
190 subfpe->type = fpe->type;
191 subfpe->name_length = len;
192 subfpe->name = malloc (len + 1);
193 if (subfpe == NULL((void*)0))
194 {
195 free(subfpe);
196 continue;
197 }
198
199 memcpy(subfpe->name, dest, len);
200 subfpe->name[len] = '\0';
201
202 /* The X server will manipulate the subfpe ref counts
203 * associated with the font in OpenFont and CloseFont, so we
204 * have to make sure it's valid. */
205 subfpe->refcount = 1;
206
207 if (FontFileInitFPE (subfpe) != Successful85)
208 {
209 free(subfpe->name);
210 free(subfpe);
211 continue;
212 }
213
214 if (CatalogueAddFPE(cat, subfpe) != Successful85)
215 {
216 FontFileFreeFPE (subfpe);
217 free(subfpe);
218 continue;
219 }
220 }
221
222 closedir(dir);
223
224 qsort(cat->fpeList,
225 cat->fpeCount, sizeof cat->fpeList[0], ComparePriority);
226
227 cat->mtime = statbuf.st_mtimest_mtim.tv_sec;
228
229 return Successful85;
230}
231
232static int
233CatalogueInitFPE (FontPathElementPtr fpe)
234{
235 CataloguePtr cat;
236
237 cat = malloc(sizeof *cat);
238 if (cat == NULL((void*)0))
239 return AllocError80;
240
241 fpe->private = (pointer) cat;
242 cat->fpeCount = 0;
243 cat->fpeAlloc = 0;
244 cat->fpeList = NULL((void*)0);
245 cat->mtime = 0;
246
247 return CatalogueRescan (fpe, TRUE1);
248}
249
250static int
251CatalogueResetFPE (FontPathElementPtr fpe)
252{
253 /* Always just tell the caller to close and re-open */
254 return FPEResetFailed89;
255}
256
257static int
258CatalogueFreeFPE (FontPathElementPtr fpe)
259{
260 CataloguePtr cat = fpe->private;
261
262 /* If the catalogue is modified while the xserver has fonts open
263 * from the previous subfpes, we'll unref the old subfpes when we
264 * reload the catalogue, and the xserver will the call FreeFPE on
265 * them once it drops its last reference. Thus, the FreeFPE call
266 * for the subfpe ends up here and we just forward it to
267 * FontFileFreeFPE. */
268
269 if (!CatalogueNameCheck (fpe->name))
270 return FontFileFreeFPE (fpe);
271
272 CatalogueUnrefFPEs (fpe);
273 free(cat->fpeList);
274 free(cat);
275
276 return Successful85;
277}
278
279static int
280CatalogueOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
281 char *name, int namelen,
282 fsBitmapFormat format, fsBitmapFormatMask fmask,
283 XID id, FontPtr *pFont, char **aliasName,
284 FontPtr non_cachable_font)
285{
286 CataloguePtr cat = fpe->private;
287 FontPathElementPtr subfpe;
288 FontDirectoryPtr dir;
289 int i, status;
290
291 CatalogueRescan (fpe, FALSE0);
292
293 for (i = 0; i < cat->fpeCount; i++)
294 {
295 subfpe = cat->fpeList[i];
296 dir = subfpe->private;
297 status = FontFileOpenFont(client, subfpe, flags,
298 name, namelen, format, fmask, id,
299 pFont, aliasName, non_cachable_font);
300 if (status == Successful85 || status == FontNameAlias82)
301 return status;
302 }
303
304 return BadFontName83;
305}
306
307static void
308CatalogueCloseFont (FontPathElementPtr fpe, FontPtr pFont)
309{
310 /* Note: this gets called with the actual subfpe where we found
311 * the font, not the catalogue fpe. */
312
313 FontFileCloseFont(fpe, pFont);
314}
315
316static int
317CatalogueListFonts (pointer client, FontPathElementPtr fpe, char *pat,
318 int len, int max, FontNamesPtr names)
319{
320 CataloguePtr cat = fpe->private;
321 FontPathElementPtr subfpe;
322 FontDirectoryPtr dir;
323 int i;
324
325 CatalogueRescan (fpe, FALSE0);
326
327 for (i = 0; i < cat->fpeCount; i++)
328 {
329 subfpe = cat->fpeList[i];
330 dir = subfpe->private;
Value stored to 'dir' is never read
331 FontFileListFonts(client, subfpe, pat, len, max, names);
332 }
333
334 return Successful85;
335}
336
337int
338FontFileStartListFonts(pointer client, FontPathElementPtr fpe,
339 char *pat, int len, int max,
340 pointer *privatep, int mark_aliases);
341
342typedef struct _LFWIData {
343 pointer *privates;
344 int current;
345} LFWIDataRec, *LFWIDataPtr;
346
347static int
348CatalogueStartListFonts(pointer client, FontPathElementPtr fpe,
349 char *pat, int len, int max, pointer *privatep,
350 int mark_aliases)
351{
352 CataloguePtr cat = fpe->private;
353 LFWIDataPtr data;
354 int ret, i, j;
355
356 CatalogueRescan (fpe, FALSE0);
357
358 data = malloc (sizeof *data + sizeof data->privates[0] * cat->fpeCount);
359 if (!data)
360 return AllocError80;
361 data->privates = (pointer *) (data + 1);
362
363 for (i = 0; i < cat->fpeCount; i++)
364 {
365 ret = FontFileStartListFonts(client, cat->fpeList[i], pat, len,
366 max, &data->privates[i], mark_aliases);
367 if (ret != Successful85)
368 goto bail;
369 }
370
371 data->current = 0;
372 *privatep = (pointer) data;
373 return Successful85;
374
375 bail:
376 for (j = 0; j < i; j++)
377 /* FIXME: we have no way to free the per-fpe privates. */;
378 free (data);
379
380 return AllocError80;
381}
382
383static int
384CatalogueStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
385 char *pat, int len, int max,
386 pointer *privatep)
387{
388 return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 0);
389}
390
391static int
392CatalogueListNextFontWithInfo(pointer client, FontPathElementPtr fpe,
393 char **namep, int *namelenp,
394 FontInfoPtr *pFontInfo,
395 int *numFonts, pointer private)
396{
397 LFWIDataPtr data = private;
398 CataloguePtr cat = fpe->private;
399 int ret;
400
401 if (data->current == cat->fpeCount)
402 {
403 free(data);
404 return BadFontName83;
405 }
406
407 ret = FontFileListNextFontWithInfo(client, cat->fpeList[data->current],
408 namep, namelenp,
409 pFontInfo, numFonts,
410 data->privates[data->current]);
411 if (ret == BadFontName83)
412 {
413 data->current++;
414 return CatalogueListNextFontWithInfo(client, fpe, namep, namelenp,
415 pFontInfo, numFonts, private);
416 }
417
418 return ret;
419}
420
421static int
422CatalogueStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
423 char *pat, int len, int max,
424 pointer *privatep)
425{
426 return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 1);
427}
428
429static int
430CatalogueListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
431 char **namep, int *namelenp, char **resolvedp,
432 int *resolvedlenp, pointer private)
433{
434 LFWIDataPtr data = private;
435 CataloguePtr cat = fpe->private;
436 int ret;
437
438 if (data->current == cat->fpeCount)
439 {
440 free(data);
441 return BadFontName83;
442 }
443
444 ret = FontFileListNextFontOrAlias(client, cat->fpeList[data->current],
445 namep, namelenp,
446 resolvedp, resolvedlenp,
447 data->privates[data->current]);
448 if (ret == BadFontName83)
449 {
450 data->current++;
451 return CatalogueListNextFontOrAlias(client, fpe, namep, namelenp,
452 resolvedp, resolvedlenp, private);
453 }
454
455 return ret;
456}
457
458void
459CatalogueRegisterLocalFpeFunctions (void)
460{
461 RegisterFPEFunctions(CatalogueNameCheck,
462 CatalogueInitFPE,
463 CatalogueFreeFPE,
464 CatalogueResetFPE,
465 CatalogueOpenFont,
466 CatalogueCloseFont,
467 CatalogueListFonts,
468 CatalogueStartListFontsWithInfo,
469 CatalogueListNextFontWithInfo,
470 NULL((void*)0),
471 NULL((void*)0),
472 NULL((void*)0),
473 CatalogueStartListFontsAndAliases,
474 CatalogueListNextFontOrAlias,
475 FontFileEmptyBitmapSource);
476}