Commit aa754e6a authored by Paul Eggert's avatar Paul Eggert

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.
parent 80b00b08
2012-06-28 Paul Eggert <eggert@cs.ucla.edu>
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.
2012-06-28 Dmitry Antipov <dmantipov@yandex.ru> 2012-06-28 Dmitry Antipov <dmantipov@yandex.ru>
* window.h (struct window): Change type of 'hscroll', * window.h (struct window): Change type of 'hscroll',
......
...@@ -3244,7 +3244,7 @@ make_parent_window (Lisp_Object window, int horflag) ...@@ -3244,7 +3244,7 @@ make_parent_window (Lisp_Object window, int horflag)
o = XWINDOW (window); o = XWINDOW (window);
p = allocate_window (); p = allocate_window ();
memcpy ((char *) p + sizeof (struct vectorlike_header), memcpy ((char *) p + sizeof (struct vectorlike_header),
(char *) o + sizeof (struct vectorlike_header), (char *) o + sizeof (struct vectorlike_header),
sizeof (Lisp_Object) * VECSIZE (struct window)); sizeof (Lisp_Object) * VECSIZE (struct window));
XSETWINDOW (parent, p); XSETWINDOW (parent, p);
...@@ -4857,6 +4857,9 @@ specifies the window to scroll. This takes precedence over ...@@ -4857,6 +4857,9 @@ specifies the window to scroll. This takes precedence over
return Qnil; return Qnil;
} }
/* Scrolling amount must fit in both ptrdiff_t and Emacs fixnum. */
#define HSCROLL_MAX min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM)
DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np", DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np",
doc: /* Scroll selected window display ARG columns left. doc: /* Scroll selected window display ARG columns left.
Default for ARG is window width minus 2. Default for ARG is window width minus 2.
...@@ -4871,13 +4874,12 @@ by this function. This happens in an interactive call. */) ...@@ -4871,13 +4874,12 @@ by this function. This happens in an interactive call. */)
Lisp_Object result; Lisp_Object result;
ptrdiff_t hscroll; ptrdiff_t hscroll;
struct window *w = XWINDOW (selected_window); struct window *w = XWINDOW (selected_window);
EMACS_INT requested_arg = (NILP (arg)
if (NILP (arg)) ? window_body_cols (w) - 2
XSETFASTINT (arg, window_body_cols (w) - 2); : XINT (Fprefix_numeric_value (arg)));
else ptrdiff_t clipped_arg =
arg = Fprefix_numeric_value (arg); clip_to_bounds (- w->hscroll, requested_arg, HSCROLL_MAX - w->hscroll);
hscroll = w->hscroll + clipped_arg;
hscroll = w->hscroll + XINT (arg);
result = Fset_window_hscroll (selected_window, make_number (hscroll)); result = Fset_window_hscroll (selected_window, make_number (hscroll));
if (!NILP (set_minimum)) if (!NILP (set_minimum))
...@@ -4900,13 +4902,12 @@ by this function. This happens in an interactive call. */) ...@@ -4900,13 +4902,12 @@ by this function. This happens in an interactive call. */)
Lisp_Object result; Lisp_Object result;
ptrdiff_t hscroll; ptrdiff_t hscroll;
struct window *w = XWINDOW (selected_window); struct window *w = XWINDOW (selected_window);
EMACS_INT requested_arg = (NILP (arg)
if (NILP (arg)) ? window_body_cols (w) - 2
XSETFASTINT (arg, window_body_cols (w) - 2); : XINT (Fprefix_numeric_value (arg)));
else ptrdiff_t clipped_arg =
arg = Fprefix_numeric_value (arg); clip_to_bounds (w->hscroll - HSCROLL_MAX, requested_arg, w->hscroll);
hscroll = w->hscroll - clipped_arg;
hscroll = w->hscroll - XINT (arg);
result = Fset_window_hscroll (selected_window, make_number (hscroll)); result = Fset_window_hscroll (selected_window, make_number (hscroll));
if (!NILP (set_minimum)) if (!NILP (set_minimum))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment