Bug Summary

File:modules/im/ximcp/imLcPrs.c
Location:line 390, column 18
Description:String copy function overflows destination buffer

Annotated Source Code

1/******************************************************************
2
3 Copyright 1992 by Oki Technosystems Laboratory, Inc.
4 Copyright 1992 by Fuji Xerox Co., Ltd.
5
6Permission to use, copy, modify, distribute, and sell this software
7and its documentation for any purpose is hereby granted without fee,
8provided that the above copyright notice appear in all copies and
9that both that copyright notice and this permission notice appear
10in supporting documentation, and that the name of Oki Technosystems
11Laboratory and Fuji Xerox not be used in advertising or publicity
12pertaining to distribution of the software without specific, written
13prior permission.
14Oki Technosystems Laboratory and Fuji Xerox make no representations
15about the suitability of this software for any purpose. It is provided
16"as is" without express or implied warranty.
17
18OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
19WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
20MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
21LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
23OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
24OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
25OR PERFORMANCE OF THIS SOFTWARE.
26
27 Author: Yasuhiro Kawai Oki Technosystems Laboratory
28 Author: Kazunori Nishihara Fuji Xerox
29
30******************************************************************/
31
32
33#ifdef HAVE_CONFIG_H1
34#include <config.h>
35#endif
36#include <X11/Xlib.h>
37#include <X11/Xmd.h>
38#include <X11/Xos.h>
39#include "Xlibint.h"
40#include "Xlcint.h"
41#include "Ximint.h"
42#include <sys/stat.h>
43#include <stdio.h>
44#include <limits.h>
45#include "pathmax.h"
46
47#define XLC_BUFSIZE256 256
48
49extern int _Xmbstowcs(
50 wchar_t *wstr,
51 char *str,
52 int len
53);
54
55extern int _Xmbstoutf8(
56 char *ustr,
57 const char *str,
58 int len
59);
60
61static void parsestringfile(FILE *fp, Xim im, int depth);
62
63/*
64 * Parsing File Format:
65 *
66 * FILE ::= { [PRODUCTION] [COMMENT] "\n"}
67 * PRODUCTION ::= LHS ":" RHS [ COMMENT ]
68 * COMMENT ::= "#" {<any character except null or newline>}
69 * LHS ::= EVENT { EVENT }
70 * EVENT ::= [MODIFIER_LIST] "<" keysym ">"
71 * MODIFIER_LIST ::= (["!"] {MODIFIER} ) | "None"
72 * MODIFIER ::= ["~"] MODIFIER_NAME
73 * MODIFIER_NAME ::= ("Ctrl"|"Lock"|"Caps"|"Shift"|"Alt"|"Meta")
74 * RHS ::= ( STRING | keysym | STRING keysym )
75 * STRING ::= '"' { CHAR } '"'
76 * CHAR ::= GRAPHIC_CHAR | ESCAPED_CHAR
77 * GRAPHIC_CHAR ::= locale (codeset) dependent code
78 * ESCAPED_CHAR ::= ('\\' | '\"' | OCTAL | HEX )
79 * OCTAL ::= '\' OCTAL_CHAR [OCTAL_CHAR [OCTAL_CHAR]]
80 * OCTAL_CHAR ::= (0|1|2|3|4|5|6|7)
81 * HEX ::= '\' (x|X) HEX_CHAR [HEX_CHAR]]
82 * HEX_CHAR ::= (0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|a|b|c|d|e|f)
83 *
84 */
85
86static int
87nextch(
88 FILE *fp,
89 int *lastch)
90{
91 int c;
92
93 if (*lastch != 0) {
94 c = *lastch;
95 *lastch = 0;
96 } else {
97 c = getc(fp);
98 if (c == '\\') {
99 c = getc(fp);
100 if (c == '\n') {
101 c = getc(fp);
102 } else {
103 ungetc(c, fp);
104 c = '\\';
105 }
106 }
107 }
108 return(c);
109}
110
111static void
112putbackch(
113 int c,
114 int *lastch)
115{
116 *lastch = c;
117}
118
119#define ENDOFFILE0 0
120#define ENDOFLINE1 1
121#define COLON2 2
122#define LESS3 3
123#define GREATER4 4
124#define EXCLAM5 5
125#define TILDE6 6
126#define STRING7 7
127#define KEY8 8
128#define ERROR9 9
129
130#ifndef isalnum
131#define isalnum(c)(('0' <= (c) && (c) <= '9') || ('A' <= (c) &&
(c) <= 'Z') || ('a' <= (c) && (c) <= 'z'))
\
132 (('0' <= (c) && (c) <= '9') || \
133 ('A' <= (c) && (c) <= 'Z') || \
134 ('a' <= (c) && (c) <= 'z'))
135#endif
136
137static int
138nexttoken(
139 FILE *fp,
140 char *tokenbuf,
141 int *lastch)
142{
143 int c;
144 int token;
145 char *p;
146 int i, j;
147
148 while ((c = nextch(fp, lastch)) == ' ' || c == '\t') {
149 }
150 switch (c) {
151 case EOF(-1):
152 token = ENDOFFILE0;
153 break;
154 case '\n':
155 token = ENDOFLINE1;
156 break;
157 case '<':
158 token = LESS3;
159 break;
160 case '>':
161 token = GREATER4;
162 break;
163 case ':':
164 token = COLON2;
165 break;
166 case '!':
167 token = EXCLAM5;
168 break;
169 case '~':
170 token = TILDE6;
171 break;
172 case '"':
173 p = tokenbuf;
174 while ((c = nextch(fp, lastch)) != '"') {
175 if (c == '\n' || c == EOF(-1)) {
176 putbackch(c, lastch);
177 token = ERROR9;
178 goto string_error;
179 } else if (c == '\\') {
180 c = nextch(fp, lastch);
181 switch (c) {
182 case '\\':
183 case '"':
184 *p++ = c;
185 break;
186 case 'n':
187 *p++ = '\n';
188 break;
189 case 'r':
190 *p++ = '\r';
191 break;
192 case 't':
193 *p++ = '\t';
194 break;
195 case '0':
196 case '1':
197 case '2':
198 case '3':
199 case '4':
200 case '5':
201 case '6':
202 case '7':
203 i = c - '0';
204 c = nextch(fp, lastch);
205 for (j = 0; j < 2 && c >= '0' && c <= '7'; j++) {
206 i <<= 3;
207 i += c - '0';
208 c = nextch(fp, lastch);
209 }
210 putbackch(c, lastch);
211 *p++ = (char)i;
212 break;
213 case 'X':
214 case 'x':
215 i = 0;
216 for (j = 0; j < 2; j++) {
217 c = nextch(fp, lastch);
218 i <<= 4;
219 if (c >= '0' && c <= '9') {
220 i += c - '0';
221 } else if (c >= 'A' && c <= 'F') {
222 i += c - 'A' + 10;
223 } else if (c >= 'a' && c <= 'f') {
224 i += c - 'a' + 10;
225 } else {
226 putbackch(c, lastch);
227 i >>= 4;
228 break;
229 }
230 }
231 if (j == 0) {
232 token = ERROR9;
233 goto string_error;
234 }
235 *p++ = (char)i;
236 break;
237 case EOF(-1):
238 putbackch(c, lastch);
239 token = ERROR9;
240 goto string_error;
241 default:
242 *p++ = c;
243 break;
244 }
245 } else {
246 *p++ = c;
247 }
248 }
249 *p = '\0';
250 token = STRING7;
251 break;
252 case '#':
253 while ((c = nextch(fp, lastch)) != '\n' && c != EOF(-1)) {
254 }
255 if (c == '\n') {
256 token = ENDOFLINE1;
257 } else {
258 token = ENDOFFILE0;
259 }
260 break;
261 default:
262 if (isalnum(c)(('0' <= (c) && (c) <= '9') || ('A' <= (c) &&
(c) <= 'Z') || ('a' <= (c) && (c) <= 'z'))
|| c == '_' || c == '-') {
263 p = tokenbuf;
264 *p++ = c;
265 c = nextch(fp, lastch);
266 while (isalnum(c)(('0' <= (c) && (c) <= '9') || ('A' <= (c) &&
(c) <= 'Z') || ('a' <= (c) && (c) <= 'z'))
|| c == '_' || c == '-') {
267 *p++ = c;
268 c = nextch(fp, lastch);
269 }
270 *p = '\0';
271 putbackch(c, lastch);
272 token = KEY8;
273 } else {
274 token = ERROR9;
275 }
276 break;
277 }
278string_error:
279 return(token);
280}
281
282static long
283modmask(
284 char *name)
285{
286 struct _modtbl {
287 const char name[6];
288 long mask;
289 };
290
291 static const struct _modtbl tbl[] = {
292 { "Ctrl", ControlMask(1<<2) },
293 { "Lock", LockMask(1<<1) },
294 { "Caps", LockMask(1<<1) },
295 { "Shift", ShiftMask(1<<0) },
296 { "Alt", Mod1Mask(1<<3) },
297 { "Meta", Mod1Mask(1<<3) }};
298
299 int i, num_entries = sizeof (tbl) / sizeof (tbl[0]);
300
301 for (i = 0; i < num_entries; i++)
302 if (!strcmp (name, tbl[i].name))
303 return tbl[i].mask;
304
305 return 0;
306}
307
308static char*
309TransFileName(Xim im, char *name)
310{
311 char *home = NULL((void*)0), *lcCompose = NULL((void*)0);
312 char dir[XLC_BUFSIZE256] = "";
313 char *i = name, *ret = NULL((void*)0), *j;
314 size_t l = 0;
315
316 while (*i) {
1
Loop condition is true. Entering loop body
5
Loop condition is false. Execution continues on line 366
317 if (*i == '%') {
2
Taking true branch
318 i++;
319 switch (*i) {
3
'Default' branch taken. Execution continues on line 360
320 case '%':
321 l++;
322 break;
323 case 'H':
324 if (home == NULL((void*)0))
325 home = getenv("HOME");
326 if (home) {
327 size_t Hsize = strlen(home);
328 if (Hsize > PATH_MAX1024)
329 /* your home directory length is ridiculous */
330 goto end;
331 l += Hsize;
332 }
333 break;
334 case 'L':
335 if (lcCompose == NULL((void*)0))
336 lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE"Compose");
337 if (lcCompose) {
338 size_t Lsize = strlen(lcCompose);
339 if (Lsize > PATH_MAX1024)
340 /* your compose pathname length is ridiculous */
341 goto end;
342 l += Lsize;
343 }
344 break;
345 case 'S':
346 if (dir[0] == '\0')
347 xlocaledir(dir, XLC_BUFSIZE256);
348 if (dir[0]) {
349 size_t Ssize = strlen(dir);
350 if (Ssize > PATH_MAX1024)
351 /* your locale directory path length is ridiculous */
352 goto end;
353 l += Ssize;
354 }
355 break;
356 }
357 } else {
358 l++;
359 }
360 i++;
361 if (l > PATH_MAX1024)
4
Taking false branch
362 /* your expanded path length is ridiculous */
363 goto end;
364 }
365
366 j = ret = Xmalloc(l+1)malloc(((l+1) == 0 ? 1 : (l+1)));
367 if (ret == NULL((void*)0))
6
Assuming 'ret' is not equal to null
7
Taking false branch
368 goto end;
369 i = name;
370 while (*i) {
8
Loop condition is true. Entering loop body
11
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
371 if (*i == '%') {
9
Taking true branch
12
Taking false branch
14
Taking true branch
372 i++;
373 switch (*i) {
10
'Default' branch taken. Execution continues on line 394
15
Control jumps to 'case 83:' at line 389
374 case '%':
375 *j++ = '%';
376 break;
377 case 'H':
378 if (home) {
379 strcpy(j, home)__builtin___strcpy_chk (j, home, __builtin_object_size (j, 2 >
1 ? 1 : 0))
;
380 j += strlen(home);
381 }
382 break;
383 case 'L':
384 if (lcCompose) {
385 strcpy(j, lcCompose)__builtin___strcpy_chk (j, lcCompose, __builtin_object_size (
j, 2 > 1 ? 1 : 0))
;
386 j += strlen(lcCompose);
387 }
388 break;
389 case 'S':
390 strcpy(j, dir)__builtin___strcpy_chk (j, dir, __builtin_object_size (j, 2 >
1 ? 1 : 0))
;
16
Within the expansion of the macro 'strcpy':
a
String copy function overflows destination buffer
391 j += strlen(dir);
392 break;
393 }
394 i++;
395 } else {
396 *j++ = *i++;
397 }
398 }
399 *j = '\0';
400end:
401 Xfree(lcCompose)free((lcCompose));
402 return ret;
403}
404
405#ifndef MB_LEN_MAX6
406#define MB_LEN_MAX6 6
407#endif
408
409static int
410get_mb_string (Xim im, char *buf, KeySym ks)
411{
412 XPointer from, to;
413 int from_len, to_len, len;
414 XPointer args[1];
415 XlcCharSet charset;
416 char local_buf[MB_LEN_MAX6];
417 unsigned int ucs;
418 ucs = KeySymToUcs4(ks);
419
420 from = (XPointer) &ucs;
421 to = (XPointer) local_buf;
422 from_len = 1;
423 to_len = MB_LEN_MAX6;
424 args[0] = (XPointer) &charset;
425 if (_XlcConvert(im->private.local.ucstoc_conv,
426 &from, &from_len, &to, &to_len, args, 1 ) != 0) {
427 return 0;
428 }
429
430 from = (XPointer) local_buf;
431 to = (XPointer) buf;
432 from_len = MB_LEN_MAX6 - to_len;
433 to_len = MB_LEN_MAX6 + 1;
434 args[0] = (XPointer) charset;
435 if (_XlcConvert(im->private.local.cstomb_conv,
436 &from, &from_len, &to, &to_len, args, 1 ) != 0) {
437 return 0;
438 }
439 len = MB_LEN_MAX6 + 1 - to_len;
440 buf[len] = '\0';
441 return len;
442}
443
444#define AllMask((1<<0) | (1<<1) | (1<<2) | (1<<3)) (ShiftMask(1<<0) | LockMask(1<<1) | ControlMask(1<<2) | Mod1Mask(1<<3))
445#define LOCAL_WC_BUFSIZE128 128
446#define LOCAL_UTF8_BUFSIZE256 256
447#define SEQUENCE_MAX10 10
448
449static int
450parseline(
451 FILE *fp,
452 Xim im,
453 char* tokenbuf,
454 int depth)
455{
456 int token;
457 DTModifier modifier_mask;
458 DTModifier modifier;
459 DTModifier tmp;
460 KeySym keysym = NoSymbol0L;
461 DTIndex *top = &im->private.local.top;
462 DefTreeBase *b = &im->private.local.base;
463 DTIndex t;
464 DefTree *p = NULL((void*)0);
465 Boolint exclam, tilde;
466 KeySym rhs_keysym = 0;
467 char *rhs_string_mb;
468 int l;
469 int lastch = 0;
470 char local_mb_buf[MB_LEN_MAX6+1];
471 wchar_t local_wc_buf[LOCAL_WC_BUFSIZE128], *rhs_string_wc;
472 char local_utf8_buf[LOCAL_UTF8_BUFSIZE256], *rhs_string_utf8;
473
474 struct DefBuffer {
475 DTModifier modifier_mask;
476 DTModifier modifier;
477 KeySym keysym;
478 };
479
480 struct DefBuffer buf[SEQUENCE_MAX10];
481 int i, n;
482
483 do {
484 token = nexttoken(fp, tokenbuf, &lastch);
485 } while (token == ENDOFLINE1);
486
487 if (token == ENDOFFILE0) {
488 return(-1);
489 }
490
491 n = 0;
492 do {
493 if ((token == KEY8) && (strcmp("include", tokenbuf) == 0)) {
494 char *filename;
495 FILE *infp;
496 token = nexttoken(fp, tokenbuf, &lastch);
497 if (token != KEY8 && token != STRING7)
498 goto error;
499 if (++depth > 100)
500 goto error;
501 if ((filename = TransFileName(im, tokenbuf)) == NULL((void*)0))
502 goto error;
503 infp = _XFopenFile(filename, "r")fopen(filename,"r");
504 Xfree(filename)free((filename));
505 if (infp == NULL((void*)0))
506 goto error;
507 parsestringfile(infp, im, depth);
508 fclose(infp);
509 return (0);
510 } else if ((token == KEY8) && (strcmp("None", tokenbuf) == 0)) {
511 modifier = 0;
512 modifier_mask = AllMask((1<<0) | (1<<1) | (1<<2) | (1<<3));
513 token = nexttoken(fp, tokenbuf, &lastch);
514 } else {
515 modifier_mask = modifier = 0;
516 exclam = False0;
517 if (token == EXCLAM5) {
518 exclam = True1;
519 token = nexttoken(fp, tokenbuf, &lastch);
520 }
521 while (token == TILDE6 || token == KEY8) {
522 tilde = False0;
523 if (token == TILDE6) {
524 tilde = True1;
525 token = nexttoken(fp, tokenbuf, &lastch);
526 if (token != KEY8)
527 goto error;
528 }
529 tmp = modmask(tokenbuf);
530 if (!tmp) {
531 goto error;
532 }
533 modifier_mask |= tmp;
534 if (tilde) {
535 modifier &= ~tmp;
536 } else {
537 modifier |= tmp;
538 }
539 token = nexttoken(fp, tokenbuf, &lastch);
540 }
541 if (exclam) {
542 modifier_mask = AllMask((1<<0) | (1<<1) | (1<<2) | (1<<3));
543 }
544 }
545
546 if (token != LESS3) {
547 goto error;
548 }
549
550 token = nexttoken(fp, tokenbuf, &lastch);
551 if (token != KEY8) {
552 goto error;
553 }
554
555 token = nexttoken(fp, tokenbuf, &lastch);
556 if (token != GREATER4) {
557 goto error;
558 }
559
560 keysym = XStringToKeysym(tokenbuf);
561 if (keysym == NoSymbol0L) {
562 goto error;
563 }
564
565 buf[n].keysym = keysym;
566 buf[n].modifier = modifier;
567 buf[n].modifier_mask = modifier_mask;
568 n++;
569 if( n >= SEQUENCE_MAX10 )
570 goto error;
571 token = nexttoken(fp, tokenbuf, &lastch);
572 } while (token != COLON2);
573
574 token = nexttoken(fp, tokenbuf, &lastch);
575 if (token == STRING7) {
576 l = strlen(tokenbuf) + 1;
577 while (b->mbused + l > b->mbsize) {
578 DTCharIndex newsize = b->mbsize ? b->mbsize * 1.5 : 1024;
579 char *newmb = Xrealloc (b->mb, newsize)realloc((b->mb), ((newsize) == 0 ? 1 : (newsize)));
580 if (newmb == NULL((void*)0))
581 goto error;
582 b->mb = newmb;
583 b->mbsize = newsize;
584 }
585 rhs_string_mb = &b->mb[b->mbused];
586 b->mbused += l;
587 strcpy(rhs_string_mb, tokenbuf)__builtin___strcpy_chk (rhs_string_mb, tokenbuf, __builtin_object_size
(rhs_string_mb, 2 > 1 ? 1 : 0))
;
588 token = nexttoken(fp, tokenbuf, &lastch);
589 if (token == KEY8) {
590 rhs_keysym = XStringToKeysym(tokenbuf);
591 if (rhs_keysym == NoSymbol0L) {
592 goto error;
593 }
594 token = nexttoken(fp, tokenbuf, &lastch);
595 }
596 if (token != ENDOFLINE1 && token != ENDOFFILE0) {
597 goto error;
598 }
599 } else if (token == KEY8) {
600 rhs_keysym = XStringToKeysym(tokenbuf);
601 if (rhs_keysym == NoSymbol0L) {
602 goto error;
603 }
604 token = nexttoken(fp, tokenbuf, &lastch);
605 if (token != ENDOFLINE1 && token != ENDOFFILE0) {
606 goto error;
607 }
608
609 l = get_mb_string(im, local_mb_buf, rhs_keysym);
610 while (b->mbused + l + 1 > b->mbsize) {
611 DTCharIndex newsize = b->mbsize ? b->mbsize * 1.5 : 1024;
612 char *newmb = Xrealloc (b->mb, newsize)realloc((b->mb), ((newsize) == 0 ? 1 : (newsize)));
613 if (newmb == NULL((void*)0))
614 goto error;
615 b->mb = newmb;
616 b->mbsize = newsize;
617 }
618 rhs_string_mb = &b->mb[b->mbused];
619 b->mbused += l + 1;
620 memcpy(rhs_string_mb, local_mb_buf, l)__builtin___memcpy_chk (rhs_string_mb, local_mb_buf, l, __builtin_object_size
(rhs_string_mb, 0))
;
621 rhs_string_mb[l] = '\0';
622 } else {
623 goto error;
624 }
625
626 l = _Xmbstowcs(local_wc_buf, rhs_string_mb, LOCAL_WC_BUFSIZE128 - 1);
627 if (l == LOCAL_WC_BUFSIZE128 - 1) {
628 local_wc_buf[l] = (wchar_t)'\0';
629 }
630 while (b->wcused + l + 1 > b->wcsize) {
631 DTCharIndex newsize = b->wcsize ? b->wcsize * 1.5 : 512;
632 wchar_t *newwc = Xrealloc (b->wc, sizeof(wchar_t) * newsize)realloc((b->wc), ((sizeof(wchar_t) * newsize) == 0 ? 1 : (
sizeof(wchar_t) * newsize)))
;
633 if (newwc == NULL((void*)0))
634 goto error;
635 b->wc = newwc;
636 b->wcsize = newsize;
637 }
638 rhs_string_wc = &b->wc[b->wcused];
639 b->wcused += l + 1;
640 memcpy((char *)rhs_string_wc, (char *)local_wc_buf, (l + 1) * sizeof(wchar_t) )__builtin___memcpy_chk ((char *)rhs_string_wc, (char *)local_wc_buf
, (l + 1) * sizeof(wchar_t), __builtin_object_size ((char *)rhs_string_wc
, 0))
;
641
642 l = _Xmbstoutf8(local_utf8_buf, rhs_string_mb, LOCAL_UTF8_BUFSIZE256 - 1);
643 if (l == LOCAL_UTF8_BUFSIZE256 - 1) {
644 local_utf8_buf[l] = '\0';
645 }
646 while (b->utf8used + l + 1 > b->utf8size) {
647 DTCharIndex newsize = b->utf8size ? b->utf8size * 1.5 : 1024;
648 char *newutf8 = Xrealloc (b->utf8, newsize)realloc((b->utf8), ((newsize) == 0 ? 1 : (newsize)));
649 if (newutf8 == NULL((void*)0))
650 goto error;
651 b->utf8 = newutf8;
652 b->utf8size = newsize;
653 }
654 rhs_string_utf8 = &b->utf8[b->utf8used];
655 b->utf8used += l + 1;
656 memcpy(rhs_string_utf8, local_utf8_buf, l + 1)__builtin___memcpy_chk (rhs_string_utf8, local_utf8_buf, l + 1
, __builtin_object_size (rhs_string_utf8, 0))
;
657
658 for (i = 0; i < n; i++) {
659 for (t = *top; t; t = b->tree[t].next) {
660 if (buf[i].keysym == b->tree[t].keysym &&
661 buf[i].modifier == b->tree[t].modifier &&
662 buf[i].modifier_mask == b->tree[t].modifier_mask) {
663 break;
664 }
665 }
666 if (t) {
667 p = &b->tree[t];
668 top = &p->succession;
669 } else {
670 while (b->treeused >= b->treesize) {
671 DefTree *old = b->tree;
672 int oldsize = b->treesize;
673 int newsize = b->treesize ? b->treesize * 1.5 : 256;
674 DefTree *new = Xrealloc (b->tree, sizeof(DefTree) * newsize)realloc((b->tree), ((sizeof(DefTree) * newsize) == 0 ? 1 :
(sizeof(DefTree) * newsize)))
;
675 if (new == NULL((void*)0))
676 goto error;
677 b->tree = new;
678 b->treesize = newsize;
679 if (top >= (DTIndex *) old && top < (DTIndex *) &old[oldsize])
680 top = (DTIndex *) (((char *) top) + (((char *)b->tree)-(char *)old));
681 }
682 p = &b->tree[b->treeused];
683 p->keysym = buf[i].keysym;
684 p->modifier = buf[i].modifier;
685 p->modifier_mask = buf[i].modifier_mask;
686 p->succession = 0;
687 p->next = *top;
688 p->mb = 0;
689 p->wc = 0;
690 p->utf8 = 0;
691 p->ks = NoSymbol0L;
692 *top = b->treeused;
693 top = &p->succession;
694 b->treeused++;
695 }
696 }
697
698 /* old entries no longer freed... */
699 p->mb = rhs_string_mb - b->mb;
700 p->wc = rhs_string_wc - b->wc;
701 p->utf8 = rhs_string_utf8 - b->utf8;
702 p->ks = rhs_keysym;
703 return(n);
704error:
705 while (token != ENDOFLINE1 && token != ENDOFFILE0) {
706 token = nexttoken(fp, tokenbuf, &lastch);
707 }
708 return(0);
709}
710
711void
712_XimParseStringFile(
713 FILE *fp,
714 Xim im)
715{
716 parsestringfile(fp, im, 0);
717}
718
719static void
720parsestringfile(
721 FILE *fp,
722 Xim im,
723 int depth)
724{
725 char tb[8192];
726 char* tbp;
727 struct stat st;
728
729 if (fstat (fileno (fp), &st) != -1) {
730 unsigned long size = (unsigned long) st.st_size;
731 if (st.st_size >= INT_MAX2147483647)
732 return;
733 if (size <= sizeof tb) tbp = tb;
734 else tbp = malloc (size);
735
736 if (tbp != NULL((void*)0)) {
737 while (parseline(fp, im, tbp, depth) >= 0) {}
738 if (tbp != tb) free (tbp);
739 }
740 }
741}