diff options
| author | Paul Eggert | 2011-09-04 12:14:54 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-09-04 12:14:54 -0700 |
| commit | 53e9fe90811730f68c4ea246cd8dee8aa22486de (patch) | |
| tree | 199e2f43e41bb6cd3d0497947029386adaebeb95 | |
| parent | f5e29b9b70a5b6493d13c912e27ecf3bffc97716 (diff) | |
| parent | 7ab3acf4ad7166a3ae8998a8a43ad59f852879ea (diff) | |
| download | emacs-53e9fe90811730f68c4ea246cd8dee8aa22486de.tar.gz emacs-53e9fe90811730f68c4ea246cd8dee8aa22486de.zip | |
Integer overflow fixes for scrolling, etc.
| -rw-r--r-- | src/ChangeLog | 36 | ||||
| -rw-r--r-- | src/indent.c | 12 | ||||
| -rw-r--r-- | src/print.c | 2 | ||||
| -rw-r--r-- | src/search.c | 10 | ||||
| -rw-r--r-- | src/window.c | 28 | ||||
| -rw-r--r-- | src/xdisp.c | 4 |
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 @@ | |||
| 1 | 2011-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 | |||
| 1 | 2011-09-03 Lars Magne Ingebrigtsen <larsi@gnus.org> | 37 | 2011-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; | |||
| 56 | static int last_known_column_modified; | 56 | static int last_known_column_modified; |
| 57 | 57 | ||
| 58 | static EMACS_INT current_column_1 (void); | 58 | static EMACS_INT current_column_1 (void); |
| 59 | static EMACS_INT position_indentation (int); | 59 | static 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 | ||
| 857 | static EMACS_INT | 857 | static EMACS_INT |
| 858 | position_indentation (register int pos_byte) | 858 | position_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. */) | |||
| 2813 | static Lisp_Object | 2813 | static Lisp_Object |
| 2814 | match_limit (Lisp_Object num, int beginningp) | 2814 | match_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 | ||