aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-06-16 14:18:12 -0700
committerPaul Eggert2011-06-16 14:18:12 -0700
commit1c8e352f7e4291ab523996e7c5feaedfe0f4b350 (patch)
tree3adb22fb15a891521047080018b22e454ba5c471 /src
parent21d890a4ecf97141f3c3f7e373bca6d083662a83 (diff)
downloademacs-1c8e352f7e4291ab523996e7c5feaedfe0f4b350.tar.gz
emacs-1c8e352f7e4291ab523996e7c5feaedfe0f4b350.zip
Improve buffer-overflow checking.
* fileio.c (Finsert_file_contents): * insdel.c (insert_from_buffer_1, replace_range, replace_range_2): Remove the old (too-loose) buffer overflow checks. They weren't needed, since make_gap checks for buffer overflow. * insdel.c (make_gap_larger): Catch buffer overflows that were missed. The old code merely checked for Emacs fixnum overflow, and relied on undefined (wraparound) behavior. The new code avoids undefined behavior, and also checks for ptrdiff_t and/or size_t overflow.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/fileio.c11
-rw-r--r--src/insdel.c34
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 @@
12011-06-16 Paul Eggert <eggert@cs.ucla.edu> 12011-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
1069insert_from_buffer_1 (struct buffer *buf, 1069insert_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);