Bug Summary

File:fontfile/fontdir.c
Location:line 156, column 2
Description:Null pointer argument in call to string copy function

Annotated Source Code

1/*
2
3Copyright 1991, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27/*
28 * Author: Keith Packard, MIT X Consortium
29 */
30
31#ifdef HAVE_CONFIG_H1
32#include <config.h>
33#endif
34#include <X11/fonts/fntfilst.h>
35#include <X11/keysym.h>
36
37#if HAVE_STDINT_H1
38#include <stdint.h>
39#elif !defined(INT32_MAX2147483647)
40#define INT32_MAX2147483647 0x7fffffff
41#endif
42
43Bool
44FontFileInitTable (FontTablePtr table, int size)
45{
46 if (size < 0 || (size > INT32_MAX2147483647/sizeof(FontEntryRec)))
47 return FALSE0;
48 if (size)
49 {
50 table->entries = malloc(sizeof(FontEntryRec) * size);
51 if (!table->entries)
52 return FALSE0;
53 }
54 else
55 table->entries = 0;
56 table->used = 0;
57 table->size = size;
58 table->sorted = FALSE0;
59 return TRUE1;
60}
61
62void
63FontFileFreeEntry (FontEntryPtr entry)
64{
65 FontScalableExtraPtr extra;
66 int i;
67
68 if (entry->name.name)
69 free(entry->name.name);
70 entry->name.name = NULL((void *)0);
71
72 switch (entry->type)
73 {
74 case FONT_ENTRY_SCALABLE0:
75 free (entry->u.scalable.fileName);
76 extra = entry->u.scalable.extra;
77 for (i = 0; i < extra->numScaled; i++)
78 if (extra->scaled[i].vals.ranges)
79 free (extra->scaled[i].vals.ranges);
80 free (extra->scaled);
81 free (extra);
82 break;
83 case FONT_ENTRY_BITMAP2:
84 free (entry->u.bitmap.fileName);
85 entry->u.bitmap.fileName = NULL((void *)0);
86 break;
87 case FONT_ENTRY_ALIAS3:
88 free (entry->u.alias.resolved);
89 entry->u.alias.resolved = NULL((void *)0);
90 break;
91 }
92}
93
94void
95FontFileFreeTable (FontTablePtr table)
96{
97 int i;
98
99 for (i = 0; i < table->used; i++)
100 FontFileFreeEntry (&table->entries[i]);
101 free (table->entries);
102}
103
104FontDirectoryPtr
105FontFileMakeDir(const char *dirName, int size)
106{
107 FontDirectoryPtr dir;
108 int dirlen;
109 int needslash = 0;
110 const char *attrib;
111 int attriblen;
112
113#if !defined(WIN32)
114 attrib = strchr(dirName, ':');
1
Value assigned to 'attrib'
115#else
116 /* OS/2 uses the colon in the drive letter descriptor, skip this */
117 attrib = strchr(dirName+2, ':');
118#endif
119 if (attrib) {
2
Assuming 'attrib' is null
3
Taking false branch
120 dirlen = attrib - dirName;
121 attriblen = strlen(attrib);
122 } else {
123 dirlen = strlen(dirName);
124 attriblen = 0;
125 }
126 if (dirName[dirlen - 1] != '/')
4
Taking false branch
127#ifdef NCD
128 if (dirlen) /* leave out slash for builtins */
129#endif
130 needslash = 1;
131 dir = malloc(sizeof *dir + dirlen + needslash + 1 +
132 (attriblen ? attriblen + 1 : 0));
5
'?' condition is false
133 if (!dir)
6
Assuming 'dir' is non-null
7
Taking false branch
134 return (FontDirectoryPtr)0;
135 if (!FontFileInitTable (&dir->scalable, 0))
8
Taking false branch
136 {
137 free (dir);
138 return (FontDirectoryPtr)0;
139 }
140 if (!FontFileInitTable (&dir->nonScalable, size))
9
Taking false branch
141 {
142 FontFileFreeTable (&dir->scalable);
143 free (dir);
144 return (FontDirectoryPtr)0;
145 }
146 dir->directory = (char *) (dir + 1);
147 dir->dir_mtime = 0;
148 dir->alias_mtime = 0;
149 if (attriblen)
10
Taking false branch
150 dir->attributes = dir->directory + dirlen + needslash + 1;
151 else
152 dir->attributes = NULL((void *)0);
153 strncpy(dir->directory, dirName, dirlen)__builtin___strncpy_chk (dir->directory, dirName, dirlen, __builtin_object_size
(dir->directory, 2 > 1 ? 1 : 0))
;
154 dir->directory[dirlen] = '\0';
155 if (dir->attributes)
11
Taking true branch
156 strcpy(dir->attributes, attrib)__builtin___strcpy_chk (dir->attributes, attrib, __builtin_object_size
(dir->attributes, 2 > 1 ? 1 : 0))
;
12
Within the expansion of the macro 'strcpy':
a
Null pointer argument in call to string copy function
157 if (needslash)
158 strcat(dir->directory, "/")__builtin___strcat_chk (dir->directory, "/", __builtin_object_size
(dir->directory, 2 > 1 ? 1 : 0))
;
159 return dir;
160}
161
162void
163FontFileFreeDir (FontDirectoryPtr dir)
164{
165 FontFileFreeTable (&dir->scalable);
166 FontFileFreeTable (&dir->nonScalable);
167 free(dir);
168}
169
170FontEntryPtr
171FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype)
172{
173 FontEntryPtr entry;
174 int newsize;
175
176 /* can't add entries to a sorted table, pointers get broken! */
177 if (table->sorted)
178 return (FontEntryPtr) 0; /* "cannot" happen */
179 if (table->used == table->size) {
180 if (table->size >= ((INT32_MAX2147483647 / sizeof(FontEntryRec)) - 100))
181 /* If we've read so many entries we're going to ask for 2gb
182 or more of memory, something is so wrong with this font
183 directory that we should just give up before we overflow. */
184 return NULL((void *)0);
185 newsize = table->size + 100;
186 entry = realloc(table->entries, newsize * sizeof(FontEntryRec));
187 if (!entry)
188 return (FontEntryPtr)0;
189 table->size = newsize;
190 table->entries = entry;
191 }
192 entry = &table->entries[table->used];
193 *entry = *prototype;
194 entry->name.name = malloc(prototype->name.length + 1);
195 if (!entry->name.name)
196 return (FontEntryPtr)0;
197 memcpy (entry->name.name, prototype->name.name, prototype->name.length)__builtin___memcpy_chk (entry->name.name, prototype->name
.name, prototype->name.length, __builtin_object_size (entry
->name.name, 0))
;
198 entry->name.name[entry->name.length] = '\0';
199 table->used++;
200 return entry;
201}
202
203/*
204 * Compare two strings just like strcmp, but preserve decimal integer
205 * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" <
206 * "iso10646-1". Strings are sorted as if sequences of digits were
207 * prefixed by a length indicator (i.e., does not ignore leading zeroes).
208 *
209 * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
210 */
211#define Xisdigit(c)('\060' <= (c) && (c) <= '\071') ('\060' <= (c) && (c) <= '\071')
212
213static int strcmpn(const char *s1, const char *s2)
214{
215 int digits, predigits = 0;
216 const char *ss1, *ss2;
217
218 while (1) {
219 if (*s1 == 0 && *s2 == 0)
220 return 0;
221 digits = Xisdigit(*s1)('\060' <= (*s1) && (*s1) <= '\071') && Xisdigit(*s2)('\060' <= (*s2) && (*s2) <= '\071');
222 if (digits && !predigits) {
223 ss1 = s1;
224 ss2 = s2;
225 while (Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071'))
226 ss1++, ss2++;
227 if (!Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071'))
228 return -1;
229 if (Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && !Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071'))
230 return 1;
231 }
232 if ((unsigned char)*s1 < (unsigned char)*s2)
233 return -1;
234 if ((unsigned char)*s1 > (unsigned char)*s2)
235 return 1;
236 predigits = digits;
237 s1++, s2++;
238 }
239}
240
241
242static int
243FontFileNameCompare(const void* a, const void* b)
244{
245 FontEntryPtr a_name = (FontEntryPtr) a,
246 b_name = (FontEntryPtr) b;
247
248 return strcmpn(a_name->name.name, b_name->name.name);
249}
250
251void
252FontFileSortTable (FontTablePtr table)
253{
254 if (!table->sorted) {
255 qsort((char *) table->entries, table->used, sizeof(FontEntryRec),
256 FontFileNameCompare);
257 table->sorted = TRUE1;
258 }
259}
260
261void
262FontFileSortDir(FontDirectoryPtr dir)
263{
264 FontFileSortTable (&dir->scalable);
265 FontFileSortTable (&dir->nonScalable);
266 /* now that the table is fixed in size, swizzle the pointers */
267 FontFileSwitchStringsToBitmapPointers (dir);
268}
269
270/*
271 Given a Font Table, SetupWildMatch() sets up various pointers and state
272 information so the table can be searched for name(s) that match a given
273 fontname pattern -- which may contain wildcards. Under certain
274 circumstances, SetupWildMatch() will find the one table entry that
275 matches the pattern. If those circumstances do not pertain,
276 SetupWildMatch() returns a range within the the table that should be
277 searched for matching name(s). With the information established by
278 SetupWildMatch(), including state information in "private", the
279 PatternMatch() procedure is then used to test names in the range for a
280 match.
281*/
282
283#define isWild(c)((c) == 0x002a || (c) == 0x003f) ((c) == XK_asterisk0x002a || (c) == XK_question0x003f)
284#define isDigit(c)(0x0030 <= (c) && (c) <= 0x0039) (XK_00x0030 <= (c) && (c) <= XK_90x0039)
285
286static int
287SetupWildMatch(FontTablePtr table, FontNamePtr pat,
288 int *leftp, int *rightp, int *privatep)
289{
290 int nDashes;
291 char c;
292 char *t;
293 char *firstWild;
294 char *firstDigit;
295 int first;
296 int center,
297 left,
298 right;
299 int result;
300 char *name;
301
302 name = pat->name;
303 nDashes = pat->ndashes;
304 firstWild = 0;
305 firstDigit = 0;
306 t = name;
307 while ((c = *t++)) {
308 if (isWild(c)((c) == 0x002a || (c) == 0x003f)) {
309 if (!firstWild)
310 firstWild = t - 1;
311 }
312 if (isDigit(c)(0x0030 <= (c) && (c) <= 0x0039)) {
313 if (!firstDigit)
314 firstDigit = t - 1;
315 }
316 }
317 left = 0;
318 right = table->used;
319 if (firstWild)
320 *privatep = nDashes;
321 else
322 *privatep = -1;
323 if (!table->sorted) {
324 *leftp = left;
325 *rightp = right;
326 return -1;
327 } else if (firstWild) {
328 if (firstDigit && firstDigit < firstWild)
329 first = firstDigit - name;
330 else
331 first = firstWild - name;
332 while (left < right) {
333 center = (left + right) / 2;
334 result = strncmp(name, table->entries[center].name.name, first);
335 if (result == 0)
336 break;
337 if (result < 0)
338 right = center;
339 else
340 left = center + 1;
341 }
342 *leftp = left;
343 *rightp = right;
344 return -1;
345 } else {
346 while (left < right) {
347 center = (left + right) / 2;
348 result = strcmpn(name, table->entries[center].name.name);
349 if (result == 0)
350 return center;
351 if (result < 0)
352 right = center;
353 else
354 left = center + 1;
355 }
356 *leftp = 1;
357 *rightp = 0;
358 return -1;
359 }
360}
361
362static int
363PatternMatch(char *pat, int patdashes, char *string, int stringdashes)
364{
365 char c,
366 t;
367
368 if (stringdashes < patdashes)
369 return 0;
370 for (;;) {
371 switch (c = *pat++) {
372 case '*':
373 if (!(c = *pat++))
374 return 1;
375 if (c == XK_minus0x002d) {
376 patdashes--;
377 for (;;) {
378 while ((t = *string++) != XK_minus0x002d)
379 if (!t)
380 return 0;
381 stringdashes--;
382 if (PatternMatch(pat, patdashes, string, stringdashes))
383 return 1;
384 if (stringdashes == patdashes)
385 return 0;
386 }
387 } else {
388 for (;;) {
389 while ((t = *string++) != c) {
390 if (!t)
391 return 0;
392 if (t == XK_minus0x002d) {
393 if (stringdashes-- < patdashes)
394 return 0;
395 }
396 }
397 if (PatternMatch(pat, patdashes, string, stringdashes))
398 return 1;
399 }
400 }
401 case '?':
402 if (*string++ == XK_minus0x002d)
403 stringdashes--;
404 break;
405 case '\0':
406 return (*string == '\0');
407 case XK_minus0x002d:
408 if (*string++ == XK_minus0x002d) {
409 patdashes--;
410 stringdashes--;
411 break;
412 }
413 return 0;
414 default:
415 if (c == *string++)
416 break;
417 return 0;
418 }
419 }
420}
421
422int
423FontFileCountDashes (char *name, int namelen)
424{
425 int ndashes = 0;
426
427 while (namelen--)
428 if (*name++ == '\055') /* avoid non ascii systems */
429 ++ndashes;
430 return ndashes;
431}
432
433/* exported in public API in <X11/fonts/fntfil.h> */
434char *
435FontFileSaveString (char *s)strdup(char *s)
436{
437 return strdup(s);
438}
439#define FontFileSaveString(s)strdup(s) strdup(s)
440
441FontEntryPtr
442FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat,
443 FontScalablePtr vals)
444{
445 int i,
446 start,
447 stop,
448 res,
449 private;
450 FontNamePtr name;
451
452 if (!table->entries)
453 return NULL((void *)0);
454 if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0)
455 return &table->entries[i];
456 for (i = start; i < stop; i++) {
457 name = &table->entries[i].name;
458 res = PatternMatch(pat->name, private, name->name, name->ndashes);
459 if (res > 0)
460 {
461 /* Check to see if enhancements requested are available */
462 if (vals)
463 {
464 int vs = vals->values_supplied;
465 int cap;
466
467 if (table->entries[i].type == FONT_ENTRY_SCALABLE0)
468 cap = table->entries[i].u.scalable.renderer->capabilities;
469 else if (table->entries[i].type == FONT_ENTRY_ALIAS3)
470 cap = ~0; /* Calling code will have to see if true */
471 else
472 cap = 0;
473 if ((((vs & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2 ||
474 (vs & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8) &&
475 !(cap & CAP_MATRIX0x1)) ||
476 ((vs & CHARSUBSET_SPECIFIED0x40) &&
477 !(cap & CAP_CHARSUBSETTING0x2)))
478 continue;
479 }
480 return &table->entries[i];
481 }
482 if (res < 0)
483 break;
484 }
485 return (FontEntryPtr)0;
486}
487
488FontEntryPtr
489FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat)
490{
491 return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0);
492}
493
494int
495FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max,
496 FontNamesPtr names, FontScalablePtr vals,
497 int alias_behavior, int *newmax)
498{
499 int i,
500 start,
501 stop,
502 res,
503 private;
504 int ret = Successful85;
505 FontEntryPtr fname;
506 FontNamePtr name;
507
508 if (max <= 0)
509 return Successful85;
510 if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) {
511 if (alias_behavior == NORMAL_ALIAS_BEHAVIOR0 ||
512 table->entries[i].type != FONT_ENTRY_ALIAS3)
513 {
514 name = &table->entries[i].name;
515 if (newmax) *newmax = max - 1;
516 return AddFontNamesName(names, name->name, name->length);
517 }
518 start = i;
519 stop = i + 1;
520 }
521 for (i = start, fname = &table->entries[start]; i < stop; i++, fname++) {
522 res = PatternMatch(pat->name, private, fname->name.name, fname->name.ndashes);
523 if (res > 0) {
524 if (vals)
525 {
526 int vs = vals->values_supplied;
527 int cap;
528
529 if (fname->type == FONT_ENTRY_SCALABLE0)
530 cap = fname->u.scalable.renderer->capabilities;
531 else if (fname->type == FONT_ENTRY_ALIAS3)
532 cap = ~0; /* Calling code will have to see if true */
533 else
534 cap = 0;
535 if ((((vs & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2 ||
536 (vs & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8) &&
537 !(cap & CAP_MATRIX0x1)) ||
538 ((vs & CHARSUBSET_SPECIFIED0x40) &&
539 !(cap & CAP_CHARSUBSETTING0x2)))
540 continue;
541 }
542
543 if ((alias_behavior & IGNORE_SCALABLE_ALIASES(1<<1)) &&
544 fname->type == FONT_ENTRY_ALIAS3)
545 {
546 FontScalableRec tmpvals;
547 if (FontParseXLFDName (fname->name.name, &tmpvals,
548 FONT_XLFD_REPLACE_NONE0) &&
549 !(tmpvals.values_supplied & SIZE_SPECIFY_MASK0xf))
550 continue;
551 }
552
553 ret = AddFontNamesName(names, fname->name.name, fname->name.length);
554 if (ret != Successful85)
555 goto bail;
556
557 /* If alias_behavior is LIST_ALIASES_AND_TARGET_NAMES, mark
558 this entry as an alias by negating its length and follow
559 it by the resolved name */
560 if ((alias_behavior & LIST_ALIASES_AND_TARGET_NAMES(1<<0)) &&
561 fname->type == FONT_ENTRY_ALIAS3)
562 {
563 names->length[names->nnames - 1] =
564 -names->length[names->nnames - 1];
565 ret = AddFontNamesName(names, fname->u.alias.resolved,
566 strlen(fname->u.alias.resolved));
567 if (ret != Successful85)
568 goto bail;
569 }
570
571 if (--max <= 0)
572 break;
573 } else if (res < 0)
574 break;
575 }
576 bail: ;
577 if (newmax) *newmax = max;
578 return ret;
579}
580
581int
582FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat,
583 int max, FontNamesPtr names)
584{
585 return FontFileFindNamesInScalableDir(table, pat, max, names,
586 (FontScalablePtr)0,
587 NORMAL_ALIAS_BEHAVIOR0, (int *)0);
588}
589
590Bool
591FontFileMatchName(char *name, int length, FontNamePtr pat)
592{
593 /* Perform a fontfile-type name match on a single name */
594 FontTableRec table;
595 FontEntryRec entries[1];
596
597 /* Dummy up a table */
598 table.used = 1;
599 table.size = 1;
600 table.sorted = TRUE1;
601 table.entries = entries;
602 entries[0].name.name = name;
603 entries[0].name.length = length;
604 entries[0].name.ndashes = FontFileCountDashes(name, length);
605
606 return FontFileFindNameInDir(&table, pat) != (FontEntryPtr)0;
607}
608
609/*
610 * Add a font file to a directory. This handles bitmap and
611 * scalable names both
612 */
613
614Bool
615FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName)
616{
617 FontEntryRec entry;
618 FontScalableRec vals, zeroVals;
619 FontRendererPtr renderer;
620 FontEntryPtr existing;
621 FontScalableExtraPtr extra;
622 FontEntryPtr bitmap = 0, scalable;
623 Bool isscale;
624 Bool scalable_xlfd;
625
626 renderer = FontFileMatchRenderer (fileName);
627 if (!renderer)
628 return FALSE0;
629 entry.name.length = strlen (fontName);
630 if (entry.name.length > MAXFONTNAMELEN1024)
631 entry.name.length = MAXFONTNAMELEN1024;
632 entry.name.name = fontName;
633 CopyISOLatin1Lowered (entry.name.name, fontName, entry.name.length);
634 entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
635 entry.name.name[entry.name.length] = '\0';
636 /*
637 * Add a bitmap name if the incoming name isn't an XLFD name, or
638 * if it isn't a scalable name (i.e. non-zero scalable fields)
639 *
640 * If name of bitmapped font contains XLFD enhancements, do not add
641 * a scalable version of the name... this can lead to confusion and
642 * ambiguity between the font name and the field enhancements.
643 */
644 isscale = entry.name.ndashes == 14 &&
645 FontParseXLFDName(entry.name.name,
646 &vals, FONT_XLFD_REPLACE_NONE0) &&
647 (vals.values_supplied & PIXELSIZE_MASK0x3) != PIXELSIZE_ARRAY0x2 &&
648 (vals.values_supplied & POINTSIZE_MASK0xc) != POINTSIZE_ARRAY0x8 &&
649 !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK0x40);
650#define UNSCALED_ATTRIB"unscaled" "unscaled"
651 scalable_xlfd = (isscale &&
652 (((vals.values_supplied & PIXELSIZE_MASK0x3) == 0) ||
653 ((vals.values_supplied & POINTSIZE_MASK0xc) == 0)));
654 /*
655 * For scalable fonts without a scalable XFLD, check if the "unscaled"
656 * attribute is present.
657 */
658 if (isscale && !scalable_xlfd &&
659 dir->attributes && dir->attributes[0] == ':') {
660 char *ptr1 = dir->attributes + 1;
661 char *ptr2;
662 int length;
663 int uslength = strlen(UNSCALED_ATTRIB"unscaled");
664
665 do {
666 ptr2 = strchr(ptr1, ':');
667 if (ptr2)
668 length = ptr2 - ptr1;
669 else
670 length = dir->attributes + strlen(dir->attributes) - ptr1;
671 if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB"unscaled", uslength))
672 isscale = FALSE0;
673 if (ptr2)
674 ptr1 = ptr2 + 1;
675 } while (ptr2);
676 }
677 if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK0xf))
678 {
679 /*
680 * If the renderer doesn't support OpenBitmap, FontFileOpenFont
681 * will still do the right thing.
682 */
683 entry.type = FONT_ENTRY_BITMAP2;
684 entry.u.bitmap.renderer = renderer;
685 entry.u.bitmap.pFont = NullFont((FontPtr) 0);
686 if (!(entry.u.bitmap.fileName = FontFileSaveString (fileName)strdup(fileName)))
687 return FALSE0;
688 if (!(bitmap = FontFileAddEntry (&dir->nonScalable, &entry)))
689 {
690 free (entry.u.bitmap.fileName);
691 return FALSE0;
692 }
693 }
694 /*
695 * Parse out scalable fields from XLFD names - a scalable name
696 * just gets inserted, a scaled name has more things to do.
697 */
698 if (isscale)
699 {
700 if (vals.values_supplied & SIZE_SPECIFY_MASK0xf)
701 {
702 bzero((char *)&zeroVals, sizeof(zeroVals))__builtin___memset_chk ((char *)&zeroVals, 0, sizeof(zeroVals
), __builtin_object_size ((char *)&zeroVals, 0))
;
703 zeroVals.x = vals.x;
704 zeroVals.y = vals.y;
705 zeroVals.values_supplied = PIXELSIZE_SCALAR0x1 | POINTSIZE_SCALAR0x4;
706 FontParseXLFDName (entry.name.name, &zeroVals,
707 FONT_XLFD_REPLACE_VALUE3);
708 entry.name.length = strlen (entry.name.name);
709 existing = FontFileFindNameInDir (&dir->scalable, &entry.name);
710 if (existing)
711 {
712 if ((vals.values_supplied & POINTSIZE_MASK0xc) ==
713 POINTSIZE_SCALAR0x4 &&
714 (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize())
715 {
716 existing->u.scalable.extra->defaults = vals;
717
718 free (existing->u.scalable.fileName);
719 if (!(existing->u.scalable.fileName = FontFileSaveString (fileName)strdup(fileName)))
720 return FALSE0;
721 }
722 if(bitmap)
723 {
724 FontFileCompleteXLFD(&vals, &vals);
725 FontFileAddScaledInstance (existing, &vals, NullFont((FontPtr) 0),
726 bitmap->name.name);
727 return TRUE1;
728 }
729 }
730 }
731 if (!(entry.u.scalable.fileName = FontFileSaveString (fileName)strdup(fileName)))
732 return FALSE0;
733 extra = malloc (sizeof (FontScalableExtraRec));
734 if (!extra)
735 {
736 free (entry.u.scalable.fileName);
737 return FALSE0;
738 }
739 bzero((char *)&extra->defaults, sizeof(extra->defaults))__builtin___memset_chk ((char *)&extra->defaults, 0, sizeof
(extra->defaults), __builtin_object_size ((char *)&extra
->defaults, 0))
;
740 if ((vals.values_supplied & POINTSIZE_MASK0xc) == POINTSIZE_SCALAR0x4 &&
741 (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize())
742 extra->defaults = vals;
743 else
744 {
745 FontResolutionPtr resolution;
746 int num;
747 int default_point_size = GetDefaultPointSize();
748
749 extra->defaults.point_matrix[0] =
750 extra->defaults.point_matrix[3] =
751 (double)default_point_size / 10.0;
752 extra->defaults.point_matrix[1] =
753 extra->defaults.point_matrix[2] = 0.0;
754 extra->defaults.values_supplied =
755 POINTSIZE_SCALAR0x4 | PIXELSIZE_UNDEFINED0;
756 extra->defaults.width = -1;
757 if (vals.x <= 0 || vals.y <= 0)
758 {
759 resolution = GetClientResolutions (&num);
760 if (resolution && num > 0)
761 {
762 extra->defaults.x = resolution->x_resolution;
763 extra->defaults.y = resolution->y_resolution;
764 }
765 else
766 {
767 extra->defaults.x = 75;
768 extra->defaults.y = 75;
769 }
770 }
771 else
772 {
773 extra->defaults.x = vals.x;
774 extra->defaults.y = vals.y;
775 }
776 FontFileCompleteXLFD (&extra->defaults, &extra->defaults);
777 }
778 extra->numScaled = 0;
779 extra->sizeScaled = 0;
780 extra->scaled = 0;
781 extra->private = 0;
782 entry.type = FONT_ENTRY_SCALABLE0;
783 entry.u.scalable.renderer = renderer;
784 entry.u.scalable.extra = extra;
785 if (!(scalable = FontFileAddEntry (&dir->scalable, &entry)))
786 {
787 free (extra);
788 free (entry.u.scalable.fileName);
789 return FALSE0;
790 }
791 if (vals.values_supplied & SIZE_SPECIFY_MASK0xf)
792 {
793 if(bitmap)
794 {
795 FontFileCompleteXLFD(&vals, &vals);
796 FontFileAddScaledInstance (scalable, &vals, NullFont((FontPtr) 0),
797 bitmap->name.name);
798 }
799 }
800 }
801 return TRUE1;
802}
803
804Bool
805FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName)
806{
807 FontEntryRec entry;
808
809 if (strcmp(aliasName,fontName) == 0) {
810 /* Don't allow an alias to point to itself and create a loop */
811 return FALSE0;
812 }
813 entry.name.length = strlen (aliasName);
814 CopyISOLatin1Lowered (aliasName, aliasName, entry.name.length);
815 entry.name.name = aliasName;
816 entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
817 entry.type = FONT_ENTRY_ALIAS3;
818 if (!(entry.u.alias.resolved = FontFileSaveString (fontName)strdup(fontName)))
819 return FALSE0;
820 if (!FontFileAddEntry (&dir->nonScalable, &entry))
821 {
822 free (entry.u.alias.resolved);
823 return FALSE0;
824 }
825 return TRUE1;
826}