aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/ChangeLog7
-rw-r--r--lib-src/etags.c44
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
222011-07-28 Paul Eggert <eggert@cs.ucla.edu> 292011-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);
414static void canonicalize_filename (char *); 414static void canonicalize_filename (char *);
415static void linebuffer_init (linebuffer *); 415static void linebuffer_init (linebuffer *);
416static void linebuffer_setlen (linebuffer *, int); 416static void linebuffer_setlen (linebuffer *, int);
417static PTR xmalloc (unsigned int); 417static PTR xmalloc (size_t);
418static PTR xrealloc (char *, unsigned int); 418static PTR xrealloc (char *, size_t);
419 419
420 420
421static char searchar = '/'; /* use /.../ searches */ 421static char searchar = '/'; /* use /.../ searches */
@@ -425,6 +425,7 @@ static char *progname; /* name this program was invoked with */
425static char *cwd; /* current working directory */ 425static char *cwd; /* current working directory */
426static char *tagfiledir; /* directory of tagfile */ 426static char *tagfiledir; /* directory of tagfile */
427static FILE *tagf; /* ioptr for tags file */ 427static FILE *tagf; /* ioptr for tags file */
428static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */
428 429
429static fdesc *fdhead; /* head of file description list */ 430static fdesc *fdhead; /* head of file description list */
430static fdesc *curfdp; /* current file description */ 431static 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. */
6658static PTR 6682static PTR
6659xmalloc (unsigned int size) 6683xmalloc (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
6667static PTR 6691static PTR
6668xrealloc (char *ptr, unsigned int size) 6692xrealloc (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)