aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorPaul Eggert2012-06-28 08:50:11 -0700
committerPaul Eggert2012-06-28 08:50:11 -0700
commitaa754e6a9ef5fb65e6a4f582101d7284adc01656 (patch)
tree7e9e88060fe037dfa4816c2c1904d3f263c0395f /src/window.c
parent80b00b0885b8e124a208dfc9de95d2039a101108 (diff)
downloademacs-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/window.c')
-rw-r--r--src/window.c31
1 files changed, 16 insertions, 15 deletions
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
4860DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np", 4863DEFUN ("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.
4862Default for ARG is window width minus 2. 4865Default 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))