Bug Summary

File:xkbcomp.c
Location:line 1044, column 35
Description:Access to field 'flags' results in a dereference of a null pointer (loaded from field 'xkb')

Annotated Source Code

1/************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27#include <stdio.h>
28#include <ctype.h>
29#include <X11/keysym.h>
30
31/* for symlink attack security fix -- Branden Robinson */
32#include <sys/stat.h>
33#include <sys/types.h>
34#include <unistd.h>
35/* end BR */
36
37#if defined(sgi)
38#include <malloc.h>
39#endif
40
41#define DEBUG_VARdebugFlags debugFlags
42#include "xkbcomp.h"
43#include <stdlib.h>
44#include "xkbpath.h"
45#include "parseutils.h"
46#include "misc.h"
47#include "tokens.h"
48#include <X11/extensions/XKBgeom.h>
49
50
51#ifdef WIN32
52#define S_IRGRP0000040 0
53#define S_IWGRP0000020 0
54#define S_IROTH0000004 0
55#define S_IWOTH0000002 0
56#endif
57
58#define lowbit(x)((x) & (-(x))) ((x) & (-(x)))
59
60/***====================================================================***/
61
62#define WANT_DEFAULT0 0
63#define WANT_XKM_FILE1 1
64#define WANT_C_HDR2 2
65#define WANT_XKB_FILE3 3
66#define WANT_X_SERVER4 4
67#define WANT_LISTING5 5
68
69#define INPUT_UNKNOWN0 0
70#define INPUT_XKB1 1
71#define INPUT_XKM2 2
72
73unsigned int debugFlags;
74
75static const char *fileTypeExt[] = {
76 "XXX",
77 "xkm",
78 "h",
79 "xkb",
80 "dir"
81};
82
83static unsigned inputFormat, outputFormat;
84char *rootDir;
85static char *inputFile;
86static char *inputMap;
87static char *outputFile;
88static char *inDpyName;
89static char *outDpyName;
90static Display *inDpy;
91static Display *outDpy;
92static Boolint showImplicit = False0;
93static Boolint synch = False0;
94static Boolint computeDflts = False0;
95static Boolint xkblist = False0;
96unsigned warningLevel = 5;
97unsigned verboseLevel = 0;
98unsigned dirsToStrip = 0;
99unsigned optionalParts = 0;
100static char *preErrorMsg = NULL((void*)0);
101static char *postErrorMsg = NULL((void*)0);
102static char *errorPrefix = NULL((void*)0);
103static unsigned int device_id = XkbUseCoreKbd0x0100;
104
105/***====================================================================***/
106
107#define M(m)fprintf(__stderrp,(m)) fprintf(stderr__stderrp,(m))
108#define M1(m,a)fprintf(__stderrp,(m),(a)) fprintf(stderr__stderrp,(m),(a))
109
110static void
111Usage(int argc, char *argv[])
112{
113 if (!xkblist)
114 M1("Usage: %s [options] input-file [ output-file ]\n", argv[0])fprintf(__stderrp,("Usage: %s [options] input-file [ output-file ]\n"
),(argv[0]))
;
115 else
116 M1("Usage: %s [options] file[(map)] ...\n", argv[0])fprintf(__stderrp,("Usage: %s [options] file[(map)] ...\n"),(
argv[0]))
;
117 M("Legal options:\n")fprintf(__stderrp,("Legal options:\n"));
118 M("-?,-help Print this message\n")fprintf(__stderrp,("-?,-help Print this message\n"
))
;
119 M("-version Print the version number\n")fprintf(__stderrp,("-version Print the version number\n"
))
;
120 if (!xkblist)
121 {
122 M("-a Show all actions\n")fprintf(__stderrp,("-a Show all actions\n")
)
;
123 M("-C Create a C header file\n")fprintf(__stderrp,("-C Create a C header file\n"
))
;
124 }
125#ifdef DEBUG
126 M("-d [flags] Report debugging information\n")fprintf(__stderrp,("-d [flags] Report debugging information\n"
))
;
127#endif
128 M("-em1 <msg> Print <msg> before printing first error message\n")fprintf(__stderrp,("-em1 <msg> Print <msg> before printing first error message\n"
))
;
129 M("-emp <msg> Print <msg> at the start of each message line\n")fprintf(__stderrp,("-emp <msg> Print <msg> at the start of each message line\n"
))
;
130 M("-eml <msg> If there were any errors, print <msg> before exiting\n")fprintf(__stderrp,("-eml <msg> If there were any errors, print <msg> before exiting\n"
))
;
131 if (!xkblist)
132 {
133 M("-dflts Compute defaults for missing parts\n")fprintf(__stderrp,("-dflts Compute defaults for missing parts\n"
))
;
134 M("-I[<dir>] Specifies a top level directory for include\n")fprintf(__stderrp,("-I[<dir>] Specifies a top level directory for include\n"
))
;
135 M(" directives. Multiple directories are legal.\n")fprintf(__stderrp,(" directives. Multiple directories are legal.\n"
))
;
136 M("-l [flags] List matching maps in the specified files\n")fprintf(__stderrp,("-l [flags] List matching maps in the specified files\n"
))
;
137 M(" f: list fully specified names\n")fprintf(__stderrp,(" f: list fully specified names\n"
))
;
138 M(" h: also list hidden maps\n")fprintf(__stderrp,(" h: also list hidden maps\n"
))
;
139 M(" l: long listing (show flags)\n")fprintf(__stderrp,(" l: long listing (show flags)\n"
))
;
140 M(" p: also list partial maps\n")fprintf(__stderrp,(" p: also list partial maps\n"
))
;
141 M(" R: recursively list subdirectories\n")fprintf(__stderrp,(" R: recursively list subdirectories\n"
))
;
142 M(" default is all options off\n")fprintf(__stderrp,(" default is all options off\n"
))
;
143 }
144 M("-i <deviceid> Specifies device ID (not name) to compile for\n")fprintf(__stderrp,("-i <deviceid> Specifies device ID (not name) to compile for\n"
))
;
145 M("-m[ap] <map> Specifies map to compile\n")fprintf(__stderrp,("-m[ap] <map> Specifies map to compile\n"
))
;
146 M("-o <file> Specifies output file name\n")fprintf(__stderrp,("-o <file> Specifies output file name\n"
))
;
147 if (!xkblist)
148 {
149 M("-opt[ional] <parts> Specifies optional components of keymap\n")fprintf(__stderrp,("-opt[ional] <parts> Specifies optional components of keymap\n"
))
;
150 M(" Errors in optional parts are not fatal\n")fprintf(__stderrp,(" Errors in optional parts are not fatal\n"
))
;
151 M(" <parts> can be any combination of:\n")fprintf(__stderrp,(" <parts> can be any combination of:\n"
))
;
152 M(" c: compat map g: geometry\n")fprintf(__stderrp,(" c: compat map g: geometry\n"
))
;
153 M(" k: keycodes s: symbols\n")fprintf(__stderrp,(" k: keycodes s: symbols\n"
))
;
154 M(" t: types\n")fprintf(__stderrp,(" t: types\n"));
155 }
156 if (xkblist)
157 {
158 M("-p <count> Specifies the number of slashes to be stripped\n")fprintf(__stderrp,("-p <count> Specifies the number of slashes to be stripped\n"
))
;
159 M(" from the front of the map name on output\n")fprintf(__stderrp,(" from the front of the map name on output\n"
))
;
160 }
161 M("-R[<DIR>] Specifies the root directory for\n")fprintf(__stderrp,("-R[<DIR>] Specifies the root directory for\n"
))
;
162 M(" relative path names\n")fprintf(__stderrp,(" relative path names\n"
))
;
163 M("-synch Force synchronization\n")fprintf(__stderrp,("-synch Force synchronization\n"
))
;
164 if (xkblist)
165 {
166 M("-v [<flags>] Set level of detail for listing.\n")fprintf(__stderrp,("-v [<flags>] Set level of detail for listing.\n"
))
;
167 M(" flags are as for the -l option\n")fprintf(__stderrp,(" flags are as for the -l option\n"
))
;
168 }
169 M("-w [<lvl>] Set warning level (0=none, 10=all)\n")fprintf(__stderrp,("-w [<lvl>] Set warning level (0=none, 10=all)\n"
))
;
170 if (!xkblist)
171 {
172 M("-xkb Create an XKB source (.xkb) file\n")fprintf(__stderrp,("-xkb Create an XKB source (.xkb) file\n"
))
;
173 M("-xkm Create a compiled key map (.xkm) file\n")fprintf(__stderrp,("-xkm Create a compiled key map (.xkm) file\n"
))
;
174 }
175 return;
176}
177
178/***====================================================================***/
179
180static void
181setVerboseFlags(char *str)
182{
183 for (; *str; str++)
184 {
185 switch (*str)
186 {
187 case 'f':
188 verboseLevel |= WantFullNames(1<<3);
189 break;
190 case 'h':
191 verboseLevel |= WantHiddenMaps(1<<2);
192 break;
193 case 'l':
194 verboseLevel |= WantLongListing(1<<0);
195 break;
196 case 'p':
197 verboseLevel |= WantPartialMaps(1<<1);
198 break;
199 case 'R':
200 verboseLevel |= ListRecursive(1<<4);
201 break;
202 default:
203 if (warningLevel > 4)
204 {
205 WARN1uWarning("Unknown verbose option \"%c\"\n", (unsigned int) *str);
206 ACTIONuAction("Ignored\n");
207 }
208 break;
209 }
210 }
211 return;
212}
213
214static Boolint
215parseArgs(int argc, char *argv[])
216{
217 register int i, tmp;
218
219 i = strlen(argv[0]);
220 tmp = strlen("xkblist");
221 if ((i >= tmp) && (strcmp(&argv[0][i - tmp], "xkblist") == 0))
222 {
223 xkblist = True1;
224 }
225 for (i = 1; i < argc; i++)
226 {
227 int itmp;
228 if ((argv[i][0] != '-') || (uStringEqual(argv[i], "-")((((argv[i])==((char *)((void*)0))||("-")==((char *)((void*)0
)))? (argv[i])!=("-"):strcmp(argv[i],"-"))==((Comparison)0))
))
229 {
230 if (!xkblist)
231 {
232 if (inputFile == NULL((void*)0))
233 inputFile = argv[i];
234 else if (outputFile == NULL((void*)0))
235 outputFile = argv[i];
236 else if (warningLevel > 0)
237 {
238 WARNuWarning("Too many file names on command line\n");
239 ACTION3uAction
240 ("Compiling %s, writing to %s, ignoring %s\n",
241 inputFile, outputFile, argv[i]);
242 }
243 }
244 else if (!AddMatchingFiles(argv[i]))
245 return False0;
246 }
247 else if ((strcmp(argv[i], "-?") == 0)
248 || (strcmp(argv[i], "-help") == 0))
249 {
250 Usage(argc, argv);
251 exit(0);
252 }
253 else if (strcmp(argv[i], "-version") == 0)
254 {
255 printf("xkbcomp %s\n", PACKAGE_VERSION"1.3.1");
256 exit(0);
257 } else if ((strcmp(argv[i], "-a") == 0) && (!xkblist))
258 {
259 showImplicit = True1;
260 }
261 else if ((strcmp(argv[i], "-C") == 0) && (!xkblist))
262 {
263 if ((outputFormat != WANT_DEFAULT0)
264 && (outputFormat != WANT_C_HDR2))
265 {
266 if (warningLevel > 0)
267 {
268 WARNuWarning("Multiple output file formats specified\n");
269 ACTION1uAction("\"%s\" flag ignored\n", argv[i]);
270 }
271 }
272 else
273 outputFormat = WANT_C_HDR2;
274 }
275#ifdef DEBUG
276 else if (strcmp(argv[i], "-d") == 0)
277 {
278 if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0])))
279 {
280 debugFlags = 1;
281 }
282 else
283 {
284 if (sscanf(argv[++i], "%i", &itmp) == 1)
285 debugFlags = itmp;
286 }
287 INFO1uInformation("Setting debug flags to %d\n", debugFlags);
288 }
289#endif
290 else if ((strcmp(argv[i], "-dflts") == 0) && (!xkblist))
291 {
292 computeDflts = True1;
293 }
294 else if (strcmp(argv[i], "-em1") == 0)
295 {
296 if (++i >= argc)
297 {
298 if (warningLevel > 0)
299 {
300 WARNuWarning("No pre-error message specified\n");
301 ACTIONuAction("Trailing \"-em1\" option ignored\n");
302 }
303 }
304 else if (preErrorMsg != NULL((void*)0))
305 {
306 if (warningLevel > 0)
307 {
308 WARNuWarning("Multiple pre-error messsages specified\n");
309 ACTION2uAction("Compiling %s, ignoring %s\n",
310 preErrorMsg, argv[i]);
311 }
312 }
313 else
314 preErrorMsg = argv[i];
315 }
316 else if (strcmp(argv[i], "-emp") == 0)
317 {
318 if (++i >= argc)
319 {
320 if (warningLevel > 0)
321 {
322 WARNuWarning("No error prefix specified\n");
323 ACTIONuAction("Trailing \"-emp\" option ignored\n");
324 }
325 }
326 else if (errorPrefix != NULL((void*)0))
327 {
328 if (warningLevel > 0)
329 {
330 WARNuWarning("Multiple error prefixes specified\n");
331 ACTION2uAction("Compiling %s, ignoring %s\n",
332 errorPrefix, argv[i]);
333 }
334 }
335 else
336 errorPrefix = argv[i];
337 }
338 else if (strcmp(argv[i], "-eml") == 0)
339 {
340 if (++i >= argc)
341 {
342 if (warningLevel > 0)
343 {
344 WARNuWarning("No post-error message specified\n");
345 ACTIONuAction("Trailing \"-eml\" option ignored\n");
346 }
347 }
348 else if (postErrorMsg != NULL((void*)0))
349 {
350 if (warningLevel > 0)
351 {
352 WARNuWarning("Multiple post-error messages specified\n");
353 ACTION2uAction("Compiling %s, ignoring %s\n",
354 postErrorMsg, argv[i]);
355 }
356 }
357 else
358 postErrorMsg = argv[i];
359 }
360 else if ((strncmp(argv[i], "-I", 2) == 0) && (!xkblist))
361 {
362 if (!XkbAddDirectoryToPath(&argv[i][2]))
363 {
364 ACTIONuAction("Exiting\n");
365 exit(1);
366 }
367 }
368 else if ((strncmp(argv[i], "-i", 2) == 0) && (!xkblist))
369 {
370 if (++i >= argc)
371 {
372 if (warningLevel > 0)
373 WARNuWarning("No device ID specified\n");
374 }
375 device_id = atoi(argv[i]);
376 }
377 else if ((strncmp(argv[i], "-l", 2) == 0) && (!xkblist))
378 {
379 if (outputFormat != WANT_DEFAULT0)
380 {
381 if (warningLevel > 0)
382 {
383 WARNuWarning("Multiple output file formats specified\n");
384 ACTION1uAction("\"%s\" flag ignored\n", argv[i]);
385 }
386 }
387 else
388 {
389 if (argv[i][2] != '\0')
390 setVerboseFlags(&argv[i][2]);
391 xkblist = True1;
392 if ((inputFile) && (!AddMatchingFiles(inputFile)))
393 return False0;
394 else
395 inputFile = NULL((void*)0);
396 if ((outputFile) && (!AddMatchingFiles(outputFile)))
397 return False0;
398 else
399 outputFile = NULL((void*)0);
400 }
401 }
402 else if ((strcmp(argv[i], "-m") == 0)
403 || (strcmp(argv[i], "-map") == 0))
404 {
405 if (++i >= argc)
406 {
407 if (warningLevel > 0)
408 {
409 WARNuWarning("No map name specified\n");
410 ACTION1uAction("Trailing \"%s\" option ignored\n", argv[i - 1]);
411 }
412 }
413 else if (xkblist)
414 {
415 if (!AddMapOnly(argv[i]))
416 return False0;
417 }
418 else if (inputMap != NULL((void*)0))
419 {
420 if (warningLevel > 0)
421 {
422 WARNuWarning("Multiple map names specified\n");
423 ACTION2uAction("Compiling %s, ignoring %s\n", inputMap, argv[i]);
424 }
425 }
426 else
427 inputMap = argv[i];
428 }
429 else if ((strcmp(argv[i], "-merge") == 0) && (!xkblist))
430 {
431 /* Ignored */
432 }
433 else if (strcmp(argv[i], "-o") == 0)
434 {
435 if (++i >= argc)
436 {
437 if (warningLevel > 0)
438 {
439 WARNuWarning("No output file specified\n");
440 ACTIONuAction("Trailing \"-o\" option ignored\n");
441 }
442 }
443 else if (outputFile != NULL((void*)0))
444 {
445 if (warningLevel > 0)
446 {
447 WARNuWarning("Multiple output files specified\n");
448 ACTION2uAction("Compiling %s, ignoring %s\n", outputFile,
449 argv[i]);
450 }
451 }
452 else
453 outputFile = argv[i];
454 }
455 else if (((strcmp(argv[i], "-opt") == 0)
456 || (strcmp(argv[i], "optional") == 0)) && (!xkblist))
457 {
458 if (++i >= argc)
459 {
460 if (warningLevel > 0)
461 {
462 WARNuWarning("No optional components specified\n");
463 ACTION1uAction("Trailing \"%s\" option ignored\n", argv[i - 1]);
464 }
465 }
466 else
467 {
468 char *tmp2;
469 for (tmp2 = argv[i]; (*tmp2 != '\0'); tmp2++)
470 {
471 switch (*tmp2)
472 {
473 case 'c':
474 case 'C':
475 optionalParts |= XkmCompatMapMask(1<<1);
476 break;
477 case 'g':
478 case 'G':
479 optionalParts |= XkmGeometryMask(1<<5);
480 break;
481 case 'k':
482 case 'K':
483 optionalParts |= XkmKeyNamesMask(1<<4);
484 break;
485 case 's':
486 case 'S':
487 optionalParts |= XkmSymbolsMask(1<<2);
488 break;
489 case 't':
490 case 'T':
491 optionalParts |= XkmTypesMask(1<<0);
492 break;
493 default:
494 if (warningLevel > 0)
495 {
496 WARN1uWarning
497 ("Illegal component for %s option\n",
498 argv[i - 1]);
499 ACTION1uAction
500 ("Ignoring unknown specifier \"%c\"\n",
501 (unsigned int) *tmp2);
502 }
503 break;
504 }
505 }
506 }
507 }
508 else if (strncmp(argv[i], "-p", 2) == 0)
509 {
510 if (isdigit(argv[i][2]))
511 {
512 if (sscanf(&argv[i][2], "%i", &itmp) == 1)
513 dirsToStrip = itmp;
514 }
515 else if ((i < (argc - 1)) && (isdigit(argv[i + 1][0])))
516 {
517 if (sscanf(argv[++i], "%i", &itmp) == 1)
518 dirsToStrip = itmp;
519 }
520 else
521 {
522 dirsToStrip = 0;
523 }
524 if (warningLevel > 5)
525 INFO1uInformation("Setting path count to %d\n", dirsToStrip);
526 }
527 else if (strncmp(argv[i], "-R", 2) == 0)
528 {
529 if (argv[i][2] == '\0')
530 {
531 if (warningLevel > 0)
532 {
533 WARNuWarning("No root directory specified\n");
534 ACTIONuAction("Ignoring -R option\n");
535 }
536 }
537 else if (rootDir != NULL((void*)0))
538 {
539 if (warningLevel > 0)
540 {
541 WARNuWarning("Multiple root directories specified\n");
542 ACTION2uAction("Using %s, ignoring %s\n", rootDir, argv[i]);
543 }
544 }
545 else
546 {
547 rootDir = &argv[i][2];
548 if (warningLevel > 8)
549 {
550 WARN1uWarning("Changing root directory to \"%s\"\n", rootDir);
551 }
552 if ((chdir(rootDir) < 0) && (warningLevel > 0))
553 {
554 WARN1uWarning("Couldn't change directory to \"%s\"\n", rootDir);
555 ACTIONuAction("Root directory (-R) option ignored\n");
556 rootDir = NULL((void*)0);
557 }
558 }
559 }
560 else if ((strcmp(argv[i], "-synch") == 0)
561 || (strcmp(argv[i], "-s") == 0))
562 {
563 synch = True1;
564 }
565 else if (strncmp(argv[i], "-v", 2) == 0)
566 {
567 char *str;
568 if (argv[i][2] != '\0')
569 str = &argv[i][2];
570 else if ((i < (argc - 1)) && (argv[i + 1][0] != '-'))
571 str = argv[++i];
572 else
573 str = NULL((void*)0);
574 if (str)
575 setVerboseFlags(str);
576 }
577 else if (strncmp(argv[i], "-w", 2) == 0)
578 {
579 unsigned long utmp;
580 char *tmp2;
581 /* If text is just after "-w" in the same word, then it must
582 * be a number and it is the warning level. Otherwise, if the
583 * next argument is a number, then it is the warning level,
584 * else the warning level is assumed to be 0.
585 */
586 if (argv[i][2] == '\0')
587 {
588 warningLevel = 0;
589 if (i < argc - 1)
590 {
591 utmp = strtoul(argv[i+1], &tmp2, 10);
592 if (argv[i+1][0] != '\0' && *tmp2 == '\0')
593 {
594 warningLevel = utmp > 10 ? 10 : utmp;
595 i++;
596 }
597 }
598 }
599 else
600 {
601 utmp = strtoul(&argv[i][2], &tmp2, 10);
602 if (*tmp2 == '\0')
603 warningLevel = utmp > 10 ? 10 : utmp;
604 else
605 {
606 ERROR1uError("Unknown flag \"%s\" on command line\n", argv[i]);
607 Usage(argc, argv);
608 return False0;
609 }
610 }
611 }
612 else if ((strcmp(argv[i], "-xkb") == 0) && (!xkblist))
613 {
614 if ((outputFormat != WANT_DEFAULT0)
615 && (outputFormat != WANT_XKB_FILE3))
616 {
617 if (warningLevel > 0)
618 {
619 WARNuWarning("Multiple output file formats specified\n");
620 ACTION1uAction("\"%s\" flag ignored\n", argv[i]);
621 }
622 }
623 else
624 outputFormat = WANT_XKB_FILE3;
625 }
626 else if ((strcmp(argv[i], "-xkm") == 0) && (!xkblist))
627 {
628 if ((outputFormat != WANT_DEFAULT0)
629 && (outputFormat != WANT_XKM_FILE1))
630 {
631 if (warningLevel > 0)
632 {
633 WARNuWarning("Multiple output file formats specified\n");
634 ACTION1uAction("\"%s\" flag ignored\n", argv[i]);
635 }
636 }
637 else
638 outputFormat = WANT_XKM_FILE1;
639 }
640 else
641 {
642 ERROR1uError("Unknown flag \"%s\" on command line\n", argv[i]);
643 Usage(argc, argv);
644 return False0;
645 }
646 }
647 if (xkblist)
648 inputFormat = INPUT_XKB1;
649 else if (inputFile == NULL((void*)0))
650 {
651 ERRORuError("No input file specified\n");
652 return False0;
653 }
654 else if (uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void*
)0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison
)0))
)
655 {
656 inputFormat = INPUT_XKB1;
657 }
658#ifndef WIN32
659 else if (strchr(inputFile, ':') == NULL((void*)0))
660 {
661#else
662 else if ((strchr(inputFile, ':') == NULL((void*)0)) || (strlen(inputFile) > 2 &&
663 isalpha(inputFile[0]) &&
664 inputFile[1] == ':'
665 && strchr(inputFile + 2,
666 ':') == NULL((void*)0)))
667 {
668#endif
669 int len;
670 len = strlen(inputFile);
671 if (inputFile[len - 1] == ')')
672 {
673 char *tmpstr;
674 if ((tmpstr = strchr(inputFile, '(')) != NULL((void*)0))
675 {
676 *tmpstr = '\0';
677 inputFile[len - 1] = '\0';
678 tmpstr++;
679 if (*tmpstr == '\0')
680 {
681 WARNuWarning("Empty map in filename\n");
682 ACTIONuAction("Ignored\n");
683 }
684 else if (inputMap == NULL((void*)0))
685 {
686 inputMap = uStringDup(tmpstr)((tmpstr) ? strdup(tmpstr) : ((void*)0));
687 }
688 else
689 {
690 WARNuWarning("Map specified in filename and with -m flag\n");
691 ACTION1uAction("map from name (\"%s\") ignored\n", tmpstr);
692 }
693 }
694 else
695 {
696 ERROR1uError("Illegal name \"%s\" for input file\n", inputFile);
697 return False0;
698 }
699 }
700 if ((len > 4) && (strcmp(&inputFile[len - 4], ".xkm") == 0))
701 {
702 inputFormat = INPUT_XKM2;
703 }
704 else
705 {
706 FILE *file;
707 file = fopen(inputFile, "r");
708 if (file)
709 {
710 if (XkmProbe(file))
711 inputFormat = INPUT_XKM2;
712 else
713 inputFormat = INPUT_XKB1;
714 fclose(file);
715 }
716 else
717 {
718 fprintf(stderr__stderrp, "Cannot open \"%s\" for reading\n",
719 inputFile);
720 return False0;
721 }
722 }
723 }
724 else
725 {
726 inDpyName = inputFile;
727 inputFile = NULL((void*)0);
728 inputFormat = INPUT_XKM2;
729 }
730
731 if (outputFormat == WANT_DEFAULT0)
732 {
733 if (xkblist)
734 outputFormat = WANT_LISTING5;
735 else if (inputFormat == INPUT_XKB1)
736 outputFormat = WANT_XKM_FILE1;
737 else
738 outputFormat = WANT_XKB_FILE3;
739 }
740 if ((outputFormat == WANT_LISTING5) && (inputFormat != INPUT_XKB1))
741 {
742 if (inputFile)
743 ERRORuError("Cannot generate a listing from a .xkm file (yet)\n");
744 else
745 ERRORuError("Cannot generate a listing from an X connection (yet)\n");
746 return False0;
747 }
748 if (xkblist)
749 {
750 if (outputFile == NULL((void*)0))
751 outputFile = uStringDup("-")(("-") ? strdup("-") : ((void*)0));
752 else if (strchr(outputFile, ':') != NULL((void*)0))
753 {
754 ERRORuError("Cannot write a listing to an X connection\n");
755 return False0;
756 }
757 }
758 else if ((!outputFile) && (inputFile) && uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void*
)0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison
)0))
)
759 {
760 int len = strlen("stdin") + strlen(fileTypeExt[outputFormat]) + 2;
761 outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char)));
762 if (outputFile == NULL((void*)0))
763 {
764 WSGOuInternalError("Cannot allocate space for output file name\n");
765 ACTIONuAction("Exiting\n");
766 exit(1);
767 }
768 snprintf(outputFile, len, "stdin.%s", fileTypeExt[outputFormat])__builtin___snprintf_chk (outputFile, len, 0, __builtin_object_size
(outputFile, 2 > 1 ? 1 : 0), "stdin.%s", fileTypeExt[outputFormat
])
;
769 }
770 else if ((outputFile == NULL((void*)0)) && (inputFile != NULL((void*)0)))
771 {
772 int len;
773 char *base, *ext;
774
775 if (inputMap == NULL((void*)0))
776 {
777 base = strrchr(inputFile, '/');
778 if (base == NULL((void*)0))
779 base = inputFile;
780 else
781 base++;
782 }
783 else
784 base = inputMap;
785
786 len = strlen(base) + strlen(fileTypeExt[outputFormat]) + 2;
787 outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char)));
788 if (outputFile == NULL((void*)0))
789 {
790 WSGOuInternalError("Cannot allocate space for output file name\n");
791 ACTIONuAction("Exiting\n");
792 exit(1);
793 }
794 ext = strrchr(base, '.');
795 if (ext == NULL((void*)0))
796 snprintf(outputFile, len, "%s.%s", base, fileTypeExt[outputFormat])__builtin___snprintf_chk (outputFile, len, 0, __builtin_object_size
(outputFile, 2 > 1 ? 1 : 0), "%s.%s", base, fileTypeExt[outputFormat
])
;
797 else
798 {
799 strcpy(outputFile, base)__builtin___strcpy_chk (outputFile, base, __builtin_object_size
(outputFile, 2 > 1 ? 1 : 0))
;
800 strcpy(&outputFile[ext - base + 1], fileTypeExt[outputFormat])__builtin___strcpy_chk (&outputFile[ext - base + 1], fileTypeExt
[outputFormat], __builtin_object_size (&outputFile[ext - base
+ 1], 2 > 1 ? 1 : 0))
;
801 }
802 }
803 else if (outputFile == NULL((void*)0))
804 {
805 int len;
806 char *ch, *name, buf[128];
807 if (inDpyName[0] == ':')
808 snprintf(name = buf, sizeof(buf), "server%s", inDpyName)__builtin___snprintf_chk (name = buf, sizeof(buf), 0, __builtin_object_size
(name = buf, 2 > 1 ? 1 : 0), "server%s", inDpyName)
;
809 else
810 name = inDpyName;
811
812 len = strlen(name) + strlen(fileTypeExt[outputFormat]) + 2;
813 outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char)));
814 if (outputFile == NULL((void*)0))
815 {
816 WSGOuInternalError("Cannot allocate space for output file name\n");
817 ACTIONuAction("Exiting\n");
818 exit(1);
819 }
820 strcpy(outputFile, name)__builtin___strcpy_chk (outputFile, name, __builtin_object_size
(outputFile, 2 > 1 ? 1 : 0))
;
821 for (ch = outputFile; (*ch) != '\0'; ch++)
822 {
823 if (*ch == ':')
824 *ch = '-';
825 else if (*ch == '.')
826 *ch = '_';
827 }
828 *ch++ = '.';
829 strcpy(ch, fileTypeExt[outputFormat])__builtin___strcpy_chk (ch, fileTypeExt[outputFormat], __builtin_object_size
(ch, 2 > 1 ? 1 : 0))
;
830 }
831#ifdef WIN32
832 else if (strlen(outputFile) > 2 &&
833 isalpha(outputFile[0]) &&
834 outputFile[1] == ':' && strchr(outputFile + 2, ':') == NULL((void*)0))
835 {
836 }
837#endif
838 else if (strchr(outputFile, ':') != NULL((void*)0))
839 {
840 outDpyName = outputFile;
841 outputFile = NULL((void*)0);
842 outputFormat = WANT_X_SERVER4;
843 }
844 return True1;
845}
846
847static Display *
848GetDisplay(char *program, char *dpyName)
849{
850 int mjr, mnr, error;
851 Display *dpy;
852
853 mjr = XkbMajorVersion1;
854 mnr = XkbMinorVersion0;
855 dpy = XkbOpenDisplay(dpyName, NULL((void*)0), NULL((void*)0), &mjr, &mnr, &error);
856 if (dpy == NULL((void*)0))
857 {
858 switch (error)
859 {
860 case XkbOD_BadLibraryVersion1:
861 INFO3uInformation("%s was compiled with XKB version %d.%02d\n",
862 program, XkbMajorVersion1, XkbMinorVersion0);
863 ERROR2uError("X library supports incompatible version %d.%02d\n",
864 mjr, mnr);
865 break;
866 case XkbOD_ConnectionRefused2:
867 ERROR1uError("Cannot open display \"%s\"\n", dpyName);
868 break;
869 case XkbOD_NonXkbServer3:
870 ERROR1uError("XKB extension not present on %s\n", dpyName);
871 break;
872 case XkbOD_BadServerVersion4:
873 INFO3uInformation("%s was compiled with XKB version %d.%02d\n",
874 program, XkbMajorVersion1, XkbMinorVersion0);
875 ERROR3uError("Server %s uses incompatible version %d.%02d\n",
876 dpyName, mjr, mnr);
877 break;
878 default:
879 WSGO1uInternalError("Unknown error %d from XkbOpenDisplay\n", error);
880 }
881 }
882 else if (synch)
883 XSynchronize(dpy, True1);
884 return dpy;
885}
886
887/***====================================================================***/
888
889#ifdef DEBUG
890extern int yydebug;
891#endif
892
893int
894main(int argc, char *argv[])
895{
896 FILE *file; /* input file (or stdin) */
897 XkbFile *rtrn;
898 XkbFile *mapToUse;
899 int ok;
900 XkbFileInfo result;
901 Statusint status;
902
903 scan_set_file(stdin__stdinp);
904 uSetDebugFile(NullString((char *)((void*)0)));
905 uSetErrorFile(NullString((char *)((void*)0)));
906
907 XkbInitIncludePath();
908 if (!parseArgs(argc, argv))
1
Taking false branch
909 exit(1);
910#ifdef DEBUG
911 if (debugFlags & 0x2)
912 yydebug = 1;
913#endif
914 if (preErrorMsg)
2
Assuming 'preErrorMsg' is null
3
Taking false branch
915 uSetPreErrorMessage(preErrorMsg);
916 if (errorPrefix)
4
Assuming 'errorPrefix' is null
5
Taking false branch
917 uSetErrorPrefix(errorPrefix);
918 if (postErrorMsg)
6
Assuming 'postErrorMsg' is null
7
Taking false branch
919 uSetPostErrorMessage(postErrorMsg);
920 file = NULL((void*)0);
921 XkbInitAtoms(NULL((void*)0));
922 XkbAddDefaultDirectoriesToPath();
923 if (xkblist)
8
Assuming 'xkblist' is 0
9
Taking false branch
924 {
925 Boolint gotSome;
926 gotSome = GenerateListing(outputFile);
927 if ((warningLevel > 7) && (!gotSome))
928 return -1;
929 return 0;
930 }
931 if (inputFile != NULL((void*)0))
10
Assuming 'inputFile' is not equal to null
11
Taking true branch
932 {
933 if (uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void*
)0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison
)0))
)
12
Taking false branch
934 {
935 file = stdin__stdinp;
936 inputFile = "stdin";
937 }
938 else
939 {
940 file = fopen(inputFile, "r");
941 }
942 }
943 else if (inDpyName != NULL((void*)0))
944 {
945 inDpy = GetDisplay(argv[0], inDpyName);
946 if (!inDpy)
947 {
948 ACTIONuAction("Exiting\n");
949 exit(1);
950 }
951 }
952 if (outDpyName != NULL((void*)0))
13
Assuming 'outDpyName' is equal to null
14
Taking false branch
953 {
954 outDpy = GetDisplay(argv[0], outDpyName);
955 if (!outDpy)
956 {
957 ACTIONuAction("Exiting\n");
958 exit(1);
959 }
960 }
961 if ((inDpy == NULL((void*)0)) && (outDpy == NULL((void*)0)))
15
Assuming 'inDpy' is not equal to null
962 {
963 int mjr, mnr;
964 mjr = XkbMajorVersion1;
965 mnr = XkbMinorVersion0;
966 if (!XkbLibraryVersion(&mjr, &mnr))
967 {
968 INFO3uInformation("%s was compiled with XKB version %d.%02d\n",
969 argv[0], XkbMajorVersion1, XkbMinorVersion0);
970 ERROR2uError("X library supports incompatible version %d.%02d\n",
971 mjr, mnr);
972 ACTIONuAction("Exiting\n");
973 exit(1);
974 }
975 }
976 if (file)
16
Assuming 'file' is non-null
17
Taking true branch
977 {
978 ok = True1;
979 setScanState(inputFile, 1);
980 if ((inputFormat == INPUT_XKB1) /* parse .xkb file */
18
Assuming 'inputFormat' is equal to 1
20
Taking true branch
981 && (XKBParseFile(file, &rtrn) && (rtrn != NULL((void*)0))))
19
Assuming 'rtrn' is not equal to null
982 {
983 fclose(file);
984 mapToUse = rtrn;
985 if (inputMap != NULL((void*)0)) /* map specified on cmdline? */
21
Assuming 'inputMap' is equal to null
22
Taking false branch
986 {
987 while ((mapToUse)
988 && (!uStringEqual(mapToUse->name, inputMap)((((mapToUse->name)==((char *)((void*)0))||(inputMap)==((char
*)((void*)0)))? (mapToUse->name)!=(inputMap):strcmp(mapToUse
->name,inputMap))==((Comparison)0))
))
989 {
990 mapToUse = (XkbFile *) mapToUse->common.next;
991 }
992 if (!mapToUse)
993 {
994 FATAL2uFatalError("No map named \"%s\" in \"%s\"\n",
995 inputMap, inputFile);
996 /* NOTREACHED */
997 }
998 }
999 else if (rtrn->common.next != NULL((void*)0))
23
Taking false branch
1000 {
1001 /* look for map with XkbLC_Default flag. */
1002 mapToUse = rtrn;
1003 for (; mapToUse; mapToUse = (XkbFile *) mapToUse->common.next)
1004 {
1005 if (mapToUse->flags & XkbLC_Default(1L << 1))
1006 break;
1007 }
1008 if (!mapToUse)
1009 {
1010 mapToUse = rtrn;
1011 if (warningLevel > 4)
1012 {
1013 WARN1uWarning
1014 ("No map specified, but \"%s\" has several\n",
1015 inputFile);
1016 ACTION1uAction
1017 ("Using the first defined map, \"%s\"\n",
1018 mapToUse->name);
1019 }
1020 }
1021 }
1022 bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result
), __builtin_object_size ((char *) &result, 0))
;
1023 result.type = mapToUse->type;
1024 if ((result.xkb = XkbAllocKeyboard()) == NULL((void*)0))
24
Value assigned to 'result.xkb'
25
Assuming pointer value is null
26
Taking true branch
1025 {
1026 WSGOuInternalError("Cannot allocate keyboard description\n");
1027 /* NOTREACHED */
1028 }
1029 switch (mapToUse->type)
27
Control jumps to 'case 2:' at line 1042
1030 {
1031 case XkmSemanticsFile20:
1032 case XkmLayoutFile21:
1033 case XkmKeymapFile22:
1034 ok = CompileKeymap(mapToUse, &result, MergeReplace3);
1035 break;
1036 case XkmKeyNamesIndex4:
1037 ok = CompileKeycodes(mapToUse, &result, MergeReplace3);
1038 break;
1039 case XkmTypesIndex0:
1040 ok = CompileKeyTypes(mapToUse, &result, MergeReplace3);
1041 break;
1042 case XkmSymbolsIndex2:
1043 /* if it's just symbols, invent key names */
1044 result.xkb->flags |= AutoKeyNames(1L << 0);
28
Access to field 'flags' results in a dereference of a null pointer (loaded from field 'xkb')
1045 ok = False0;
1046 break;
1047 case XkmCompatMapIndex1:
1048 ok = CompileCompatMap(mapToUse, &result, MergeReplace3, NULL((void*)0));
1049 break;
1050 case XkmGeometryFile23:
1051 case XkmGeometryIndex5:
1052 /* if it's just a geometry, invent key names */
1053 result.xkb->flags |= AutoKeyNames(1L << 0);
1054 ok = CompileGeometry(mapToUse, &result, MergeReplace3);
1055 break;
1056 default:
1057 WSGO1uInternalError("Unknown file type %d\n", mapToUse->type);
1058 ok = False0;
1059 break;
1060 }
1061 result.xkb->device_spec = device_id;
1062 }
1063 else if (inputFormat == INPUT_XKM2) /* parse xkm file */
1064 {
1065 unsigned tmp;
1066 bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result
), __builtin_object_size ((char *) &result, 0))
;
1067 if ((result.xkb = XkbAllocKeyboard()) == NULL((void*)0))
1068 {
1069 WSGOuInternalError("Cannot allocate keyboard description\n");
1070 /* NOTREACHED */
1071 }
1072 tmp = XkmReadFile(file, 0, XkmKeymapLegal((((1<<1))|((1<<4)|(1<<2)|(1<<0)))|((
((1<<0)|(1<<6)|(1<<3))|((1<<6)|(1<<
5)))&(~(((1<<1))|((1<<4)|(1<<2)|(1<<
0))))))
, &result);
1073 if (tmp == XkmKeymapLegal((((1<<1))|((1<<4)|(1<<2)|(1<<0)))|((
((1<<0)|(1<<6)|(1<<3))|((1<<6)|(1<<
5)))&(~(((1<<1))|((1<<4)|(1<<2)|(1<<
0))))))
)
1074 {
1075 ERROR1uError("Cannot read XKM file \"%s\"\n", inputFile);
1076 ok = False0;
1077 }
1078 result.xkb->device_spec = device_id;
1079 }
1080 else
1081 {
1082 INFO1uInformation("Errors encountered in %s; not compiled.\n", inputFile);
1083 ok = False0;
1084 }
1085 }
1086 else if (inDpy != NULL((void*)0))
1087 {
1088 bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result
), __builtin_object_size ((char *) &result, 0))
;
1089 result.type = XkmKeymapFile22;
1090 result.xkb = XkbGetMap(inDpy, XkbAllMapComponentsMask(((1<<0)|(1<<1)|(1<<2))|((1<<3)|(1<<
4)|(1<<5)|(1<<6)|(1<<7)))
, device_id);
1091 if (result.xkb == NULL((void*)0))
1092 WSGOuInternalError("Cannot load keyboard description\n");
1093 if (XkbGetIndicatorMap(inDpy, ~0, result.xkb) != Success0)
1094 WSGOuInternalError("Could not load indicator map\n");
1095 if (XkbGetControls(inDpy, XkbAllControlsMask(0xF8001FFF), result.xkb) != Success0)
1096 WSGOuInternalError("Could not load keyboard controls\n");
1097 if (XkbGetCompatMap(inDpy, XkbAllCompatMask(0x3), result.xkb) != Success0)
1098 WSGOuInternalError("Could not load compatibility map\n");
1099 if (XkbGetNames(inDpy, XkbAllNamesMask(0x3fff), result.xkb) != Success0)
1100 WSGOuInternalError("Could not load names\n");
1101 if ((status = XkbGetGeometry(inDpy, result.xkb)) != Success0)
1102 {
1103 if (warningLevel > 3)
1104 {
1105 char buf[100];
1106 buf[0] = '\0';
1107 XGetErrorText(inDpy, status, buf, 100);
1108 WARN1uWarning("Could not load keyboard geometry for %s\n", inDpyName);
1109 ACTION1uAction("%s\n", buf);
1110 ACTIONuAction("Resulting keymap file will not describe geometry\n");
1111 }
1112 }
1113 if (computeDflts)
1114 ok = (ComputeKbdDefaults(result.xkb) == Success0);
1115 else
1116 ok = True1;
1117 }
1118 else
1119 {
1120 fprintf(stderr__stderrp, "Cannot open \"%s\" to compile\n", inputFile);
1121 ok = 0;
1122 }
1123 if (ok)
1124 {
1125 FILE *out = stdout__stdoutp;
1126 if ((inDpy != outDpy) &&
1127 (XkbChangeKbdDisplay(outDpy, &result) != Success0))
1128 {
1129 WSGO2uInternalError("Error converting keyboard display from %s to %s\n",
1130 inDpyName, outDpyName);
1131 exit(1);
1132 }
1133 if (outputFile != NULL((void*)0))
1134 {
1135 if (uStringEqual(outputFile, "-")((((outputFile)==((char *)((void*)0))||("-")==((char *)((void
*)0)))? (outputFile)!=("-"):strcmp(outputFile,"-"))==((Comparison
)0))
)
1136 outputFile = "stdout";
1137 else
1138 {
1139 /*
1140 * fix to prevent symlink attack (e.g.,
1141 * ln -s /etc/passwd /var/tmp/server-0.xkm)
1142 */
1143 /*
1144 * this patch may have POSIX, Linux, or GNU libc bias
1145 * -- Branden Robinson
1146 */
1147 int outputFileFd;
1148 int binMode = 0;
1149 const char *openMode = "w";
1150 unlink(outputFile);
1151#ifdef O_BINARY
1152 switch (outputFormat)
1153 {
1154 case WANT_XKM_FILE1:
1155 binMode = O_BINARY;
1156 openMode = "wb";
1157 break;
1158 default:
1159 binMode = 0;
1160 break;
1161 }
1162#endif
1163 outputFileFd =
1164 open(outputFile, O_WRONLY0x0001 | O_CREAT0x0200 | O_EXCL0x0800,
1165 S_IRUSR0000400 | S_IWUSR0000200 | S_IRGRP0000040 | S_IWGRP0000020 | S_IROTH0000004
1166 | S_IWOTH0000002 | binMode);
1167 if (outputFileFd < 0)
1168 {
1169 ERROR1uError
1170 ("Cannot open \"%s\" to write keyboard description\n",
1171 outputFile);
1172 ACTIONuAction("Exiting\n");
1173 exit(1);
1174 }
1175#ifndef WIN32
1176 out = fdopen(outputFileFd, openMode);
1177#else
1178 close(outputFileFd);
1179 out = fopen(outputFile, "wb");
1180#endif
1181 /* end BR */
1182 if (out == NULL((void*)0))
1183 {
1184 ERROR1uError
1185 ("Cannot open \"%s\" to write keyboard description\n",
1186 outputFile);
1187 ACTIONuAction("Exiting\n");
1188 exit(1);
1189 }
1190 }
1191 }
1192 switch (outputFormat)
1193 {
1194 case WANT_XKM_FILE1:
1195 ok = XkbWriteXKMFile(out, &result);
1196 break;
1197 case WANT_XKB_FILE3:
1198 ok = XkbWriteXKBFile(out, &result, showImplicit, NULL((void*)0), NULL((void*)0));
1199 break;
1200 case WANT_C_HDR2:
1201 ok = XkbWriteCFile(out, outputFile, &result);
1202 break;
1203 case WANT_X_SERVER4:
1204 if (!(ok = XkbWriteToServer(&result)))
1205 {
1206 ERROR2uError("%s in %s\n", _XkbErrMessages[_XkbErrCode],
1207 _XkbErrLocation ? _XkbErrLocation : "unknown");
1208 ACTION1uAction("Couldn't write keyboard description to %s\n",
1209 outDpyName);
1210 }
1211 break;
1212 default:
1213 WSGO1uInternalError("Unknown output format %d\n", outputFormat);
1214 ACTIONuAction("No output file created\n");
1215 ok = False0;
1216 break;
1217 }
1218 if (outputFormat != WANT_X_SERVER4)
1219 {
1220 if (fclose(out))
1221 {
1222 ERROR1uError("Cannot close \"%s\" properly (not enough space?)\n",
1223 outputFile);
1224 ok= False0;
1225 }
1226 else if (!ok)
1227 {
1228 ERROR2uError("%s in %s\n", _XkbErrMessages[_XkbErrCode],
1229 _XkbErrLocation ? _XkbErrLocation : "unknown");
1230 }
1231 if (!ok)
1232 {
1233 ACTION1uAction("Output file \"%s\" removed\n", outputFile);
1234 unlink(outputFile);
1235 }
1236 }
1237 }
1238 if (inDpy)
1239 XCloseDisplay(inDpy);
1240 inDpy = NULL((void*)0);
1241 if (outDpy)
1242 XCloseDisplay(outDpy);
1243 uFinishUp();
1244 return (ok == 0);
1245}