aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-09-04 12:14:54 -0700
committerPaul Eggert2011-09-04 12:14:54 -0700
commit53e9fe90811730f68c4ea246cd8dee8aa22486de (patch)
tree199e2f43e41bb6cd3d0497947029386adaebeb95
parentf5e29b9b70a5b6493d13c912e27ecf3bffc97716 (diff)
parent7ab3acf4ad7166a3ae8998a8a43ad59f852879ea (diff)
downloademacs-53e9fe90811730f68c4ea246cd8dee8aa22486de.tar.gz
emacs-53e9fe90811730f68c4ea246cd8dee8aa22486de.zip
Integer overflow fixes for scrolling, etc.
-rw-r--r--src/ChangeLog36
-rw-r--r--src/indent.c12
-rw-r--r--src/print.c2
-rw-r--r--src/search.c10
-rw-r--r--src/window.c28
-rw-r--r--src/xdisp.c4
6 files changed, 61 insertions, 31 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 6113c2362ee..741bd6e3d53 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,39 @@
12011-09-04 Paul Eggert <eggert@cs.ucla.edu>
2
3 Integer overflow fixes for scrolling, etc.
4 Without this fix, Emacs silently mishandles large integers sometimes.
5 For example, "C-u 4294967297 M-x recenter" was be treated as if
6 it were "C-u 1 M-x recenter" on a typical 64-bit host.
7
8 * xdisp.c: Integer overflow fix.
9 (try_window_id): Check Emacs fixnum range before converting to 'int'.
10
11 * window.c: Integer overflow fixes.
12 (window_scroll_line_based, Frecenter):
13 Check that an Emacs fixnum is in range before assigning it to 'int'.
14 (Frecenter, Fmove_to_window_line): Use EMACS_INT, not int, for
15 values converted from Emacs fixnums.
16 (Frecenter): Don't wrap around a line count if it is out of 'int'
17 range; instead, treat it as an extreme value.
18 (Fset_window_configuration, compare_window_configurations):
19 Use ptrdiff_t, not int, for index that might exceed 2 GiB.
20
21 * search.c: Integer overflow fixes
22 (Freplace_match): Use ptrdiff_t, not int, for indexes that can
23 exceed INT_MAX. Check that EMACS_INT value is in range before
24 assigning it to the (possibly-narrower) index.
25 (match_limit): Don't assume that a fixnum can fit in 'int'.
26
27 * print.c: Integer overflow fix.
28 (print_object): Use ptrdiff_t, not int, for index that can
29 exceed INT_MAX.
30
31 * indent.c: Integer overflow fixes.
32 (position_indentation): Now takes ptrdiff_t, not int.
33 (Fvertical_motion): Don't wrap around LINES values that don't fit
34 in 'int'. Instead, treat them as extreme values. This is good
35 enough for windows, which can't have more than INT_MAX lines anyway.
36
12011-09-03 Lars Magne Ingebrigtsen <larsi@gnus.org> 372011-09-03 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 38
3 * Require libxml/parser.h to avoid compilation warning. 39 * Require libxml/parser.h to avoid compilation warning.
diff --git a/src/indent.c b/src/indent.c
index 313315e9081..6e602d28f60 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -56,7 +56,7 @@ EMACS_INT last_known_column_point;
56static int last_known_column_modified; 56static int last_known_column_modified;
57 57
58static EMACS_INT current_column_1 (void); 58static EMACS_INT current_column_1 (void);
59static EMACS_INT position_indentation (int); 59static EMACS_INT position_indentation (ptrdiff_t);
60 60
61/* Cache of beginning of line found by the last call of 61/* Cache of beginning of line found by the last call of
62 current_column. */ 62 current_column. */
@@ -855,7 +855,7 @@ following any initial whitespace. */)
855} 855}
856 856
857static EMACS_INT 857static EMACS_INT
858position_indentation (register int pos_byte) 858position_indentation (ptrdiff_t pos_byte)
859{ 859{
860 register EMACS_INT column = 0; 860 register EMACS_INT column = 0;
861 int tab_width = SANE_TAB_WIDTH (current_buffer); 861 int tab_width = SANE_TAB_WIDTH (current_buffer);
@@ -2063,7 +2063,7 @@ whether or not it is currently displayed in some window. */)
2063 /* Do this even if LINES is 0, so that we move back to the 2063 /* Do this even if LINES is 0, so that we move back to the
2064 beginning of the current line as we ought. */ 2064 beginning of the current line as we ought. */
2065 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0) 2065 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0)
2066 move_it_by_lines (&it, XINT (lines)); 2066 move_it_by_lines (&it, max (INT_MIN, XINT (lines)));
2067 } 2067 }
2068 else 2068 else
2069 { 2069 {
@@ -2083,7 +2083,7 @@ whether or not it is currently displayed in some window. */)
2083 && it.c == '\n')) 2083 && it.c == '\n'))
2084 move_it_by_lines (&it, -1); 2084 move_it_by_lines (&it, -1);
2085 it.vpos = 0; 2085 it.vpos = 0;
2086 move_it_by_lines (&it, XINT (lines)); 2086 move_it_by_lines (&it, min (INT_MAX, XINT (lines)));
2087 } 2087 }
2088 else 2088 else
2089 { 2089 {
@@ -2099,12 +2099,12 @@ whether or not it is currently displayed in some window. */)
2099 move_it_by_lines (&it, 1); 2099 move_it_by_lines (&it, 1);
2100 } 2100 }
2101 if (XINT (lines) > 1) 2101 if (XINT (lines) > 1)
2102 move_it_by_lines (&it, XINT (lines) - 1); 2102 move_it_by_lines (&it, min (INT_MAX, XINT (lines) - 1));
2103 } 2103 }
2104 else 2104 else
2105 { 2105 {
2106 it.vpos = 0; 2106 it.vpos = 0;
2107 move_it_by_lines (&it, XINT (lines)); 2107 move_it_by_lines (&it, min (INT_MAX, XINT (lines)));
2108 } 2108 }
2109 } 2109 }
2110 } 2110 }
diff --git a/src/print.c b/src/print.c
index 35f89860843..913a14b3e42 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1697,7 +1697,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1697 } 1697 }
1698 else if (BOOL_VECTOR_P (obj)) 1698 else if (BOOL_VECTOR_P (obj))
1699 { 1699 {
1700 register int i; 1700 ptrdiff_t i;
1701 register unsigned char c; 1701 register unsigned char c;
1702 struct gcpro gcpro1; 1702 struct gcpro gcpro1;
1703 EMACS_INT size_in_chars 1703 EMACS_INT size_in_chars
diff --git a/src/search.c b/src/search.c
index d892792cbaa..b3d67e6c431 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2404,7 +2404,7 @@ since only regular expressions have distinguished subexpressions. */)
2404 int some_uppercase; 2404 int some_uppercase;
2405 int some_nonuppercase_initial; 2405 int some_nonuppercase_initial;
2406 register int c, prevc; 2406 register int c, prevc;
2407 int sub; 2407 ptrdiff_t sub;
2408 EMACS_INT opoint, newpoint; 2408 EMACS_INT opoint, newpoint;
2409 2409
2410 CHECK_STRING (newtext); 2410 CHECK_STRING (newtext);
@@ -2423,9 +2423,9 @@ since only regular expressions have distinguished subexpressions. */)
2423 else 2423 else
2424 { 2424 {
2425 CHECK_NUMBER (subexp); 2425 CHECK_NUMBER (subexp);
2426 sub = XINT (subexp); 2426 if (! (0 <= XINT (subexp) && XINT (subexp) < search_regs.num_regs))
2427 if (sub < 0 || sub >= search_regs.num_regs)
2428 args_out_of_range (subexp, make_number (search_regs.num_regs)); 2427 args_out_of_range (subexp, make_number (search_regs.num_regs));
2428 sub = XINT (subexp);
2429 } 2429 }
2430 2430
2431 if (NILP (string)) 2431 if (NILP (string))
@@ -2662,7 +2662,7 @@ since only regular expressions have distinguished subexpressions. */)
2662 unsigned char str[MAX_MULTIBYTE_LENGTH]; 2662 unsigned char str[MAX_MULTIBYTE_LENGTH];
2663 const unsigned char *add_stuff = NULL; 2663 const unsigned char *add_stuff = NULL;
2664 ptrdiff_t add_len = 0; 2664 ptrdiff_t add_len = 0;
2665 int idx = -1; 2665 ptrdiff_t idx = -1;
2666 2666
2667 if (str_multibyte) 2667 if (str_multibyte)
2668 { 2668 {
@@ -2813,7 +2813,7 @@ since only regular expressions have distinguished subexpressions. */)
2813static Lisp_Object 2813static Lisp_Object
2814match_limit (Lisp_Object num, int beginningp) 2814match_limit (Lisp_Object num, int beginningp)
2815{ 2815{
2816 register int n; 2816 EMACS_INT n;
2817 2817
2818 CHECK_NUMBER (num); 2818 CHECK_NUMBER (num);
2819 n = XINT (num); 2819 n = XINT (num);
diff --git a/src/window.c b/src/window.c
index 96b1144acf2..e3850387a64 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4662,14 +4662,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4662 4662
4663 if (pos < ZV) 4663 if (pos < ZV)
4664 { 4664 {
4665 int this_scroll_margin = scroll_margin;
4666
4667 /* Don't use a scroll margin that is negative or too large. */ 4665 /* Don't use a scroll margin that is negative or too large. */
4668 if (this_scroll_margin < 0) 4666 int this_scroll_margin =
4669 this_scroll_margin = 0; 4667 max (0, min (scroll_margin, XINT (w->total_lines) / 4));
4670
4671 if (XINT (w->total_lines) < 4 * scroll_margin)
4672 this_scroll_margin = XINT (w->total_lines) / 4;
4673 4668
4674 set_marker_restricted_both (w->start, w->buffer, pos, pos_byte); 4669 set_marker_restricted_both (w->start, w->buffer, pos, pos_byte);
4675 w->start_at_line_beg = bolp; 4670 w->start_at_line_beg = bolp;
@@ -5057,7 +5052,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5057 struct buffer *obuf = current_buffer; 5052 struct buffer *obuf = current_buffer;
5058 int center_p = 0; 5053 int center_p = 0;
5059 EMACS_INT charpos, bytepos; 5054 EMACS_INT charpos, bytepos;
5060 int iarg IF_LINT (= 0); 5055 EMACS_INT iarg IF_LINT (= 0);
5061 int this_scroll_margin; 5056 int this_scroll_margin;
5062 5057
5063 /* If redisplay is suppressed due to an error, try again. */ 5058 /* If redisplay is suppressed due to an error, try again. */
@@ -5096,9 +5091,8 @@ and redisplay normally--don't erase and redraw the frame. */)
5096 5091
5097 /* Do this after making BUF current 5092 /* Do this after making BUF current
5098 in case scroll_margin is buffer-local. */ 5093 in case scroll_margin is buffer-local. */
5099 this_scroll_margin = max (0, scroll_margin); 5094 this_scroll_margin =
5100 this_scroll_margin = min (this_scroll_margin, 5095 max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4));
5101 XFASTINT (w->total_lines) / 4);
5102 5096
5103 /* Handle centering on a graphical frame specially. Such frames can 5097 /* Handle centering on a graphical frame specially. Such frames can
5104 have variable-height lines and centering point on the basis of 5098 have variable-height lines and centering point on the basis of
@@ -5122,7 +5116,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5122 { 5116 {
5123 struct it it; 5117 struct it it;
5124 struct text_pos pt; 5118 struct text_pos pt;
5125 int nlines = -iarg; 5119 int nlines = min (INT_MAX, -iarg);
5126 int extra_line_spacing; 5120 int extra_line_spacing;
5127 int h = window_box_height (w); 5121 int h = window_box_height (w);
5128 void *itdata = bidi_shelve_cache (); 5122 void *itdata = bidi_shelve_cache ();
@@ -5288,15 +5282,14 @@ zero means top of window, negative means relative to bottom of window. */)
5288 lines = displayed_window_lines (w); 5282 lines = displayed_window_lines (w);
5289 5283
5290#if 0 5284#if 0
5291 this_scroll_margin = max (0, scroll_margin); 5285 this_scroll_margin = max (0, min (scroll_margin, lines / 4));
5292 this_scroll_margin = min (this_scroll_margin, lines / 4);
5293#endif 5286#endif
5294 5287
5295 if (NILP (arg)) 5288 if (NILP (arg))
5296 XSETFASTINT (arg, lines / 2); 5289 XSETFASTINT (arg, lines / 2);
5297 else 5290 else
5298 { 5291 {
5299 int iarg = XINT (Fprefix_numeric_value (arg)); 5292 EMACS_INT iarg = XINT (Fprefix_numeric_value (arg));
5300 5293
5301 if (iarg < 0) 5294 if (iarg < 0)
5302 iarg = iarg + lines; 5295 iarg = iarg + lines;
@@ -5468,7 +5461,8 @@ the return value is nil. Otherwise the value is t. */)
5468 struct window *root_window; 5461 struct window *root_window;
5469 struct window **leaf_windows; 5462 struct window **leaf_windows;
5470 int n_leaf_windows; 5463 int n_leaf_windows;
5471 int k, i, n; 5464 ptrdiff_t k;
5465 int i, n;
5472 5466
5473 /* If the frame has been resized since this window configuration was 5467 /* If the frame has been resized since this window configuration was
5474 made, we change the frame to the size specified in the 5468 made, we change the frame to the size specified in the
@@ -6344,7 +6338,7 @@ compare_window_configurations (Lisp_Object configuration1, Lisp_Object configura
6344{ 6338{
6345 register struct save_window_data *d1, *d2; 6339 register struct save_window_data *d1, *d2;
6346 struct Lisp_Vector *sws1, *sws2; 6340 struct Lisp_Vector *sws1, *sws2;
6347 int i; 6341 ptrdiff_t i;
6348 6342
6349 CHECK_WINDOW_CONFIGURATION (configuration1); 6343 CHECK_WINDOW_CONFIGURATION (configuration1);
6350 CHECK_WINDOW_CONFIGURATION (configuration2); 6344 CHECK_WINDOW_CONFIGURATION (configuration2);
diff --git a/src/xdisp.c b/src/xdisp.c
index 1716cc82188..f11362c1ae6 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -16919,8 +16919,8 @@ try_window_id (struct window *w)
16919 { 16919 {
16920 int this_scroll_margin, cursor_height; 16920 int this_scroll_margin, cursor_height;
16921 16921
16922 this_scroll_margin = max (0, scroll_margin); 16922 this_scroll_margin =
16923 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4); 16923 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
16924 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); 16924 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
16925 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height; 16925 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
16926 16926