Bug Summary

File:FreeType/xttcap.c
Location:line 622, column 25
Description:Value stored to 'len' during its initialization is never read

Annotated Source Code

1/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
2/* ===FileName: ===
3 Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
4 Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
5 Copyright (c) 2003 After X-TT Project, All rights reserved.
6
7===Notice
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 SUCH DAMAGE.
28
29 Major Release ID: X-TrueType Server Version 1.4 [Charles's Wain Release 0]
30
31Notice===
32 */
33
34/*
35#include "xttversion.h"
36
37static char const * const releaseID =
38 _XTT_RELEASE_NAME;
39*/
40
41#ifdef HAVE_CONFIG_H1
42#include <config.h>
43#endif
44#include <X11/fonts/fontmisc.h>
45#include <string.h>
46#include <ctype.h>
47#include <math.h>
48
49#ifndef True(-1)
50#define True(-1) (-1)
51#endif /* True */
52#ifndef False(0)
53#define False(0) (0)
54#endif /* False */
55
56#include "xttcap.h"
57
58
59/**************************************************************************
60 Private Data Types
61 */
62
63/* Property Record List */
64/* List Node */
65typedef struct TagSPropRecValListNodeP
66{
67 SPropRecValContainerEntityP containerE;
68 struct TagSPropRecValListNodeP *nextNode;
69} SPropRecValListNodeP;
70
71
72/**************************************************************************
73 Tables
74 */
75
76/* valid record field */
77static SPropertyRecord const validRecords[] =
78{
79 { "FontFile", eRecTypeString },
80 { "FaceNumber", eRecTypeString },
81 { "AutoItalic", eRecTypeDouble },
82 { "DoubleStrike", eRecTypeString },
83 { "FontProperties", eRecTypeBool },
84 { "ForceSpacing", eRecTypeString },
85 { "ScaleBBoxWidth", eRecTypeString },
86 { "ScaleWidth", eRecTypeDouble },
87 { "EncodingOptions", eRecTypeString },
88 { "Hinting", eRecTypeBool },
89 { "VeryLazyMetrics", eRecTypeBool },
90 { "CodeRange", eRecTypeString },
91 { "EmbeddedBitmap", eRecTypeString },
92 { "VeryLazyBitmapWidthScale", eRecTypeDouble },
93 { "ForceConstantSpacingCodeRange", eRecTypeString },
94 { "ForceConstantSpacingMetrics", eRecTypeString },
95 { "Dummy", eRecTypeVoid }
96};
97static int const
98numOfValidRecords = sizeof(validRecords)/sizeof(validRecords[0]);
99
100/* correspondence between record name and cap variable name */
101static struct {
102 char const * capVariable;
103 char const * recordName;
104} const correspondRelations[] = {
105 { "fn", "FaceNumber" },
106 { "ai", "AutoItalic" },
107 { "ds", "DoubleStrike" },
108 { "fp", "FontProperties" },
109 { "fs", "ForceSpacing" },
110 { "bw", "ScaleBBoxWidth" },
111 { "sw", "ScaleWidth" },
112 { "eo", "EncodingOptions" },
113 { "vl", "VeryLazyMetrics" },
114 { "bs", "VeryLazyBitmapWidthScale" },
115 { "cr", "CodeRange" },
116 { "eb", "EmbeddedBitmap" },
117 { "hi", "Hinting" },
118 { "fc", "ForceConstantSpacingCodeRange" },
119 { "fm", "ForceConstantSpacingMetrics" }
120};
121static int const
122numOfCorrespondRelations
123= sizeof(correspondRelations)/sizeof(correspondRelations[0]);
124
125/**************************************************************************
126 Functions
127 */
128
129/* get property record type by record name */
130static Bool /* True == Found, False == Not Found */
131get_record_type_by_name(SPropertyRecord const ** const refRefRecord, /*result*/
132 char const *strName)
133{
134 Bool result = False(0);
135 int i;
136
137 *refRefRecord = NULL((void*)0);
138 for (i=0; i<numOfValidRecords; i++) {
139 if (!strcasecmp(validRecords[i].strRecordName, strName)) {
140 result = True(-1);
141 *refRefRecord = &validRecords[i];
142 break;
143 }
144 }
145
146 return result;
147}
148
149/* Add Property Record Value */
150static Bool /* True == Error, False == Success */
151SPropRecValList_add_record(SDynPropRecValList *pThisList,
152 char const * const recordName,
153 char const * const strValue)
154{
155 Bool result = False(0);
156 SPropRecValContainerEntityP tmpContainerE;
157
158 if (get_record_type_by_name(&tmpContainerE.refRecordType, recordName)) {
159 switch (tmpContainerE.refRecordType->recordType) {
160 case eRecTypeInteger:
161 {
162 int val;
163 char *endPtr;
164
165 val = strtol(strValue, &endPtr, 0);
166 if ('\0' != *endPtr) {
167 fprintf(stderrstderr,
168 "truetype font property : "
169 "%s record needs integer value.\n",
170 recordName);
171 result = True(-1);
172 goto quit;
173 }
174 SPropContainer_value_int(&tmpContainerE)((&tmpContainerE)->uValue.integerValue) = val;
175 }
176 break;
177 case eRecTypeDouble:
178 {
179 double val;
180 char *endPtr;
181
182 val = strtod(strValue, &endPtr);
183 if ('\0' != *endPtr) {
184 fprintf(stderrstderr,
185 "truetype font property : "
186 "%s record needs floating point value.\n",
187 recordName);
188 result = True(-1);
189 goto quit;
190 }
191 SPropContainer_value_dbl(&tmpContainerE)((&tmpContainerE)->uValue.doubleValue) = val;
192 }
193 break;
194 case eRecTypeBool:
195 {
196 Bool val;
197
198 if (!strcasecmp(strValue, "yes"))
199 val = True(-1);
200 else if (!strcasecmp(strValue, "y"))
201 val = True(-1);
202 else if (!strcasecmp(strValue, "on"))
203 val = True(-1);
204 else if (!strcasecmp(strValue, "true"))
205 val = True(-1);
206 else if (!strcasecmp(strValue, "t"))
207 val = True(-1);
208 else if (!strcasecmp(strValue, "ok"))
209 val = True(-1);
210 else if (!strcasecmp(strValue, "no"))
211 val = False(0);
212 else if (!strcasecmp(strValue, "n"))
213 val = False(0);
214 else if (!strcasecmp(strValue, "off"))
215 val = False(0);
216 else if (!strcasecmp(strValue, "false"))
217 val = False(0);
218 else if (!strcasecmp(strValue, "f"))
219 val = False(0);
220 else if (!strcasecmp(strValue, "bad"))
221 val = False(0);
222 else {
223 fprintf(stderrstderr,
224 "truetype font property : "
225 "%s record needs boolean value.\n",
226 recordName);
227 result = True(-1);
228 goto quit;
229 }
230 SPropContainer_value_bool(&tmpContainerE)((&tmpContainerE)->uValue.boolValue) = val;
231 }
232 break;
233 case eRecTypeString:
234 {
235 char *p;
236
237 if (NULL((void*)0) == (p = malloc(strlen(strValue)+1))) {
238 fprintf(stderrstderr,
239 "truetype font property : "
240 "cannot allocate memory.\n");
241 result = True(-1);
242 goto quit;
243 }
244 strcpy(p, strValue);
245 SPropContainer_value_str(&tmpContainerE)((&tmpContainerE)->uValue.dynStringValue) = p;
246 }
247 break;
248 case eRecTypeVoid:
249 if ('\0' != *strValue) {
250 fprintf(stderrstderr,
251 "truetype font property : "
252 "%s record needs void.\n", recordName);
253 result = True(-1);
254 }
255 break;
256 }
257 {
258 /* add to list */
259 SPropRecValListNodeP *newNode;
260
261 if (NULL((void*)0) == (newNode = malloc(sizeof(*newNode)))) {
262 fprintf(stderrstderr,
263 "truetype font property : "
264 "cannot allocate memory.\n");
265 result = True(-1);
266 goto quit;
267 }
268 newNode->nextNode = pThisList->headNode;
269 newNode->containerE = tmpContainerE;
270 tmpContainerE.refRecordType = NULL((void*)0); /* invalidate --
271 disown value handle. */
272 pThisList->headNode = newNode;
273 }
274 } else {
275 /* invalid record name */
276 fprintf(stderrstderr,
277 "truetype font : "
278 "invalid record name \"%s.\"\n", recordName);
279 result = True(-1);
280 }
281
282 quit:
283 return result;
284}
285
286#ifdef USE_TTP_FILE
287
288#ifndef LEN_LINEBUF
289#define LEN_LINEBUF 2048
290#endif /* !def LEN_LINEBUF */
291
292/* get one line */
293static Bool /* True == Error, False == Success */
294get_one_line(FILE *is, char *buf)
295{
296 Bool result = False(0);
297 int count = 0;
298 Bool flHead = True(-1);
299 Bool flSpace = False(0);
300 Bool flInSingleQuote = False(0);
301 Bool flInDoubleQuote = False(0);
302 Bool flBackSlash = False(0);
303 Bool flFirstElement = True(-1);
304
305 *buf = '\0';
306 for (;;) {
307 int c = fgetc(is);
308
309 if (ferror(is)) {
310 fprintf(stderrstderr, "truetype font property file : read error.\n");
311 result = True(-1);
312 break;
313 }
314
315 if (EOF(-1) == c) {
316 if (flInSingleQuote || flInDoubleQuote) {
317 fprintf(stderrstderr,
318 "truetype font property file : unmatched quote.\n");
319 result = True(-1);
320 }
321 break;
322 }
323 if (flInSingleQuote) {
324 if ('\'' == c) {
325 /* end of single quoted string */
326 flInSingleQuote = False(0);
327 c = -1; /* NOT extract to buffer. */
328 } else
329 /* others, extract all character to buffer unconditionally. */
330 ;
331 goto trans;
332 }
333 if (flBackSlash) {
334 /* escape --- when just before character is backslash,
335 next character is escaped. */
336 flBackSlash = False(0);
337 if ('n' == c)
338 /* newline */
339 c = '\n';
340 if ('\n' == c)
341 /* ignore newline */
342 c = -1;
343 else
344 /* others, extract all character to buffer unconditionally. */
345 ;
346 goto trans;
347 }
348 if ('\\' == c) {
349 /* set flag to escape next character. */
350 flBackSlash = True(-1);
351 c = -1; /* NOT extract to buffer. */
352 goto trans;
353 }
354 if (flInDoubleQuote) {
355 if ('"' == c) {
356 /* end of double quoted string */
357 flInDoubleQuote = False(0);
358 c = -1; /* NOT extract to buffer. */
359 } else
360 /* others, extract all character to buffer unconditionally. */
361 ;
362 goto trans;
363 }
364 if ('#' == c) {
365 /* skip comment till end of line. */
366 while ('\n' != c) {
367 c = fgetc(is);
368 if (ferror(is)) {
369 fprintf(stderrstderr,
370 "truetype font property file : read error.\n");
371 result = True(-1);
372 break;
373 }
374 if (EOF(-1) == c) {
375 break;
376 }
377 }
378 break;
379 }
380 if ('\'' == c) {
381 /* into single quoted string */
382 flInSingleQuote = True(-1);
383 c = -1; /* NOT extract to buffer. */
384 goto trans;
385 }
386 if ('"' == c) {
387 /* into double quoted string */
388 flInDoubleQuote = True(-1);
389 c = -1; /* NOT extract to buffer. */
390 goto trans;
391 }
392 if ('\n' == c)
393 /* End of Line */
394 break;
395 if (isspace(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace
)
) {
396 /* convine multiple spaces */
397 if (!flHead)
398 /* except space at the head of line */
399 flSpace = True(-1);
400 continue;
401 }
402 trans:
403 /* set flHead to False, since current character is not white space
404 when reaches here. */
405 flHead = False(0);
406 do {
407 if (count>=LEN_LINEBUF-1) {
408 /* overflow */
409 fprintf(stderrstderr,
410 "truetype font property file : too long line.\n");
411 result = True(-1);
412 goto quit;
413 }
414 if (flSpace) {
415 /* just before characters is white space, but
416 current character is not WS. */
417 if (flFirstElement) {
418 /* this spaces is the first cell(?) of white spaces. */
419 flFirstElement = False(0);
420 /* separate record name and record value */
421 *buf = (char)0xff;
422 } else
423 *buf = ' ';
424 flSpace = False(0);
425 } else
426 if (-1 != c) {
427 *buf = c;
428 c = -1; /* invalidate */
429 } else
430 /* skip */
431 buf--;
432 buf++;
433 } while (-1 != c); /* when 'c' is not -1, it means
434 that 'c' contains an untreated character. */
435 }
436 *buf = '\0';
437
438 quit:
439 return result;
440}
441
442/* parse one line */
443static Bool /* True == Error, False == Success */
444parse_one_line(SDynPropRecValList *pThisList, FILE *is)
445{
446 Bool result = False(0);
447 char *buf = NULL((void*)0);
448 char *recordHead, *valueHead = NULL((void*)0);
449
450 if (NULL((void*)0) == (buf = malloc(LEN_LINEBUF))) {
451 fprintf(stderrstderr,
452 "truetype font property file : cannot allocate memory.\n");
453 result = True(-1);
454 goto abort;
455 }
456 {
457 recordHead = buf;
458/* refRecordValue->refRecordType = NULL;*/
459 do {
460 if (get_one_line(is, buf)) {
461 result = True(-1);
462 goto quit;
463 }
464 if (feof(is)) {
465 if ('\0' == *buf)
466 goto quit;
467 break;
468 }
469 } while ('\0' == *buf);
470
471 if (NULL((void*)0) != (valueHead = strchr(buf, 0xff))) {
472 *valueHead = '\0';
473 valueHead++;
474 } else
475 valueHead = buf+strlen(buf);
476#if 0
477 fprintf(stderrstderr,
478 "truetype font property file : \n"
479 "recName:\"%s\"\nvalue:\"%s\"\n",
480 recordHead, valueHead);
481#endif
482 result = SPropRecValList_add_record(pThisList, recordHead, valueHead);
483 }
484 quit:
485 free(buf);
486 abort:
487 return result;
488}
489
490/* Read Property File */
491Bool /* True == Error, False == Success */
492SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
493 char const * const strFileName)
494{
495 Bool result = False(0);
496 FILE *is;
497
498#if 1
499 if (!strcmp(strFileName, "-"))
500 is = stdinstdin;
501 else
502#endif
503 is = fopen(strFileName, "r");
504 if (NULL((void*)0) == is) {
505 fprintf(stderrstderr, "truetype font property : cannot open file %s.\n",
506 strFileName);
507 result = True(-1);
508 goto abort;
509 }
510 {
511 for (;;) {
512 if (False(0) != (result = parse_one_line(pThisList, is)))
513 goto quit;
514 if (feof(is))
515 break;
516 }
517 }
518 quit:
519#if 1
520 if (strcmp(strFileName, "-"))
521#endif
522 fclose(is);
523 abort:
524 return result;
525}
526#endif /* USE_TTP_FILE */
527
528/* Constructor for Container Node */
529Bool /* True == Error, False == Success */
530SPropRecValList_new(SDynPropRecValList *pThisList)
531{
532 Bool result = False(0);
533
534 pThisList->headNode = NULL((void*)0);
535
536 return result;
537}
538
539#ifdef DUMP
540void
541SPropRecValList_dump(SRefPropRecValList *pThisList)
542{
543 SPropRecValListNodeP *p;
544 for (p=pThisList->headNode; NULL((void*)0)!=p; p=p->nextNode) {
545 switch (p->containerE.refRecordType->recordType) {
546 case eRecTypeInteger:
547 fprintf(stderrstderr, "%s = %d\n",
548 p->containerE.refRecordType->strRecordName,
549 p->containerE.uValue.integerValue);
550 break;
551 case eRecTypeDouble:
552 fprintf(stderrstderr, "%s = %f\n",
553 p->containerE.refRecordType->strRecordName,
554 p->containerE.uValue.doubleValue);
555 break;
556 case eRecTypeBool:
557 fprintf(stderrstderr, "%s = %s\n",
558 p->containerE.refRecordType->strRecordName,
559 p->containerE.uValue.boolValue
560 ? "True":"False");
561 break;
562 case eRecTypeString:
563 fprintf(stderrstderr, "%s = \"%s\"\n",
564 p->containerE.refRecordType->strRecordName,
565 p->containerE.uValue.dynStringValue);
566 break;
567 case eRecTypeVoid:
568 fprintf(stderrstderr, "%s = void\n",
569 p->containerE.refRecordType->strRecordName);
570 break;
571 }
572 }
573}
574#endif
575
576
577/* Search Property Record */
578Bool /* True == Hit, False == Miss */
579SPropRecValList_search_record(SRefPropRecValList *pThisList,
580 SPropRecValContainer *refRecValue,
581 char const * const recordName)
582{
583 Bool result = False(0);
584 SPropRecValListNodeP *p;
585
586 *refRecValue = NULL((void*)0);
587 for (p=pThisList->headNode; NULL((void*)0)!=p; p=p->nextNode) {
588 if (!strcasecmp(p->containerE.refRecordType->strRecordName,
589 recordName)) {
590 *refRecValue = &p->containerE;
591 result = True(-1);
592 break;
593 }
594 }
595
596 return result;
597}
598
599
600/* Parse TTCap */
601Bool /* True == Error, False == Success */
602SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
603 char const *strCapHead)
604{
605 Bool result = False(0);
606 /* SPropertyRecord const *refRecordType; */
607 char const *term;
608
609 if (NULL((void*)0) == (term = strrchr(strCapHead, ':')))
610 goto abort;
611
612 {
613 /* for xfsft compatible */
614 char const *p;
615 for (p=term-1; p>=strCapHead; p--) {
616 if ( ':'==*p ) {
617 /*
618 * :num:filename
619 * ^p ^term
620 */
621 if ( p!=term ) {
622 int len = term-p-1;
Value stored to 'len' during its initialization is never read
623 char *value;
624
625 len = term-p-1;
626 value=malloc(len+1);
627 memcpy(value, p+1, len);
628 value[len]='\0';
629 SPropRecValList_add_record(pThisList,
630 "FaceNumber",
631 value);
632 free(value);
633 term=p;
634 }
635 break;
636 }
637 if ( !isdigit(*p)((*__ctype_b_loc ())[(int) ((*p))] & (unsigned short int)
_ISdigit)
)
638 break;
639 }
640 }
641
642 while (strCapHead<term) {
643 int i;
644 char const *nextColon = strchr(strCapHead, ':');
645 if (0<nextColon-strCapHead) {
646 char *duplicated = malloc((nextColon-strCapHead)+1);
647 {
648 char *value;
649
650 memcpy(duplicated, strCapHead, nextColon-strCapHead);
651 duplicated[nextColon-strCapHead] = '\0';
652 if (NULL((void*)0) != (value=strchr(duplicated, '='))) {
653 *value = '\0';
654 value++;
655 } else
656 value = &duplicated[nextColon-strCapHead];
657
658 for (i=0; i<numOfCorrespondRelations; i++) {
659 if (!strcasecmp(correspondRelations[i].capVariable,
660 duplicated)) {
661 if (SPropRecValList_add_record(pThisList,
662 correspondRelations[i]
663 .recordName,
664 value))
665 break;
666 goto next;
667 }
668 }
669 fprintf(stderrstderr, "truetype font : Illegal Font Cap.\n");
670 result = True(-1);
671 break;
672 next:
673 ;
674 }
675 free(duplicated);
676 }
677 strCapHead = nextColon+1;
678 }
679
680 /* quit: */
681 abort:
682 return result;
683}
684
685
686/**************************************************************************
687 Functions (xttmisc)
688 */
689
690/* strdup clone with using the allocator of X server */
691char *
692XttXstrdup(char const *str)
693{
694 char *result;
695
696 result = malloc(strlen(str)+1);
697
698 if (result)
699 strcpy(result, str);
700
701 return result;
702}
703
704
705/* end of file */