diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/fileio.c | 11 | ||||
| -rw-r--r-- | src/insdel.c | 34 |
3 files changed, 19 insertions, 36 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 011f5beefe0..5f18c8d0062 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,15 @@ | |||
| 1 | 2011-06-16 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-06-16 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Improve buffer-overflow checking. | ||
| 4 | * fileio.c (Finsert_file_contents): | ||
| 5 | * insdel.c (insert_from_buffer_1, replace_range, replace_range_2): | ||
| 6 | Remove the old (too-loose) buffer overflow checks. | ||
| 7 | They weren't needed, since make_gap checks for buffer overflow. | ||
| 8 | * insdel.c (make_gap_larger): Catch buffer overflows that were missed. | ||
| 9 | The old code merely checked for Emacs fixnum overflow, and relied | ||
| 10 | on undefined (wraparound) behavior. The new code avoids undefined | ||
| 11 | behavior, and also checks for ptrdiff_t and/or size_t overflow. | ||
| 12 | |||
| 3 | * editfns.c (Finsert_char): Don't dump core with very negative counts. | 13 | * editfns.c (Finsert_char): Don't dump core with very negative counts. |
| 4 | Tune. Don't use wider integers than needed. Don't use alloca. | 14 | Tune. Don't use wider integers than needed. Don't use alloca. |
| 5 | Use a bigger 'string' buffer. Rewrite to avoid 'n > 0' test. | 15 | Use a bigger 'string' buffer. Rewrite to avoid 'n > 0' test. |
diff --git a/src/fileio.c b/src/fileio.c index 4458a3a4807..dd34872c263 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -3800,16 +3800,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3800 | } | 3800 | } |
| 3801 | 3801 | ||
| 3802 | if (! not_regular) | 3802 | if (! not_regular) |
| 3803 | { | 3803 | total = XINT (end) - XINT (beg); |
| 3804 | register Lisp_Object temp; | ||
| 3805 | |||
| 3806 | total = XINT (end) - XINT (beg); | ||
| 3807 | |||
| 3808 | /* Make sure point-max won't overflow after this insertion. */ | ||
| 3809 | XSETINT (temp, total); | ||
| 3810 | if (total != XINT (temp)) | ||
| 3811 | buffer_overflow (); | ||
| 3812 | } | ||
| 3813 | else | 3804 | else |
| 3814 | /* For a special file, all we can do is guess. */ | 3805 | /* For a special file, all we can do is guess. */ |
| 3815 | total = READ_BUF_SIZE; | 3806 | total = READ_BUF_SIZE; |
diff --git a/src/insdel.c b/src/insdel.c index ca53177a3e1..bc95e3ad9e8 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -406,16 +406,16 @@ make_gap_larger (EMACS_INT nbytes_added) | |||
| 406 | EMACS_INT real_gap_loc; | 406 | EMACS_INT real_gap_loc; |
| 407 | EMACS_INT real_gap_loc_byte; | 407 | EMACS_INT real_gap_loc_byte; |
| 408 | EMACS_INT old_gap_size; | 408 | EMACS_INT old_gap_size; |
| 409 | EMACS_INT current_size = Z_BYTE - BEG_BYTE + GAP_SIZE; | ||
| 410 | enum { enough_for_a_while = 2000 }; | ||
| 409 | 411 | ||
| 410 | /* If we have to get more space, get enough to last a while. */ | 412 | if (BUF_BYTES_MAX - current_size < nbytes_added) |
| 411 | nbytes_added += 2000; | 413 | buffer_overflow (); |
| 412 | 414 | ||
| 413 | { EMACS_INT total_size = Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added; | 415 | /* If we have to get more space, get enough to last a while; |
| 414 | if (total_size < 0 | 416 | but do not exceed the maximum buffer size. */ |
| 415 | /* Don't allow a buffer size that won't fit in a Lisp integer. */ | 417 | nbytes_added = min (nbytes_added + enough_for_a_while, |
| 416 | || total_size != XINT (make_number (total_size))) | 418 | BUF_BYTES_MAX - current_size); |
| 417 | buffer_overflow (); | ||
| 418 | } | ||
| 419 | 419 | ||
| 420 | enlarge_buffer_text (current_buffer, nbytes_added); | 420 | enlarge_buffer_text (current_buffer, nbytes_added); |
| 421 | 421 | ||
| @@ -1069,7 +1069,6 @@ static void | |||
| 1069 | insert_from_buffer_1 (struct buffer *buf, | 1069 | insert_from_buffer_1 (struct buffer *buf, |
| 1070 | EMACS_INT from, EMACS_INT nchars, int inherit) | 1070 | EMACS_INT from, EMACS_INT nchars, int inherit) |
| 1071 | { | 1071 | { |
| 1072 | register Lisp_Object temp; | ||
| 1073 | EMACS_INT chunk, chunk_expanded; | 1072 | EMACS_INT chunk, chunk_expanded; |
| 1074 | EMACS_INT from_byte = buf_charpos_to_bytepos (buf, from); | 1073 | EMACS_INT from_byte = buf_charpos_to_bytepos (buf, from); |
| 1075 | EMACS_INT to_byte = buf_charpos_to_bytepos (buf, from + nchars); | 1074 | EMACS_INT to_byte = buf_charpos_to_bytepos (buf, from + nchars); |
| @@ -1108,11 +1107,6 @@ insert_from_buffer_1 (struct buffer *buf, | |||
| 1108 | outgoing_nbytes = outgoing_before_gap + outgoing_after_gap; | 1107 | outgoing_nbytes = outgoing_before_gap + outgoing_after_gap; |
| 1109 | } | 1108 | } |
| 1110 | 1109 | ||
| 1111 | /* Make sure point-max won't overflow after this insertion. */ | ||
| 1112 | XSETINT (temp, outgoing_nbytes + Z); | ||
| 1113 | if (outgoing_nbytes + Z != XINT (temp)) | ||
| 1114 | buffer_overflow (); | ||
| 1115 | |||
| 1116 | /* Do this before moving and increasing the gap, | 1110 | /* Do this before moving and increasing the gap, |
| 1117 | because the before-change hooks might move the gap | 1111 | because the before-change hooks might move the gap |
| 1118 | or make it smaller. */ | 1112 | or make it smaller. */ |
| @@ -1309,7 +1303,6 @@ replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new, | |||
| 1309 | EMACS_INT insbytes = SBYTES (new); | 1303 | EMACS_INT insbytes = SBYTES (new); |
| 1310 | EMACS_INT from_byte, to_byte; | 1304 | EMACS_INT from_byte, to_byte; |
| 1311 | EMACS_INT nbytes_del, nchars_del; | 1305 | EMACS_INT nbytes_del, nchars_del; |
| 1312 | register Lisp_Object temp; | ||
| 1313 | struct gcpro gcpro1; | 1306 | struct gcpro gcpro1; |
| 1314 | INTERVAL intervals; | 1307 | INTERVAL intervals; |
| 1315 | EMACS_INT outgoing_insbytes = insbytes; | 1308 | EMACS_INT outgoing_insbytes = insbytes; |
| @@ -1353,11 +1346,6 @@ replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new, | |||
| 1353 | outgoing_insbytes | 1346 | outgoing_insbytes |
| 1354 | = count_size_as_multibyte (SDATA (new), insbytes); | 1347 | = count_size_as_multibyte (SDATA (new), insbytes); |
| 1355 | 1348 | ||
| 1356 | /* Make sure point-max won't overflow after this insertion. */ | ||
| 1357 | XSETINT (temp, Z_BYTE - nbytes_del + outgoing_insbytes); | ||
| 1358 | if (Z_BYTE - nbytes_del + outgoing_insbytes != XINT (temp)) | ||
| 1359 | buffer_overflow (); | ||
| 1360 | |||
| 1361 | GCPRO1 (new); | 1349 | GCPRO1 (new); |
| 1362 | 1350 | ||
| 1363 | /* Make sure the gap is somewhere in or next to what we are deleting. */ | 1351 | /* Make sure the gap is somewhere in or next to what we are deleting. */ |
| @@ -1488,7 +1476,6 @@ replace_range_2 (EMACS_INT from, EMACS_INT from_byte, | |||
| 1488 | int markers) | 1476 | int markers) |
| 1489 | { | 1477 | { |
| 1490 | EMACS_INT nbytes_del, nchars_del; | 1478 | EMACS_INT nbytes_del, nchars_del; |
| 1491 | Lisp_Object temp; | ||
| 1492 | 1479 | ||
| 1493 | CHECK_MARKERS (); | 1480 | CHECK_MARKERS (); |
| 1494 | 1481 | ||
| @@ -1498,11 +1485,6 @@ replace_range_2 (EMACS_INT from, EMACS_INT from_byte, | |||
| 1498 | if (nbytes_del <= 0 && insbytes == 0) | 1485 | if (nbytes_del <= 0 && insbytes == 0) |
| 1499 | return; | 1486 | return; |
| 1500 | 1487 | ||
| 1501 | /* Make sure point-max won't overflow after this insertion. */ | ||
| 1502 | XSETINT (temp, Z_BYTE - nbytes_del + insbytes); | ||
| 1503 | if (Z_BYTE - nbytes_del + insbytes != XINT (temp)) | ||
| 1504 | buffer_overflow (); | ||
| 1505 | |||
| 1506 | /* Make sure the gap is somewhere in or next to what we are deleting. */ | 1488 | /* Make sure the gap is somewhere in or next to what we are deleting. */ |
| 1507 | if (from > GPT) | 1489 | if (from > GPT) |
| 1508 | gap_right (from, from_byte); | 1490 | gap_right (from, from_byte); |