]> git.eshelyaron.com Git - emacs.git/commitdiff
Avoid infinite hscrolling in redisplay
authorNoam Postavsky <npostavs@gmail.com>
Sat, 22 Oct 2016 19:55:21 +0000 (15:55 -0400)
committerNoam Postavsky <npostavs@gmail.com>
Sat, 22 Oct 2016 20:29:52 +0000 (16:29 -0400)
* src/xdisp.c (redisplay_internal): Add a counter to avoid horizontal
scrolling (e.g., caused by pre-redisplay-functions) triggering infinite
redisplay (Bug #24633).

src/xdisp.c

index 3af5ea49ab63d731c312f84ec45702032c52290a..1a27c4c3c9635870891e5e70b70b2bee22774cbb 100644 (file)
@@ -13528,6 +13528,12 @@ redisplay_internal (void)
   bool polling_stopped_here = false;
   Lisp_Object tail, frame;
 
+  /* Set a limit to the number of retries we perform due to horizontal
+     scrolling, this avoids getting stuck in an uninterruptible
+     infinite loop (Bug #24633).  */
+  enum { MAX_HSCROLL_RETRIES = 16 };
+  int hscroll_retries = 0;
+
   /* True means redisplay has to consider all windows on all
      frames.  False, only selected_window is considered.  */
   bool consider_all_windows_p;
@@ -14044,8 +14050,12 @@ redisplay_internal (void)
                  if (!f->already_hscrolled_p)
                    {
                      f->already_hscrolled_p = true;
-                     if (hscroll_windows (f->root_window))
-                       goto retry_frame;
+                      if (hscroll_retries <= MAX_HSCROLL_RETRIES
+                          && hscroll_windows (f->root_window))
+                        {
+                          hscroll_retries++;
+                          goto retry_frame;
+                        }
                    }
 
                  /* If the frame's redisplay flag was not set before
@@ -14143,8 +14153,12 @@ redisplay_internal (void)
 
       if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
        {
-         if (hscroll_windows (selected_window))
-           goto retry;
+          if (hscroll_retries <= MAX_HSCROLL_RETRIES
+              && hscroll_windows (selected_window))
+            {
+              hscroll_retries++;
+              goto retry;
+            }
 
          XWINDOW (selected_window)->must_be_updated_p = true;
          pending = update_frame (sf, false, false);
@@ -14164,8 +14178,12 @@ redisplay_internal (void)
          XWINDOW (mini_window)->must_be_updated_p = true;
          pending |= update_frame (mini_frame, false, false);
          mini_frame->cursor_type_changed = false;
-         if (!pending && hscroll_windows (mini_window))
-           goto retry;
+          if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
+              && hscroll_windows (mini_window))
+            {
+              hscroll_retries++;
+              goto retry;
+            }
        }
     }