emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 701484d: Avoid infinite loop in display of invisibl


From: Eli Zaretskii
Subject: [Emacs-diffs] master 701484d: Avoid infinite loop in display of invisible text in strings
Date: Fri, 07 Aug 2015 13:44:20 +0000

branch: master
commit 701484d524835e3461f521138399893366229ae5
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Avoid infinite loop in display of invisible text in strings
    
    * src/xdisp.c (handle_invisible_prop): If the next change of
    invisibility spec does not mean the beginning of a visible text,
    update the string position from which to start the search for the
    next invisibility change.  This avoids an infinite loop when we
    have more than one invisibility spec that are made inactive by
    buffer-invisibility-spec.  Simplify code.  (Bug#21200)
    
    * test/redisplay-testsuite.el (test-redisplay-4): Add a test case
    for the situation that caused bug #21200.
---
 src/xdisp.c                 |   18 ++++++++++++------
 test/redisplay-testsuite.el |   13 +++++++++++++
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index e45cb87..e7626d1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4187,13 +4187,13 @@ handle_invisible_prop (struct it *it)
 
   if (STRINGP (it->string))
     {
-      Lisp_Object end_charpos, limit, charpos;
+      Lisp_Object end_charpos, limit;
 
       /* Get the value of the invisible text property at the
         current position.  Value will be nil if there is no such
         property.  */
-      charpos = make_number (IT_STRING_CHARPOS (*it));
-      prop = Fget_text_property (charpos, Qinvisible, it->string);
+      end_charpos = make_number (IT_STRING_CHARPOS (*it));
+      prop = Fget_text_property (end_charpos, Qinvisible, it->string);
       invis = TEXT_PROP_MEANS_INVISIBLE (prop);
 
       if (invis != 0 && IT_STRING_CHARPOS (*it) < it->end_charpos)
@@ -4211,8 +4211,12 @@ handle_invisible_prop (struct it *it)
          XSETINT (limit, len);
          do
            {
-             end_charpos = Fnext_single_property_change (charpos, Qinvisible,
-                                                         it->string, limit);
+             end_charpos
+               = Fnext_single_property_change (end_charpos, Qinvisible,
+                                               it->string, limit);
+             /* Since LIMIT is always an integer, so should be the
+                value returned by Fnext_single_property_change.  */
+             eassert (INTEGERP (end_charpos));
              if (INTEGERP (end_charpos))
                {
                  endpos = XFASTINT (end_charpos);
@@ -4221,6 +4225,8 @@ handle_invisible_prop (struct it *it)
                  if (invis == 2)
                    display_ellipsis_p = true;
                }
+             else /* Should never happen; but if it does, exit the loop.  */
+               endpos = len;
            }
          while (invis != 0 && endpos < len);
 
@@ -4256,7 +4262,7 @@ handle_invisible_prop (struct it *it)
                }
              else
                {
-                 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
+                 IT_STRING_CHARPOS (*it) = endpos;
                  compute_string_pos (&it->current.string_pos, old, it->string);
                }
            }
diff --git a/test/redisplay-testsuite.el b/test/redisplay-testsuite.el
index 357ab08..40a21b7 100644
--- a/test/redisplay-testsuite.el
+++ b/test/redisplay-testsuite.el
@@ -251,6 +251,18 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 
0xa5, 0xbd, 0x81, 0xff
          (str "ABC"))
       (put-text-property 1 2 'invisible 'test-redisplay--ellipsis-invis str)
       (overlay-put ov 'display str)))
+  ;; Overlay string with 2 adjacent and different invisible
+  ;; properties.  This caused an infloop before Emacs 25.
+  (insert "\n  Expected: ABC")
+  (insert "\n    Result: ")
+  (let ((opoint (point)))
+    (insert "ABC\n")
+    (let ((ov (make-overlay (1+ opoint) (+ 2 opoint)))
+          (str (concat (propertize "X"
+                                   'invisible 'test-redisplay--simple-invis)
+                       (propertize "Y"
+                                   'invisible 
'test-redisplay--simple-invis2))))
+      (overlay-put ov 'after-string str)))
 
   (insert "\n"))
 
@@ -264,6 +276,7 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 
0xa5, 0xbd, 0x81, 0xff
     (erase-buffer)
     (setq buffer-invisibility-spec
          '(test-redisplay--simple-invis
+            test-redisplay--simple-invis2
            (test-redisplay--ellipsis-invis . t)))
     (test-redisplay-1)
     (test-redisplay-2)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]