diff options
| author | Paul Eggert | 2011-06-19 12:06:16 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-19 12:06:16 -0700 |
| commit | 93f4cf88953806d319e6ab231b4d1332a227d645 (patch) | |
| tree | 2f50262a2c036ac1ee277512b15aacf0363b7eb2 /src | |
| parent | f3e92b69d2fa865d82793ac41370045a85beb269 (diff) | |
| download | emacs-93f4cf88953806d319e6ab231b4d1332a227d645.tar.gz emacs-93f4cf88953806d319e6ab231b4d1332a227d645.zip | |
* fileio.c: Fix some integer overflow issues.
(file_name_as_directory, Fexpand_file_name, Fsubstitute_in_file_name):
Don't assume string length fits in int.
(directory_file_name): Don't assume string length fits in long.
(make_temp_name): Don't assume pid fits in int, or that its print
length is less than 20.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/fileio.c | 35 |
2 files changed, 24 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index e5d7a81792e..3687da81fbb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,12 @@ | |||
| 1 | 2011-06-19 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-06-19 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | * fileio.c: Fix some integer overflow issues. | ||
| 4 | (file_name_as_directory, Fexpand_file_name, Fsubstitute_in_file_name): | ||
| 5 | Don't assume string length fits in int. | ||
| 6 | (directory_file_name): Don't assume string length fits in long. | ||
| 7 | (make_temp_name): Don't assume pid fits in int, or that its print | ||
| 8 | length is less than 20. | ||
| 9 | |||
| 3 | * data.c (Fsubr_name): Rewrite to avoid a strlen call. | 10 | * data.c (Fsubr_name): Rewrite to avoid a strlen call. |
| 4 | 11 | ||
| 5 | * coding.c (make_subsidiaries): Don't assume string length fits in int. | 12 | * coding.c (make_subsidiaries): Don't assume string length fits in int. |
diff --git a/src/fileio.c b/src/fileio.c index dd34872c263..824df8172e7 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -440,11 +440,9 @@ get a current directory to run processes in. */) | |||
| 440 | static char * | 440 | static char * |
| 441 | file_name_as_directory (char *out, const char *in) | 441 | file_name_as_directory (char *out, const char *in) |
| 442 | { | 442 | { |
| 443 | int size = strlen (in) - 1; | 443 | ptrdiff_t len = strlen (in); |
| 444 | 444 | ||
| 445 | strcpy (out, in); | 445 | if (len == 0) |
| 446 | |||
| 447 | if (size < 0) | ||
| 448 | { | 446 | { |
| 449 | out[0] = '.'; | 447 | out[0] = '.'; |
| 450 | out[1] = '/'; | 448 | out[1] = '/'; |
| @@ -452,11 +450,13 @@ file_name_as_directory (char *out, const char *in) | |||
| 452 | return out; | 450 | return out; |
| 453 | } | 451 | } |
| 454 | 452 | ||
| 453 | strcpy (out, in); | ||
| 454 | |||
| 455 | /* For Unix syntax, Append a slash if necessary */ | 455 | /* For Unix syntax, Append a slash if necessary */ |
| 456 | if (!IS_DIRECTORY_SEP (out[size])) | 456 | if (!IS_DIRECTORY_SEP (out[len - 1])) |
| 457 | { | 457 | { |
| 458 | out[size + 1] = DIRECTORY_SEP; | 458 | out[len] = DIRECTORY_SEP; |
| 459 | out[size + 2] = '\0'; | 459 | out[len + 1] = '\0'; |
| 460 | } | 460 | } |
| 461 | #ifdef DOS_NT | 461 | #ifdef DOS_NT |
| 462 | dostounix_filename (out); | 462 | dostounix_filename (out); |
| @@ -503,7 +503,7 @@ For a Unix-syntax file name, just appends a slash. */) | |||
| 503 | static int | 503 | static int |
| 504 | directory_file_name (char *src, char *dst) | 504 | directory_file_name (char *src, char *dst) |
| 505 | { | 505 | { |
| 506 | long slen; | 506 | ptrdiff_t slen; |
| 507 | 507 | ||
| 508 | slen = strlen (src); | 508 | slen = strlen (src); |
| 509 | 509 | ||
| @@ -587,9 +587,9 @@ make_temp_name (Lisp_Object prefix, int base64_p) | |||
| 587 | { | 587 | { |
| 588 | Lisp_Object val; | 588 | Lisp_Object val; |
| 589 | int len, clen; | 589 | int len, clen; |
| 590 | int pid; | 590 | intmax_t pid; |
| 591 | char *p, *data; | 591 | char *p, *data; |
| 592 | char pidbuf[20]; | 592 | char pidbuf[INT_BUFSIZE_BOUND (pid_t)]; |
| 593 | int pidlen; | 593 | int pidlen; |
| 594 | 594 | ||
| 595 | CHECK_STRING (prefix); | 595 | CHECK_STRING (prefix); |
| @@ -599,7 +599,7 @@ make_temp_name (Lisp_Object prefix, int base64_p) | |||
| 599 | three are incremented if the file already exists. This ensures | 599 | three are incremented if the file already exists. This ensures |
| 600 | 262144 unique file names per PID per PREFIX. */ | 600 | 262144 unique file names per PID per PREFIX. */ |
| 601 | 601 | ||
| 602 | pid = (int) getpid (); | 602 | pid = getpid (); |
| 603 | 603 | ||
| 604 | if (base64_p) | 604 | if (base64_p) |
| 605 | { | 605 | { |
| @@ -611,8 +611,7 @@ make_temp_name (Lisp_Object prefix, int base64_p) | |||
| 611 | else | 611 | else |
| 612 | { | 612 | { |
| 613 | #ifdef HAVE_LONG_FILE_NAMES | 613 | #ifdef HAVE_LONG_FILE_NAMES |
| 614 | sprintf (pidbuf, "%d", pid); | 614 | pidlen = sprintf (pidbuf, "%"PRIdMAX, pid); |
| 615 | pidlen = strlen (pidbuf); | ||
| 616 | #else | 615 | #else |
| 617 | pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6; | 616 | pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6; |
| 618 | pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6; | 617 | pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6; |
| @@ -737,14 +736,14 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 737 | /* This should only point to alloca'd data. */ | 736 | /* This should only point to alloca'd data. */ |
| 738 | char *target; | 737 | char *target; |
| 739 | 738 | ||
| 740 | int tlen; | 739 | ptrdiff_t tlen; |
| 741 | struct passwd *pw; | 740 | struct passwd *pw; |
| 742 | #ifdef DOS_NT | 741 | #ifdef DOS_NT |
| 743 | int drive = 0; | 742 | int drive = 0; |
| 744 | int collapse_newdir = 1; | 743 | int collapse_newdir = 1; |
| 745 | int is_escaped = 0; | 744 | int is_escaped = 0; |
| 746 | #endif /* DOS_NT */ | 745 | #endif /* DOS_NT */ |
| 747 | int length; | 746 | ptrdiff_t length; |
| 748 | Lisp_Object handler, result; | 747 | Lisp_Object handler, result; |
| 749 | int multibyte; | 748 | int multibyte; |
| 750 | Lisp_Object hdir; | 749 | Lisp_Object hdir; |
| @@ -1314,7 +1313,7 @@ See also the function `substitute-in-file-name'.") | |||
| 1314 | unsigned char *nm; | 1313 | unsigned char *nm; |
| 1315 | 1314 | ||
| 1316 | register unsigned char *newdir, *p, *o; | 1315 | register unsigned char *newdir, *p, *o; |
| 1317 | int tlen; | 1316 | ptrdiff_t tlen; |
| 1318 | unsigned char *target; | 1317 | unsigned char *target; |
| 1319 | struct passwd *pw; | 1318 | struct passwd *pw; |
| 1320 | int lose; | 1319 | int lose; |
| @@ -1366,7 +1365,7 @@ See also the function `substitute-in-file-name'.") | |||
| 1366 | unsigned char *user = nm + 1; | 1365 | unsigned char *user = nm + 1; |
| 1367 | /* Find end of name. */ | 1366 | /* Find end of name. */ |
| 1368 | unsigned char *ptr = (unsigned char *) strchr (user, '/'); | 1367 | unsigned char *ptr = (unsigned char *) strchr (user, '/'); |
| 1369 | int len = ptr ? ptr - user : strlen (user); | 1368 | ptrdiff_t len = ptr ? ptr - user : strlen (user); |
| 1370 | /* Copy the user name into temp storage. */ | 1369 | /* Copy the user name into temp storage. */ |
| 1371 | o = (unsigned char *) alloca (len + 1); | 1370 | o = (unsigned char *) alloca (len + 1); |
| 1372 | memcpy (o, user, len); | 1371 | memcpy (o, user, len); |
| @@ -1672,7 +1671,7 @@ those `/' is discarded. */) | |||
| 1672 | else | 1671 | else |
| 1673 | { | 1672 | { |
| 1674 | Lisp_Object orig, decoded; | 1673 | Lisp_Object orig, decoded; |
| 1675 | int orig_length, decoded_length; | 1674 | ptrdiff_t orig_length, decoded_length; |
| 1676 | orig_length = strlen (o); | 1675 | orig_length = strlen (o); |
| 1677 | orig = make_unibyte_string (o, orig_length); | 1676 | orig = make_unibyte_string (o, orig_length); |
| 1678 | decoded = DECODE_FILE (orig); | 1677 | decoded = DECODE_FILE (orig); |