diff options
| author | Paul Eggert | 2012-06-28 08:50:11 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-06-28 08:50:11 -0700 |
| commit | aa754e6a9ef5fb65e6a4f582101d7284adc01656 (patch) | |
| tree | 7e9e88060fe037dfa4816c2c1904d3f263c0395f /src | |
| parent | 80b00b0885b8e124a208dfc9de95d2039a101108 (diff) | |
| download | emacs-aa754e6a9ef5fb65e6a4f582101d7284adc01656.tar.gz emacs-aa754e6a9ef5fb65e6a4f582101d7284adc01656.zip | |
Avoid integer overflow on scroll-left and scroll-right.
* window.c (HSCROLL_MAX): New macro.
(Fscroll_left, Fscroll_right): Avoid undefined behavior on integer
overflow when requested scroll falls outside ptrdiff_t range.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/window.c | 31 |
2 files changed, 23 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7bb418fab5a..262ed2ce4d6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2012-06-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Avoid integer overflow on scroll-left and scroll-right. | ||
| 4 | * window.c (HSCROLL_MAX): New macro. | ||
| 5 | (Fscroll_left, Fscroll_right): Avoid undefined behavior on integer | ||
| 6 | overflow when requested scroll falls outside ptrdiff_t range. | ||
| 7 | |||
| 1 | 2012-06-28 Dmitry Antipov <dmantipov@yandex.ru> | 8 | 2012-06-28 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 9 | ||
| 3 | * window.h (struct window): Change type of 'hscroll', | 10 | * window.h (struct window): Change type of 'hscroll', |
diff --git a/src/window.c b/src/window.c index 4f3d40c51e3..9d78a3efa60 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -3244,7 +3244,7 @@ make_parent_window (Lisp_Object window, int horflag) | |||
| 3244 | 3244 | ||
| 3245 | o = XWINDOW (window); | 3245 | o = XWINDOW (window); |
| 3246 | p = allocate_window (); | 3246 | p = allocate_window (); |
| 3247 | memcpy ((char *) p + sizeof (struct vectorlike_header), | 3247 | memcpy ((char *) p + sizeof (struct vectorlike_header), |
| 3248 | (char *) o + sizeof (struct vectorlike_header), | 3248 | (char *) o + sizeof (struct vectorlike_header), |
| 3249 | sizeof (Lisp_Object) * VECSIZE (struct window)); | 3249 | sizeof (Lisp_Object) * VECSIZE (struct window)); |
| 3250 | XSETWINDOW (parent, p); | 3250 | XSETWINDOW (parent, p); |
| @@ -4857,6 +4857,9 @@ specifies the window to scroll. This takes precedence over | |||
| 4857 | return Qnil; | 4857 | return Qnil; |
| 4858 | } | 4858 | } |
| 4859 | 4859 | ||
| 4860 | /* Scrolling amount must fit in both ptrdiff_t and Emacs fixnum. */ | ||
| 4861 | #define HSCROLL_MAX min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM) | ||
| 4862 | |||
| 4860 | DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np", | 4863 | DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np", |
| 4861 | doc: /* Scroll selected window display ARG columns left. | 4864 | doc: /* Scroll selected window display ARG columns left. |
| 4862 | Default for ARG is window width minus 2. | 4865 | Default for ARG is window width minus 2. |
| @@ -4871,13 +4874,12 @@ by this function. This happens in an interactive call. */) | |||
| 4871 | Lisp_Object result; | 4874 | Lisp_Object result; |
| 4872 | ptrdiff_t hscroll; | 4875 | ptrdiff_t hscroll; |
| 4873 | struct window *w = XWINDOW (selected_window); | 4876 | struct window *w = XWINDOW (selected_window); |
| 4874 | 4877 | EMACS_INT requested_arg = (NILP (arg) | |
| 4875 | if (NILP (arg)) | 4878 | ? window_body_cols (w) - 2 |
| 4876 | XSETFASTINT (arg, window_body_cols (w) - 2); | 4879 | : XINT (Fprefix_numeric_value (arg))); |
| 4877 | else | 4880 | ptrdiff_t clipped_arg = |
| 4878 | arg = Fprefix_numeric_value (arg); | 4881 | clip_to_bounds (- w->hscroll, requested_arg, HSCROLL_MAX - w->hscroll); |
| 4879 | 4882 | hscroll = w->hscroll + clipped_arg; | |
| 4880 | hscroll = w->hscroll + XINT (arg); | ||
| 4881 | result = Fset_window_hscroll (selected_window, make_number (hscroll)); | 4883 | result = Fset_window_hscroll (selected_window, make_number (hscroll)); |
| 4882 | 4884 | ||
| 4883 | if (!NILP (set_minimum)) | 4885 | if (!NILP (set_minimum)) |
| @@ -4900,13 +4902,12 @@ by this function. This happens in an interactive call. */) | |||
| 4900 | Lisp_Object result; | 4902 | Lisp_Object result; |
| 4901 | ptrdiff_t hscroll; | 4903 | ptrdiff_t hscroll; |
| 4902 | struct window *w = XWINDOW (selected_window); | 4904 | struct window *w = XWINDOW (selected_window); |
| 4903 | 4905 | EMACS_INT requested_arg = (NILP (arg) | |
| 4904 | if (NILP (arg)) | 4906 | ? window_body_cols (w) - 2 |
| 4905 | XSETFASTINT (arg, window_body_cols (w) - 2); | 4907 | : XINT (Fprefix_numeric_value (arg))); |
| 4906 | else | 4908 | ptrdiff_t clipped_arg = |
| 4907 | arg = Fprefix_numeric_value (arg); | 4909 | clip_to_bounds (w->hscroll - HSCROLL_MAX, requested_arg, w->hscroll); |
| 4908 | 4910 | hscroll = w->hscroll - clipped_arg; | |
| 4909 | hscroll = w->hscroll - XINT (arg); | ||
| 4910 | result = Fset_window_hscroll (selected_window, make_number (hscroll)); | 4911 | result = Fset_window_hscroll (selected_window, make_number (hscroll)); |
| 4911 | 4912 | ||
| 4912 | if (!NILP (set_minimum)) | 4913 | if (!NILP (set_minimum)) |