]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix bug #11857 with messed up display for insanely large hscroll values.
authorEli Zaretskii <eliz@gnu.org>
Thu, 5 Jul 2012 15:04:57 +0000 (18:04 +0300)
committerEli Zaretskii <eliz@gnu.org>
Thu, 5 Jul 2012 15:04:57 +0000 (18:04 +0300)
 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) <hscroll, min_hscroll>: Change type to 'int'.

src/ChangeLog
src/window.h
src/xdisp.c

index 4519ea2dabf185ef8af701323af6e1c43fa10abc..d14c322cadfd75df5215bb69c137c357b07ed6ec 100644 (file)
@@ -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.
index 10cabed979bbf0dc756bc544b41766d4fc2965cd..2684713eb6b6b851e03539b83e2be98bd8e26e6a 100644 (file)
@@ -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.  */
index 8231922056f6d4159fe866f187e288331750c36b..e6ad6a0bd788b6a1570dc142ddac45706b1181a4 100644 (file)
@@ -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));