From d6e7bf450c0a084927d533cb6913bc5f540a0032 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 5 Jul 2012 18:04:57 +0300 Subject: [PATCH] Fix bug #11857 with messed up display for insanely large hscroll values. src/xdisp.c (window_hscroll_limited): New function. (pos_visible_p, init_iterator): Use it to avoid overflow of pixel coordinates when window's hscroll is set to insanely large values. src/window.h (struct window) : Change type to 'int'. --- src/ChangeLog | 10 ++++++++++ src/window.h | 4 ++-- src/xdisp.c | 25 ++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 4519ea2dabf..d14c322cadf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2012-07-05 Eli Zaretskii + + * xdisp.c (window_hscroll_limited): New function. + (pos_visible_p, init_iterator): Use it to avoid overflow of pixel + coordinates when window's hscroll is set to insanely large + values. (Bug#11857) + + * window.h (struct window) : Change type to + 'int'. + 2012-07-05 Juanma Barranquero * makefile.w32-in ($(BLD)/dired.$(O), $(BLD)/fileio.$(O)): Fix typo. diff --git a/src/window.h b/src/window.h index 10cabed979b..2684713eb6b 100644 --- a/src/window.h +++ b/src/window.h @@ -238,11 +238,11 @@ struct window int sequence_number; /* Number of columns display within the window is scrolled to the left. */ - ptrdiff_t hscroll; + int hscroll; /* Minimum hscroll for automatic hscrolling. This is the value the user has set, by set-window-hscroll for example. */ - ptrdiff_t min_hscroll; + int min_hscroll; /* Displayed buffer's text modification events counter as of last time display completed. */ diff --git a/src/xdisp.c b/src/xdisp.c index 8231922056f..e6ad6a0bd78 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1251,6 +1251,23 @@ string_from_display_spec (Lisp_Object spec) return spec; } + +/* Limit insanely large values of W->hscroll on frame F to the largest + value that will still prevent first_visible_x and last_visible_x of + 'struct it' from overflowing an int. */ +static inline int +window_hscroll_limited (struct window *w, struct frame *f) +{ + int window_hscroll = w->hscroll; + int window_text_width = window_box_width (w, TEXT_AREA); + int colwidth = FRAME_COLUMN_WIDTH (f); + + if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1) + window_hscroll = (INT_MAX - window_text_width) / colwidth - 1; + + return window_hscroll; +} + /* Return 1 if position CHARPOS is visible in window W. CHARPOS < 0 means return info about WINDOW_END position. If visible, set *X and *Y to pixel coordinates of top left corner. @@ -1563,7 +1580,9 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, current_header_line_height = current_mode_line_height = -1; if (visible_p && w->hscroll > 0) - *x -= w->hscroll * WINDOW_FRAME_COLUMN_WIDTH (w); + *x -= + window_hscroll_limited (w, WINDOW_XFRAME (w)) + * WINDOW_FRAME_COLUMN_WIDTH (w); #if 0 /* Debugging code. */ @@ -2759,8 +2778,8 @@ init_iterator (struct it *it, struct window *w, } else { - it->first_visible_x - = it->w->hscroll * FRAME_COLUMN_WIDTH (it->f); + it->first_visible_x = + window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f); it->last_visible_x = (it->first_visible_x + window_box_width (w, TEXT_AREA)); -- 2.39.2