Bug Summary

File:bitmap/bdfread.c
Location:line 158, column 23
Description:Array access (from variable 'picture') results in a null pointer dereference

Annotated Source Code

1/************************************************************************
2Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3
4 All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Digital not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22************************************************************************/
23
24/*
25
26Copyright 1994, 1998 The Open Group
27
28Permission to use, copy, modify, distribute, and sell this software and its
29documentation for any purpose is hereby granted without fee, provided that
30the above copyright notice appear in all copies and that both that
31copyright notice and this permission notice appear in supporting
32documentation.
33
34The above copyright notice and this permission notice shall be included
35in all copies or substantial portions of the Software.
36
37THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
40IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
41OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
42ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43OTHER DEALINGS IN THE SOFTWARE.
44
45Except as contained in this notice, the name of The Open Group shall
46not be used in advertising or otherwise to promote the sale, use or
47other dealings in this Software without prior written authorization
48from The Open Group.
49
50*/
51
52#ifdef HAVE_CONFIG_H1
53#include <config.h>
54#endif
55#include "libxfontint.h"
56
57#include <ctype.h>
58#include <X11/fonts/fntfilst.h>
59#include <X11/fonts/fontutil.h>
60/* use bitmap structure */
61#include <X11/fonts/bitmap.h>
62#include <X11/fonts/bdfint.h>
63
64#if HAVE_STDINT_H1
65#include <stdint.h>
66#else
67# ifndef INT32_MAX2147483647
68# define INT32_MAX2147483647 0x7fffffff
69# endif
70# ifndef INT16_MAX32767
71# define INT16_MAX32767 0x7fff
72# endif
73# ifndef INT16_MIN-32768
74# define INT16_MIN-32768 (0 - 0x8000)
75# endif
76#endif
77
78#define INDICES256 256
79#define MAXENCODING0xFFFF 0xFFFF
80#define BDFLINELEN1024 1024
81#define BDFLINESTR"%1023s" "%1023s" /* scanf specifier to read a BDFLINELEN string */
82
83static Bool bdfPadToTerminal(FontPtr pFont);
84extern int bdfFileLineNum;
85
86/***====================================================================***/
87
88static Bool
89bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
90 int glyph, int scan, CARD32 *sizes)
91{
92 int widthBits,
93 widthBytes,
94 widthHexChars;
95 int height,
96 row;
97 int i,
98 inLineLen,
99 nextByte;
100 unsigned char *pInBits,
101 *picture,
102 *line = NULL((void *)0);
103 unsigned char lineBuf[BDFLINELEN1024];
104
105 widthBits = GLYPHWIDTHPIXELS(pCI)((pCI)->metrics.rightSideBearing - (pCI)->metrics.leftSideBearing
)
;
106 height = GLYPHHEIGHTPIXELS(pCI)((pCI)->metrics.ascent + (pCI)->metrics.descent);
107
108 widthBytes = BYTES_PER_ROW(widthBits, glyph)((glyph) == 1 ? (((widthBits)+7)>>3) :(glyph) == 2 ? ((
((widthBits)+15)>>3)&~1) :(glyph) == 4 ? ((((widthBits
)+31)>>3)&~3) :(glyph) == 8 ? ((((widthBits)+63)>>
3)&~7) : 0)
;
109 if (widthBytes * height > 0) {
1
Taking false branch
110 picture = malloc(widthBytes * height);
111 if (!picture) {
112 bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);
113 goto BAILOUT;
114 }
115 } else
116 picture = NULL((void *)0);
2
Null pointer value stored to 'picture'
117 pCI->bits = (char *) picture;
118
119 if (sizes) {
3
Assuming 'sizes' is null
4
Taking false branch
120 for (i = 0; i < GLYPHPADOPTIONS4; i++)
121 sizes[i] += BYTES_PER_ROW(widthBits, (1 << i))(((1 << i)) == 1 ? (((widthBits)+7)>>3) :((1 <<
i)) == 2 ? ((((widthBits)+15)>>3)&~1) :((1 <<
i)) == 4 ? ((((widthBits)+31)>>3)&~3) :((1 <<
i)) == 8 ? ((((widthBits)+63)>>3)&~7) : 0)
* height;
122 }
123 nextByte = 0;
124 widthHexChars = BYTES_PER_ROW(widthBits, 1)((1) == 1 ? (((widthBits)+7)>>3) :(1) == 2 ? ((((widthBits
)+15)>>3)&~1) :(1) == 4 ? ((((widthBits)+31)>>
3)&~3) :(1) == 8 ? ((((widthBits)+63)>>3)&~7) :
0)
;
125
126/* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */
127/* 0 width characters? */
128
129 for (row = 0; row < height; row++) {
5
Assuming 'row' is < 'height'
6
Loop condition is true. Entering loop body
130 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
131 if (!line)
7
Assuming 'line' is non-null
8
Taking false branch
132 break;
133
134 if (widthBits == 0) {
9
Assuming 'widthBits' is not equal to 0
10
Taking false branch
135 if ((!line) || (bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR")))))
136 break;
137 else
138 continue;
139 }
140 pInBits = line;
141 inLineLen = strlen((char *) pInBits);
142
143 if (inLineLen & 1) {
11
Taking false branch
144 bdfError("odd number of characters in hex encoding\n");
145 line[inLineLen++] = '0';
146 line[inLineLen] = '\0';
147 }
148 inLineLen >>= 1;
149 i = inLineLen;
150 if (i > widthHexChars)
12
Taking false branch
151 i = widthHexChars;
152 for (; i > 0; i--, pInBits += 2)
13
Assuming 'i' is <= 0
14
Loop condition is false. Execution continues on line 156
153 picture[nextByte++] = bdfHexByte(pInBits);
154
155 /* pad if line is too short */
156 if (inLineLen < widthHexChars) {
15
Taking true branch
157 for (i = widthHexChars - inLineLen; i > 0; i--)
16
Assuming 'i' is > 0
17
Loop condition is true. Entering loop body
158 picture[nextByte++] = 0;
18
Array access (from variable 'picture') results in a null pointer dereference
159 } else {
160 unsigned char mask;
161
162 mask = 0xff << (8 - (widthBits & 0x7));
163 if (mask && picture[nextByte - 1] & ~mask) {
164 picture[nextByte - 1] &= mask;
165 }
166 }
167
168 if (widthBytes > widthHexChars) {
169 i = widthBytes - widthHexChars;
170 while (i-- > 0)
171 picture[nextByte++] = 0;
172 }
173 }
174
175 if ((line && (!bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR"))))) || (height == 0))
176 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
177
178 if ((!line) || (!bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR"))))) {
179 bdfError("missing 'ENDCHAR'\n");
180 goto BAILOUT;
181 }
182 if (nextByte != height * widthBytes) {
183 bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
184 nextByte, height, widthBytes);
185 goto BAILOUT;
186 }
187 if (picture != NULL((void *)0)) {
188 if (bit == LSBFirst0)
189 BitOrderInvert(picture, nextByte);
190 if (bit != byte) {
191 if (scan == 2)
192 TwoByteSwap(picture, nextByte);
193 else if (scan == 4)
194 FourByteSwap(picture, nextByte);
195 }
196 }
197 return (TRUE1);
198BAILOUT:
199 if (picture)
200 free(picture);
201 pCI->bits = NULL((void *)0);
202 return (FALSE0);
203}
204
205/***====================================================================***/
206
207static Bool
208bdfSkipBitmap(FontFilePtr file, int height)
209{
210 unsigned char *line;
211 int i = 0;
212 unsigned char lineBuf[BDFLINELEN1024];
213
214 do {
215 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
216 i++;
217 } while (line && !bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR"))) && i <= height);
218
219 if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR")))) {
220 bdfError("Error in bitmap, missing 'ENDCHAR'\n");
221 return (FALSE0);
222 }
223 return (TRUE1);
224}
225
226/***====================================================================***/
227
228static void
229bdfFreeFontBits(FontPtr pFont)
230{
231 BitmapFontPtr bitmapFont;
232 BitmapExtraPtr bitmapExtra;
233 int i, nencoding;
234
235 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
236 bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
237 free(bitmapFont->ink_metrics);
238 if(bitmapFont->encoding) {
239 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
240 (pFont->info.lastRow - pFont->info.firstRow + 1);
241 for(i=0; i<NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128); i++)
242 free(bitmapFont->encoding[i]);
243 }
244 free(bitmapFont->encoding);
245 for (i = 0; i < bitmapFont->num_chars; i++)
246 free(bitmapFont->metrics[i].bits);
247 free(bitmapFont->metrics);
248 if (bitmapExtra)
249 {
250 free (bitmapExtra->glyphNames);
251 free (bitmapExtra->sWidths);
252 free (bitmapExtra);
253 }
254 free(pFont->info.props);
255 free(bitmapFont);
256}
257
258
259static Bool
260bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
261 int bit, int byte, int glyph, int scan)
262{
263 unsigned char *line;
264 register CharInfoPtr ci;
265 int i,
266 ndx,
267 nchars,
268 nignored;
269 unsigned int char_row, char_col;
270 int numEncodedGlyphs = 0;
271 CharInfoPtr *bdfEncoding[256];
272 BitmapFontPtr bitmapFont;
273 BitmapExtraPtr bitmapExtra;
274 CARD32 *bitmapsSizes;
275 unsigned char lineBuf[BDFLINELEN1024];
276 int nencoding;
277
278 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
279 bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
280
281 if (bitmapExtra) {
282 bitmapsSizes = bitmapExtra->bitmapsSizes;
283 for (i = 0; i < GLYPHPADOPTIONS4; i++)
284 bitmapsSizes[i] = 0;
285 } else
286 bitmapsSizes = NULL((void *)0);
287
288 bzero(bdfEncoding, sizeof(bdfEncoding))__builtin___memset_chk (bdfEncoding, 0, sizeof(bdfEncoding), __builtin_object_size
(bdfEncoding, 0))
;
289 bitmapFont->metrics = NULL((void *)0);
290 ndx = 0;
291
292 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
293
294 if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
295 bdfError("bad 'CHARS' in bdf file\n");
296 return (FALSE0);
297 }
298 if (nchars < 1) {
299 bdfError("invalid number of CHARS in BDF file\n");
300 return (FALSE0);
301 }
302 if (nchars > (signed) (INT32_MAX2147483647 / sizeof(CharInfoRec))) {
303 bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
304 (int) sizeof(CharInfoRec));
305 goto BAILOUT;
306 }
307 ci = calloc(nchars, sizeof(CharInfoRec));
308 if (!ci) {
309 bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
310 (int) sizeof(CharInfoRec));
311 goto BAILOUT;
312 }
313 bitmapFont->metrics = ci;
314
315 if (bitmapExtra) {
316 bitmapExtra->glyphNames = malloc(nchars * sizeof(Atom));
317 if (!bitmapExtra->glyphNames) {
318 bdfError("Couldn't allocate glyphNames (%d*%d)\n",
319 nchars, (int) sizeof(Atom));
320 goto BAILOUT;
321 }
322 }
323 if (bitmapExtra) {
324 bitmapExtra->sWidths = malloc(nchars * sizeof(int));
325 if (!bitmapExtra->sWidths) {
326 bdfError("Couldn't allocate sWidth (%d *%d)\n",
327 nchars, (int) sizeof(int));
328 return FALSE0;
329 }
330 }
331 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
332 pFont->info.firstRow = 256;
333 pFont->info.lastRow = 0;
334 pFont->info.firstCol = 256;
335 pFont->info.lastCol = 0;
336 nignored = 0;
337 for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR")(!strncmp((char *)line,"STARTCHAR",strlen("STARTCHAR"))));) {
338 int t;
339 int wx; /* x component of width */
340 int wy; /* y component of width */
341 int bw; /* bounding-box width */
342 int bh; /* bounding-box height */
343 int bl; /* bounding-box left */
344 int bb; /* bounding-box bottom */
345 int enc,
346 enc2; /* encoding */
347 unsigned char *p; /* temp pointer into line */
348 char charName[100];
349 int ignore;
350
351 if (sscanf((char *) line, "STARTCHAR %99s", charName) != 1) {
352 bdfError("bad character name in BDF file\n");
353 goto BAILOUT; /* bottom of function, free and return error */
354 }
355 if (bitmapExtra)
356 bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL((void *)0));
357
358 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
359 if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
360 bdfError("bad 'ENCODING' in BDF file\n");
361 goto BAILOUT;
362 }
363 if (enc < -1 || (t == 2 && enc2 < -1)) {
364 bdfError("bad ENCODING value");
365 goto BAILOUT;
366 }
367 if (t == 2 && enc == -1)
368 enc = enc2;
369 ignore = 0;
370 if (enc == -1) {
371 if (!bitmapExtra) {
372 nignored++;
373 ignore = 1;
374 }
375 } else if (enc > MAXENCODING0xFFFF) {
376 bdfError("char '%s' has encoding too large (%d)\n",
377 charName, enc);
378 } else {
379 char_row = (enc >> 8) & 0xFF;
380 char_col = enc & 0xFF;
381 if (char_row < pFont->info.firstRow)
382 pFont->info.firstRow = char_row;
383 if (char_row > pFont->info.lastRow)
384 pFont->info.lastRow = char_row;
385 if (char_col < pFont->info.firstCol)
386 pFont->info.firstCol = char_col;
387 if (char_col > pFont->info.lastCol)
388 pFont->info.lastCol = char_col;
389 if (bdfEncoding[char_row] == (CharInfoPtr *) NULL((void *)0)) {
390 bdfEncoding[char_row] = malloc(256 * sizeof(CharInfoPtr));
391 if (!bdfEncoding[char_row]) {
392 bdfError("Couldn't allocate row %d of encoding (%d*%d)\n",
393 char_row, INDICES256, (int) sizeof(CharInfoPtr));
394 goto BAILOUT;
395 }
396 for (i = 0; i < 256; i++)
397 bdfEncoding[char_row][i] = (CharInfoPtr) NULL((void *)0);
398 }
399 if (bdfEncoding[char_row] != NULL((void *)0)) {
400 bdfEncoding[char_row][char_col] = ci;
401 numEncodedGlyphs++;
402 }
403 }
404
405 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
406 if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
407 bdfError("bad 'SWIDTH'\n");
408 goto BAILOUT;
409 }
410 if (wy != 0) {
411 bdfError("SWIDTH y value must be zero\n");
412 goto BAILOUT;
413 }
414 if (bitmapExtra)
415 bitmapExtra->sWidths[ndx] = wx;
416
417/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
418/* from all of these. */
419
420 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
421 if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
422 bdfError("bad 'DWIDTH'\n");
423 goto BAILOUT;
424 }
425 if (wy != 0) {
426 bdfError("DWIDTH y value must be zero\n");
427 goto BAILOUT;
428 }
429 /* xCharInfo metrics are stored as INT16 */
430 if ((wx < INT16_MIN-32768) || (wx > INT16_MAX32767)) {
431 bdfError("character '%s' has out of range width, %d\n",
432 charName, wx);
433 goto BAILOUT;
434 }
435 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
436 if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
437 bdfError("bad 'BBX'\n");
438 goto BAILOUT;
439 }
440 if ((bh < 0) || (bw < 0)) {
441 bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
442 charName, bw, bh);
443 goto BAILOUT;
444 }
445 /* xCharInfo metrics are read as int, but stored as INT16 */
446 if ((bl > INT16_MAX32767) || (bl < INT16_MIN-32768) ||
447 (bb > INT16_MAX32767) || (bb < INT16_MIN-32768) ||
448 (bw > (INT16_MAX32767 - bl)) || (bh > (INT16_MAX32767 - bb))) {
449 bdfError("character '%s' has out of range metrics, %d %d %d %d\n",
450 charName, bl, (bl+bw), (bh+bb), -bb);
451 goto BAILOUT;
452 }
453 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
454 if ((line) && (bdfIsPrefix(line, "ATTRIBUTES")(!strncmp((char *)line,"ATTRIBUTES",strlen("ATTRIBUTES"))))) {
455 for (p = line + strlen("ATTRIBUTES ");
456 (*p == ' ') || (*p == '\t');
457 p++)
458 /* empty for loop */ ;
459 ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
460 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
461 } else
462 ci->metrics.attributes = 0;
463
464 if (!line || !bdfIsPrefix(line, "BITMAP")(!strncmp((char *)line,"BITMAP",strlen("BITMAP")))) {
465 bdfError("missing 'BITMAP'\n");
466 goto BAILOUT;
467 }
468 /* collect data for generated properties */
469 if ((strlen(charName) == 1)) {
470 if ((charName[0] >= '0') && (charName[0] <= '9')) {
471 pState->digitWidths += wx;
472 pState->digitCount++;
473 } else if (charName[0] == 'x') {
474 pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb;
475 }
476 }
477 if (!ignore) {
478 ci->metrics.leftSideBearing = bl;
479 ci->metrics.rightSideBearing = bl + bw;
480 ci->metrics.ascent = bh + bb;
481 ci->metrics.descent = -bb;
482 ci->metrics.characterWidth = wx;
483 ci->bits = NULL((void *)0);
484 if (!bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes)) {
485 bdfError("could not read bitmap for character '%s'\n", charName);
486 goto BAILOUT;
487 }
488 ci++;
489 ndx++;
490 } else
491 bdfSkipBitmap(file, bh);
492
493 line = bdfGetLine(file, lineBuf, BDFLINELEN1024); /* get STARTCHAR or
494 * ENDFONT */
495 }
496
497 if (ndx + nignored != nchars) {
498 bdfError("%d too few characters\n", nchars - (ndx + nignored));
499 goto BAILOUT;
500 }
501 nchars = ndx;
502 bitmapFont->num_chars = nchars;
503 if ((line) && (bdfIsPrefix(line, "STARTCHAR")(!strncmp((char *)line,"STARTCHAR",strlen("STARTCHAR"))))) {
504 bdfError("more characters than specified\n");
505 goto BAILOUT;
506 }
507 if ((!line) || (!bdfIsPrefix(line, "ENDFONT")(!strncmp((char *)line,"ENDFONT",strlen("ENDFONT"))))) {
508 bdfError("missing 'ENDFONT'\n");
509 goto BAILOUT;
510 }
511 if (numEncodedGlyphs == 0)
512 bdfWarning("No characters with valid encodings\n");
513
514 nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) *
515 (pFont->info.lastCol - pFont->info.firstCol + 1);
516 bitmapFont->encoding = calloc(NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128),sizeof(CharInfoPtr*));
517 if (!bitmapFont->encoding) {
518 bdfError("Couldn't allocate ppCI (%d,%d)\n",
519 NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128),
520 (int) sizeof(CharInfoPtr*));
521 goto BAILOUT;
522 }
523 pFont->info.allExist = TRUE1;
524 i = 0;
525 for (char_row = pFont->info.firstRow;
526 char_row <= pFont->info.lastRow;
527 char_row++) {
528 if (bdfEncoding[char_row] == (CharInfoPtr *) NULL((void *)0)) {
529 pFont->info.allExist = FALSE0;
530 i += pFont->info.lastCol - pFont->info.firstCol + 1;
531 } else {
532 for (char_col = pFont->info.firstCol;
533 char_col <= pFont->info.lastCol;
534 char_col++) {
535 if (!bdfEncoding[char_row][char_col])
536 pFont->info.allExist = FALSE0;
537 else {
538 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)]) {
539 bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)]=
540 calloc(BITMAP_FONT_SEGMENT_SIZE128,
541 sizeof(CharInfoPtr));
542 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)])
543 goto BAILOUT;
544 }
545 ACCESSENCODINGL(bitmapFont->encoding,i)(bitmapFont->encoding[(i)/128][(i)%128]) =
546 bdfEncoding[char_row][char_col];
547 }
548 i++;
549 }
550 }
551 }
552 for (i = 0; i < 256; i++)
553 if (bdfEncoding[i])
554 free(bdfEncoding[i]);
555 return (TRUE1);
556BAILOUT:
557 for (i = 0; i < 256; i++)
558 if (bdfEncoding[i])
559 free(bdfEncoding[i]);
560 /* bdfFreeFontBits will clean up the rest */
561 return (FALSE0);
562}
563
564/***====================================================================***/
565
566static Bool
567bdfReadHeader(FontFilePtr file, bdfFileState *pState)
568{
569 unsigned char *line;
570 char namebuf[BDFLINELEN1024];
571 unsigned char lineBuf[BDFLINELEN1024];
572
573 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
574 if (!line ||
575 sscanf((char *) line, "STARTFONT " BDFLINESTR"%1023s", namebuf) != 1 ||
576 !bdfStrEqual(namebuf, "2.1")(!strcmp(namebuf,"2.1"))) {
577 bdfError("bad 'STARTFONT'\n");
578 return (FALSE0);
579 }
580 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
581#if MAXFONTNAMELEN1024 != 1024
582# error "need to adjust sscanf length limit to be MAXFONTNAMELEN - 1"
583#endif
584 if (!line ||
585 sscanf((char *) line, "FONT %1023[^\n]", pState->fontName) != 1) {
586 bdfError("bad 'FONT'\n");
587 return (FALSE0);
588 }
589 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
590 if (!line || !bdfIsPrefix(line, "SIZE")(!strncmp((char *)line,"SIZE",strlen("SIZE")))) {
591 bdfError("missing 'SIZE'\n");
592 return (FALSE0);
593 }
594 if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
595 &pState->resolution_x, &pState->resolution_y) != 3) {
596 bdfError("bad 'SIZE'\n");
597 return (FALSE0);
598 }
599 if (pState->pointSize < 1 ||
600 pState->resolution_x < 1 || pState->resolution_y < 1) {
601 bdfError("SIZE values must be > 0\n");
602 return (FALSE0);
603 }
604 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
605 if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")(!strncmp((char *)line,"FONTBOUNDINGBOX",strlen("FONTBOUNDINGBOX"
)))
) {
606 bdfError("missing 'FONTBOUNDINGBOX'\n");
607 return (FALSE0);
608 }
609 return (TRUE1);
610}
611
612/***====================================================================***/
613
614static Bool
615bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
616{
617 int nProps, props_left,
618 nextProp;
619 char *stringProps;
620 FontPropPtr props;
621 char namebuf[BDFLINELEN1024],
622 secondbuf[BDFLINELEN1024],
623 thirdbuf[BDFLINELEN1024];
624 unsigned char *line;
625 unsigned char lineBuf[BDFLINELEN1024];
626 BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
627
628 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
629 if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")(!strncmp((char *)line,"STARTPROPERTIES",strlen("STARTPROPERTIES"
)))
) {
630 bdfError("missing 'STARTPROPERTIES'\n");
631 return (FALSE0);
632 }
633 if ((sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) ||
634 (nProps <= 0) ||
635 (nProps > (signed) ((INT32_MAX2147483647 / sizeof(FontPropRec)) - BDF_GENPROPS6))) {
636 bdfError("bad 'STARTPROPERTIES'\n");
637 return (FALSE0);
638 }
639 pFont->info.isStringProp = NULL((void *)0);
640 pFont->info.props = NULL((void *)0);
641 pFont->info.nprops = 0;
642
643 stringProps = malloc((nProps + BDF_GENPROPS6) * sizeof(char));
644 pFont->info.isStringProp = stringProps;
645 if (stringProps == NULL((void *)0)) {
646 bdfError("Couldn't allocate stringProps (%d*%d)\n",
647 (nProps + BDF_GENPROPS6), (int) sizeof(Bool));
648 goto BAILOUT;
649 }
650 pFont->info.props = props = calloc(nProps + BDF_GENPROPS6,
651 sizeof(FontPropRec));
652 if (props == NULL((void *)0)) {
653 bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS6,
654 (int) sizeof(FontPropRec));
655 goto BAILOUT;
656 }
657
658 nextProp = 0;
659 props_left = nProps;
660 while (props_left-- > 0) {
661 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
662 if (line == NULL((void *)0) || bdfIsPrefix(line, "ENDPROPERTIES")(!strncmp((char *)line,"ENDPROPERTIES",strlen("ENDPROPERTIES"
)))
) {
663 bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
664 nProps, nProps - props_left - 1);
665 goto BAILOUT;
666 }
667 while (*line && isspace(*line))
668 line++;
669
670 switch (sscanf((char *) line,
671 BDFLINESTR"%1023s" BDFLINESTR"%1023s" BDFLINESTR"%1023s",
672 namebuf, secondbuf, thirdbuf)) {
673 default:
674 bdfError("missing '%s' parameter value\n", namebuf);
675 goto BAILOUT;
676
677 case 2:
678 /*
679 * Possibilites include: valid quoted string with no white space
680 * valid integer value invalid value
681 */
682 if (secondbuf[0] == '"') {
683 stringProps[nextProp] = TRUE1;
684 props[nextProp].value =
685 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
686 if (!props[nextProp].value)
687 goto BAILOUT;
688 break;
689 } else if (bdfIsInteger(secondbuf)) {
690 stringProps[nextProp] = FALSE0;
691 props[nextProp].value = atoi(secondbuf);
692 break;
693 } else {
694 bdfError("invalid '%s' parameter value\n", namebuf);
695 goto BAILOUT;
696 }
697
698 case 3:
699 /*
700 * Possibilites include: valid quoted string with some white space
701 * invalid value (reject even if second string is integer)
702 */
703 if (secondbuf[0] == '"') {
704 stringProps[nextProp] = TRUE1;
705 props[nextProp].value =
706 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
707 if (!props[nextProp].value)
708 goto BAILOUT;
709 break;
710 } else {
711 bdfError("invalid '%s' parameter value\n", namebuf);
712 goto BAILOUT;
713 }
714 }
715 props[nextProp].name = bdfForceMakeAtom(namebuf, NULL((void *)0));
716 if (props[nextProp].name == None0L) {
717 bdfError("Empty property name.\n");
718 goto BAILOUT;
719 }
720 if (!bdfSpecialProperty(pFont, &props[nextProp],
721 stringProps[nextProp], pState))
722 nextProp++;
723 }
724
725 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
726 if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")(!strncmp((char *)line,"ENDPROPERTIES",strlen("ENDPROPERTIES"
)))
) {
727 bdfError("missing 'ENDPROPERTIES'\n");
728 goto BAILOUT;
729 }
730 if (!pState->haveFontAscent || !pState->haveFontDescent) {
731 bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
732 goto BAILOUT;
733 }
734 if (bitmapFont->bitmapExtra) {
735 bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
736 bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
737 }
738 if (!pState->pointSizeProp) {
739 props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL((void *)0));
740 props[nextProp].value = (INT32) (pState->pointSize * 10.0);
741 stringProps[nextProp] = FALSE0;
742 pState->pointSizeProp = &props[nextProp];
743 nextProp++;
744 }
745 if (!pState->fontProp) {
746 props[nextProp].name = bdfForceMakeAtom("FONT", NULL((void *)0));
747 props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL((void *)0));
748 stringProps[nextProp] = TRUE1;
749 pState->fontProp = &props[nextProp];
750 nextProp++;
751 }
752 if (!pState->weightProp) {
753 props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL((void *)0));
754 props[nextProp].value = -1; /* computed later */
755 stringProps[nextProp] = FALSE0;
756 pState->weightProp = &props[nextProp];
757 nextProp++;
758 }
759 if (!pState->resolutionProp &&
760 pState->resolution_x == pState->resolution_y) {
761 props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL((void *)0));
762 props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27);
763 stringProps[nextProp] = FALSE0;
764 pState->resolutionProp = &props[nextProp];
765 nextProp++;
766 }
767 if (!pState->resolutionXProp) {
768 props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL((void *)0));
769 props[nextProp].value = (INT32) pState->resolution_x;
770 stringProps[nextProp] = FALSE0;
771 pState->resolutionProp = &props[nextProp];
772 nextProp++;
773 }
774 if (!pState->resolutionYProp) {
775 props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL((void *)0));
776 props[nextProp].value = (INT32) pState->resolution_y;
777 stringProps[nextProp] = FALSE0;
778 pState->resolutionProp = &props[nextProp];
779 nextProp++;
780 }
781 if (!pState->xHeightProp) {
782 props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL((void *)0));
783 props[nextProp].value = -1; /* computed later */
784 stringProps[nextProp] = FALSE0;
785 pState->xHeightProp = &props[nextProp];
786 nextProp++;
787 }
788 if (!pState->quadWidthProp) {
789 props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL((void *)0));
790 props[nextProp].value = -1; /* computed later */
791 stringProps[nextProp] = FALSE0;
792 pState->quadWidthProp = &props[nextProp];
793 nextProp++;
794 }
795 pFont->info.nprops = nextProp;
796 return (TRUE1);
797BAILOUT:
798 if (pFont->info.isStringProp) {
799 free(pFont->info.isStringProp);
800 pFont->info.isStringProp = NULL((void *)0);
801 }
802 if (pFont->info.props) {
803 free(pFont->info.props);
804 pFont->info.props = NULL((void *)0);
805 }
806 while (line && bdfIsPrefix(line, "ENDPROPERTIES")(!strncmp((char *)line,"ENDPROPERTIES",strlen("ENDPROPERTIES"
)))
)
807 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
808 return (FALSE0);
809}
810
811/***====================================================================***/
812
813static void
814bdfUnloadFont(FontPtr pFont)
815{
816 bdfFreeFontBits (pFont);
817 DestroyFontRec(pFont);
818}
819
820int
821bdfReadFont(FontPtr pFont, FontFilePtr file,
822 int bit, int byte, int glyph, int scan)
823{
824 bdfFileState state;
825 xCharInfo *min,
826 *max;
827 BitmapFontPtr bitmapFont;
828
829 pFont->fontPrivate = 0;
830
831 bzero(&state, sizeof(bdfFileState))__builtin___memset_chk (&state, 0, sizeof(bdfFileState), __builtin_object_size
(&state, 0))
;
832 bdfFileLineNum = 0;
833
834 if (!bdfReadHeader(file, &state))
835 goto BAILOUT;
836
837 bitmapFont = calloc(1, sizeof(BitmapFontRec));
838 if (!bitmapFont) {
839 bdfError("Couldn't allocate bitmapFontRec (%d)\n",
840 (int) sizeof(BitmapFontRec));
841 goto BAILOUT;
842 }
843
844 pFont->fontPrivate = (pointer) bitmapFont;
845 bitmapFont->metrics = 0;
846 bitmapFont->ink_metrics = 0;
847 bitmapFont->bitmaps = 0;
848 bitmapFont->encoding = 0;
849 bitmapFont->pDefault = NULL((void *)0);
850
851 bitmapFont->bitmapExtra = calloc(1, sizeof(BitmapExtraRec));
852 if (!bitmapFont->bitmapExtra) {
853 bdfError("Couldn't allocate bitmapExtra (%d)\n",
854 (int) sizeof(BitmapExtraRec));
855 goto BAILOUT;
856 }
857
858 bitmapFont->bitmapExtra->glyphNames = 0;
859 bitmapFont->bitmapExtra->sWidths = 0;
860
861 if (!bdfReadProperties(file, pFont, &state))
862 goto BAILOUT;
863
864 if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
865 goto BAILOUT;
866
867 if (state.haveDefaultCh) {
868 unsigned int r, c, cols;
869
870 r = pFont->info.defaultCh >> 8;
871 c = pFont->info.defaultCh & 0xFF;
872 if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
873 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
874 cols = pFont->info.lastCol - pFont->info.firstCol + 1;
875 r = r - pFont->info.firstRow;
876 c = c - pFont->info.firstCol;
877 bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding,(bitmapFont->encoding[(r * cols + c)/128]?(bitmapFont->
encoding[(r * cols + c)/128][(r * cols + c)%128]):0)
878 r * cols + c)(bitmapFont->encoding[(r * cols + c)/128]?(bitmapFont->
encoding[(r * cols + c)/128][(r * cols + c)%128]):0)
;
879 }
880 }
881 pFont->bit = bit;
882 pFont->byte = byte;
883 pFont->glyph = glyph;
884 pFont->scan = scan;
885 pFont->info.anamorphic = FALSE0;
886 pFont->info.cachable = TRUE1;
887 bitmapComputeFontBounds(pFont);
888 if (FontCouldBeTerminal(&pFont->info)) {
889 bdfPadToTerminal(pFont);
890 bitmapComputeFontBounds(pFont);
891 }
892 FontComputeInfoAccelerators(&pFont->info);
893 if (bitmapFont->bitmapExtra)
894 FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info);
895 if (pFont->info.constantMetrics) {
896 if (!bitmapAddInkMetrics(pFont)) {
897 bdfError("Failed to add bitmap ink metrics\n");
898 goto BAILOUT;
899 }
900 }
901 if (bitmapFont->bitmapExtra)
902 bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
903
904 bitmapComputeFontInkBounds(pFont);
905/* ComputeFontAccelerators (pFont); */
906
907 /* generate properties */
908 min = &pFont->info.ink_minbounds;
909 max = &pFont->info.ink_maxbounds;
910 if (state.xHeightProp && (state.xHeightProp->value == -1))
911 state.xHeightProp->value = state.exHeight ?
912 state.exHeight : min->ascent;
913
914 if (state.quadWidthProp && (state.quadWidthProp->value == -1))
915 state.quadWidthProp->value = state.digitCount ?
916 (INT32) (state.digitWidths / state.digitCount) :
917 (min->characterWidth + max->characterWidth) / 2;
918
919 if (state.weightProp && (state.weightProp->value == -1))
920 state.weightProp->value = bitmapComputeWeight(pFont);
921
922 pFont->get_glyphs = bitmapGetGlyphs;
923 pFont->get_metrics = bitmapGetMetrics;
924 pFont->unload_font = bdfUnloadFont;
925 pFont->unload_glyphs = NULL((void *)0);
926 return Successful85;
927BAILOUT:
928 if (pFont->fontPrivate)
929 bdfFreeFontBits (pFont);
930 return AllocError80;
931}
932
933int
934bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
935{
936 FontRec font;
937 int ret;
938
939 bzero(&font, sizeof (FontRec))__builtin___memset_chk (&font, 0, sizeof (FontRec), __builtin_object_size
(&font, 0))
;
940
941 ret = bdfReadFont(&font, file, MSBFirst1, LSBFirst0, 1, 1);
942 if (ret == Successful85) {
943 *pFontInfo = font.info;
944 font.info.props = 0;
945 font.info.isStringProp = 0;
946 font.info.nprops = 0;
947 bdfFreeFontBits (&font);
948 }
949 return ret;
950}
951
952static Bool
953bdfPadToTerminal(FontPtr pFont)
954{
955 BitmapFontPtr bitmapFont;
956 BitmapExtraPtr bitmapExtra;
957 int i;
958 int new_size;
959 CharInfoRec new;
960 int w,
961 h;
962
963 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
964
965 bzero(&new, sizeof(CharInfoRec))__builtin___memset_chk (&new, 0, sizeof(CharInfoRec), __builtin_object_size
(&new, 0))
;
966 new.metrics.ascent = pFont->info.fontAscent;
967 new.metrics.descent = pFont->info.fontDescent;
968 new.metrics.leftSideBearing = 0;
969 new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth;
970 new.metrics.characterWidth = new.metrics.rightSideBearing;
971 new_size = BYTES_FOR_GLYPH(&new, pFont->glyph)(((&new)->metrics.ascent + (&new)->metrics.descent
) * ((pFont->glyph) == 1 ? (((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+7)>>3) :(pFont
->glyph) == 2 ? ((((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+15)>>3)&
~1) :(pFont->glyph) == 4 ? ((((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+31)>>3)&
~3) :(pFont->glyph) == 8 ? ((((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+63)>>3)&
~7) : 0))
;
972
973 for (i = 0; i < bitmapFont->num_chars; i++) {
974 new.bits = malloc(new_size);
975 if (!new.bits) {
976 bdfError("Couldn't allocate bits (%d)\n", new_size);
977 return FALSE0;
978 }
979 FontCharReshape(pFont, &bitmapFont->metrics[i], &new);
980 new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes;
981 free(bitmapFont->metrics[i].bits);
982 bitmapFont->metrics[i] = new;
983 }
984 bitmapExtra = bitmapFont->bitmapExtra;
985 if (bitmapExtra) {
986 w = GLYPHWIDTHPIXELS(&new)((&new)->metrics.rightSideBearing - (&new)->metrics
.leftSideBearing)
;
987 h = GLYPHHEIGHTPIXELS(&new)((&new)->metrics.ascent + (&new)->metrics.descent
)
;
988 for (i = 0; i < GLYPHPADOPTIONS4; i++)
989 bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars *
990 (BYTES_PER_ROW(w, 1 << i)((1 << i) == 1 ? (((w)+7)>>3) :(1 << i) == 2
? ((((w)+15)>>3)&~1) :(1 << i) == 4 ? ((((w)
+31)>>3)&~3) :(1 << i) == 8 ? ((((w)+63)>>
3)&~7) : 0)
* h);
991 }
992 return TRUE1;
993}