Bug Summary

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