diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 10 | ||||
-rw-r--r-- | src/window.h | 4 | ||||
-rw-r--r-- | 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 <eliz@gnu.org> + + * 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) <hscroll, min_hscroll>: Change type to + 'int'. + 2012-07-05 Juanma Barranquero <lekktu@gmail.com> * 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)); |