diff options
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/ChangeLog | 7 | ||||
| -rw-r--r-- | lib-src/etags.c | 44 |
2 files changed, 41 insertions, 10 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index d056b1a4b81..8d46a37ce51 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog | |||
| @@ -19,6 +19,13 @@ | |||
| 19 | result might not fit in 'int'. | 19 | result might not fit in 'int'. |
| 20 | (set_local_socket): Do not assume uid fits in 'int'. | 20 | (set_local_socket): Do not assume uid fits in 'int'. |
| 21 | 21 | ||
| 22 | * etags.c (xmalloc, xrealloc): Accept size_t, not unsigned int, | ||
| 23 | to avoid potential buffer overflow issues on typical 64-bit hosts. | ||
| 24 | (whatlen_max): New static var. | ||
| 25 | (main): Avoid buffer overflow if subsidiary command length is | ||
| 26 | greater than BUFSIZ or 2*BUFSIZ + 20. Do not use sprintf when its | ||
| 27 | result might not fit in 'int'. | ||
| 28 | |||
| 22 | 2011-07-28 Paul Eggert <eggert@cs.ucla.edu> | 29 | 2011-07-28 Paul Eggert <eggert@cs.ucla.edu> |
| 23 | 30 | ||
| 24 | Assume freestanding C89 headers, string.h, stdlib.h. | 31 | Assume freestanding C89 headers, string.h, stdlib.h. |
diff --git a/lib-src/etags.c b/lib-src/etags.c index 522c54ee4a5..9d920565804 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -414,8 +414,8 @@ static bool filename_is_absolute (char *f); | |||
| 414 | static void canonicalize_filename (char *); | 414 | static void canonicalize_filename (char *); |
| 415 | static void linebuffer_init (linebuffer *); | 415 | static void linebuffer_init (linebuffer *); |
| 416 | static void linebuffer_setlen (linebuffer *, int); | 416 | static void linebuffer_setlen (linebuffer *, int); |
| 417 | static PTR xmalloc (unsigned int); | 417 | static PTR xmalloc (size_t); |
| 418 | static PTR xrealloc (char *, unsigned int); | 418 | static PTR xrealloc (char *, size_t); |
| 419 | 419 | ||
| 420 | 420 | ||
| 421 | static char searchar = '/'; /* use /.../ searches */ | 421 | static char searchar = '/'; /* use /.../ searches */ |
| @@ -425,6 +425,7 @@ static char *progname; /* name this program was invoked with */ | |||
| 425 | static char *cwd; /* current working directory */ | 425 | static char *cwd; /* current working directory */ |
| 426 | static char *tagfiledir; /* directory of tagfile */ | 426 | static char *tagfiledir; /* directory of tagfile */ |
| 427 | static FILE *tagf; /* ioptr for tags file */ | 427 | static FILE *tagf; /* ioptr for tags file */ |
| 428 | static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */ | ||
| 428 | 429 | ||
| 429 | static fdesc *fdhead; /* head of file description list */ | 430 | static fdesc *fdhead; /* head of file description list */ |
| 430 | static fdesc *curfdp; /* current file description */ | 431 | static fdesc *curfdp; /* current file description */ |
| @@ -1066,6 +1067,7 @@ main (int argc, char **argv) | |||
| 1066 | int current_arg, file_count; | 1067 | int current_arg, file_count; |
| 1067 | linebuffer filename_lb; | 1068 | linebuffer filename_lb; |
| 1068 | bool help_asked = FALSE; | 1069 | bool help_asked = FALSE; |
| 1070 | ptrdiff_t len; | ||
| 1069 | char *optstring; | 1071 | char *optstring; |
| 1070 | int opt; | 1072 | int opt; |
| 1071 | 1073 | ||
| @@ -1110,6 +1112,9 @@ main (int argc, char **argv) | |||
| 1110 | /* This means that a file name has been seen. Record it. */ | 1112 | /* This means that a file name has been seen. Record it. */ |
| 1111 | argbuffer[current_arg].arg_type = at_filename; | 1113 | argbuffer[current_arg].arg_type = at_filename; |
| 1112 | argbuffer[current_arg].what = optarg; | 1114 | argbuffer[current_arg].what = optarg; |
| 1115 | len = strlen (optarg); | ||
| 1116 | if (whatlen_max < len) | ||
| 1117 | whatlen_max = len; | ||
| 1113 | ++current_arg; | 1118 | ++current_arg; |
| 1114 | ++file_count; | 1119 | ++file_count; |
| 1115 | break; | 1120 | break; |
| @@ -1118,6 +1123,9 @@ main (int argc, char **argv) | |||
| 1118 | /* Parse standard input. Idea by Vivek <vivek@etla.org>. */ | 1123 | /* Parse standard input. Idea by Vivek <vivek@etla.org>. */ |
| 1119 | argbuffer[current_arg].arg_type = at_stdin; | 1124 | argbuffer[current_arg].arg_type = at_stdin; |
| 1120 | argbuffer[current_arg].what = optarg; | 1125 | argbuffer[current_arg].what = optarg; |
| 1126 | len = strlen (optarg); | ||
| 1127 | if (whatlen_max < len) | ||
| 1128 | whatlen_max = len; | ||
| 1121 | ++current_arg; | 1129 | ++current_arg; |
| 1122 | ++file_count; | 1130 | ++file_count; |
| 1123 | if (parsing_stdin) | 1131 | if (parsing_stdin) |
| @@ -1160,6 +1168,9 @@ main (int argc, char **argv) | |||
| 1160 | case 'r': | 1168 | case 'r': |
| 1161 | argbuffer[current_arg].arg_type = at_regexp; | 1169 | argbuffer[current_arg].arg_type = at_regexp; |
| 1162 | argbuffer[current_arg].what = optarg; | 1170 | argbuffer[current_arg].what = optarg; |
| 1171 | len = strlen (optarg); | ||
| 1172 | if (whatlen_max < len) | ||
| 1173 | whatlen_max = len; | ||
| 1163 | ++current_arg; | 1174 | ++current_arg; |
| 1164 | break; | 1175 | break; |
| 1165 | case 'R': | 1176 | case 'R': |
| @@ -1198,6 +1209,9 @@ main (int argc, char **argv) | |||
| 1198 | { | 1209 | { |
| 1199 | argbuffer[current_arg].arg_type = at_filename; | 1210 | argbuffer[current_arg].arg_type = at_filename; |
| 1200 | argbuffer[current_arg].what = argv[optind]; | 1211 | argbuffer[current_arg].what = argv[optind]; |
| 1212 | len = strlen (argv[optind]); | ||
| 1213 | if (whatlen_max < len) | ||
| 1214 | whatlen_max = len; | ||
| 1201 | ++current_arg; | 1215 | ++current_arg; |
| 1202 | ++file_count; | 1216 | ++file_count; |
| 1203 | } | 1217 | } |
| @@ -1331,7 +1345,9 @@ main (int argc, char **argv) | |||
| 1331 | /* From here on, we are in (CTAGS && !cxref_style) */ | 1345 | /* From here on, we are in (CTAGS && !cxref_style) */ |
| 1332 | if (update) | 1346 | if (update) |
| 1333 | { | 1347 | { |
| 1334 | char cmd[BUFSIZ]; | 1348 | char *cmd = |
| 1349 | xmalloc (strlen (tagfile) + whatlen_max + | ||
| 1350 | sizeof "mv..OTAGS;fgrep -v '\t\t' OTAGS >;rm OTAGS"); | ||
| 1335 | for (i = 0; i < current_arg; ++i) | 1351 | for (i = 0; i < current_arg; ++i) |
| 1336 | { | 1352 | { |
| 1337 | switch (argbuffer[i].arg_type) | 1353 | switch (argbuffer[i].arg_type) |
| @@ -1342,12 +1358,17 @@ main (int argc, char **argv) | |||
| 1342 | default: | 1358 | default: |
| 1343 | continue; /* the for loop */ | 1359 | continue; /* the for loop */ |
| 1344 | } | 1360 | } |
| 1345 | sprintf (cmd, | 1361 | strcpy (cmd, "mv "); |
| 1346 | "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", | 1362 | strcat (cmd, tagfile); |
| 1347 | tagfile, argbuffer[i].what, tagfile); | 1363 | strcat (cmd, " OTAGS;fgrep -v '\t"); |
| 1364 | strcat (cmd, argbuffer[i].what); | ||
| 1365 | strcat (cmd, "\t' OTAGS >"); | ||
| 1366 | strcat (cmd, tagfile); | ||
| 1367 | strcat (cmd, ";rm OTAGS"); | ||
| 1348 | if (system (cmd) != EXIT_SUCCESS) | 1368 | if (system (cmd) != EXIT_SUCCESS) |
| 1349 | fatal ("failed to execute shell command", (char *)NULL); | 1369 | fatal ("failed to execute shell command", (char *)NULL); |
| 1350 | } | 1370 | } |
| 1371 | free (cmd); | ||
| 1351 | append_to_tagfile = TRUE; | 1372 | append_to_tagfile = TRUE; |
| 1352 | } | 1373 | } |
| 1353 | 1374 | ||
| @@ -1363,11 +1384,14 @@ main (int argc, char **argv) | |||
| 1363 | if (CTAGS) | 1384 | if (CTAGS) |
| 1364 | if (append_to_tagfile || update) | 1385 | if (append_to_tagfile || update) |
| 1365 | { | 1386 | { |
| 1366 | char cmd[2*BUFSIZ+20]; | 1387 | char *cmd = xmalloc (2 * strlen (tagfile) + sizeof "sort -u -o.."); |
| 1367 | /* Maybe these should be used: | 1388 | /* Maybe these should be used: |
| 1368 | setenv ("LC_COLLATE", "C", 1); | 1389 | setenv ("LC_COLLATE", "C", 1); |
| 1369 | setenv ("LC_ALL", "C", 1); */ | 1390 | setenv ("LC_ALL", "C", 1); */ |
| 1370 | sprintf (cmd, "sort -u -o %.*s %.*s", BUFSIZ, tagfile, BUFSIZ, tagfile); | 1391 | strcpy (cmd, "sort -u -o "); |
| 1392 | strcat (cmd, tagfile); | ||
| 1393 | strcat (cmd, " "); | ||
| 1394 | strcat (cmd, tagfile); | ||
| 1371 | exit (system (cmd)); | 1395 | exit (system (cmd)); |
| 1372 | } | 1396 | } |
| 1373 | return EXIT_SUCCESS; | 1397 | return EXIT_SUCCESS; |
| @@ -6656,7 +6680,7 @@ linebuffer_setlen (linebuffer *lbp, int toksize) | |||
| 6656 | 6680 | ||
| 6657 | /* Like malloc but get fatal error if memory is exhausted. */ | 6681 | /* Like malloc but get fatal error if memory is exhausted. */ |
| 6658 | static PTR | 6682 | static PTR |
| 6659 | xmalloc (unsigned int size) | 6683 | xmalloc (size_t size) |
| 6660 | { | 6684 | { |
| 6661 | PTR result = (PTR) malloc (size); | 6685 | PTR result = (PTR) malloc (size); |
| 6662 | if (result == NULL) | 6686 | if (result == NULL) |
| @@ -6665,7 +6689,7 @@ xmalloc (unsigned int size) | |||
| 6665 | } | 6689 | } |
| 6666 | 6690 | ||
| 6667 | static PTR | 6691 | static PTR |
| 6668 | xrealloc (char *ptr, unsigned int size) | 6692 | xrealloc (char *ptr, size_t size) |
| 6669 | { | 6693 | { |
| 6670 | PTR result = (PTR) realloc (ptr, size); | 6694 | PTR result = (PTR) realloc (ptr, size); |
| 6671 | if (result == NULL) | 6695 | if (result == NULL) |