emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/emacs-24 r107993: Fix bug #11417 with inflo


From: Eli Zaretskii
Subject: [Emacs-diffs] /srv/bzr/emacs/emacs-24 r107993: Fix bug #11417 with infloop when left-fringe/right-fringe spec is used on TTY.
Date: Sun, 13 May 2012 18:35:13 +0300
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 107993
fixes bug(s): http://debbugs.gnu.org/11417
committer: Eli Zaretskii <address@hidden>
branch nick: emacs-24
timestamp: Sun 2012-05-13 18:35:13 +0300
message:
  Fix bug #11417 with infloop when left-fringe/right-fringe spec is used on TTY.
  
   src/xdisp.c (handle_stop): Don't call get_overlay_strings_1 if we
   already have overlays loaded.
   (handle_single_display_spec): Before returning without displaying
   fringe bitmap, synchronize the bidi iterator with the main display
   iterator, by calling iterate_out_of_display_property.
   (iterate_out_of_display_property): Detect buffer iteration by
   testing that it->string is a Lisp string.
   (get_next_display_element): When the current object is exhausted,
   and there's something on it->stack, call set_iterator_to_next to
   proceed with what's on the stack, instead of returning zero.
   (set_iterator_to_next): If called at the end of a Lisp string,
   proceed to consider_string_end without incrementing string
   position.  Don't increment display vector index past the end of
   the display vector.
modified:
  src/ChangeLog
  src/xdisp.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-05-11 14:05:06 +0000
+++ b/src/ChangeLog     2012-05-13 15:35:13 +0000
@@ -1,3 +1,20 @@
+2012-05-13  Eli Zaretskii  <address@hidden>
+
+       * xdisp.c (handle_stop): Don't call get_overlay_strings_1 if we
+       already have overlays loaded.
+       (handle_single_display_spec): Before returning without displaying
+       fringe bitmap, synchronize the bidi iterator with the main display
+       iterator, by calling iterate_out_of_display_property.
+       (iterate_out_of_display_property): Detect buffer iteration by
+       testing that it->string is a Lisp string.
+       (get_next_display_element): When the current object is exhausted,
+       and there's something on it->stack, call set_iterator_to_next to
+       proceed with what's on the stack, instead of returning zero.
+       (set_iterator_to_next): If called at the end of a Lisp string,
+       proceed to consider_string_end without incrementing string
+       position.  Don't increment display vector index past the end of
+       the display vector.  (Bug#11417)
+
 2012-05-11  Eli Zaretskii  <address@hidden>
 
        * xdisp.c (handle_single_display_spec): Return 1 for left-margin

=== modified file 'src/xdisp.c'
--- a/src/xdisp.c       2012-05-11 14:05:06 +0000
+++ b/src/xdisp.c       2012-05-13 15:35:13 +0000
@@ -839,6 +839,7 @@
 static int trailing_whitespace_p (EMACS_INT);
 static intmax_t message_log_check_duplicate (EMACS_INT, EMACS_INT);
 static void push_it (struct it *, struct text_pos *);
+static void iterate_out_of_display_property (struct it *);
 static void pop_it (struct it *);
 static void sync_frame_with_window_matrix_rows (struct window *);
 static void select_frame_for_redisplay (Lisp_Object);
@@ -3125,7 +3126,15 @@
                 overlays even if the actual buffer text is replaced.  */
              if (!handle_overlay_change_p
                  || it->sp > 1
-                 || !get_overlay_strings_1 (it, 0, 0))
+                 /* Don't call get_overlay_strings_1 if we already
+                    have overlay strings loaded, because doing so
+                    will load them again and push the iterator state
+                    onto the stack one more time, which is not
+                    expected by the rest of the code that processes
+                    overlay strings.  */
+                 || (it->n_overlay_strings <= 0
+                     ? !get_overlay_strings_1 (it, 0, 0)
+                     : 0))
                {
                  if (it->ellipsis_p)
                    setup_for_ellipsis (it, 0);
@@ -4681,7 +4690,19 @@
          if (!FRAME_WINDOW_P (it->f))
            /* If we return here, POSITION has been advanced
               across the text with this property.  */
-           return 1;
+           {
+             /* Synchronize the bidi iterator with POSITION.  This is
+                needed because we are not going to push the iterator
+                on behalf of this display property, so there will be
+                no pop_it call to do this synchronization for us.  */
+             if (it->bidi_p)
+               {
+                 it->position = *position;
+                 iterate_out_of_display_property (it);
+                 *position = it->position;
+               }
+             return 1;
+           }
        }
       else if (!frame_window_p)
        return 1;
@@ -4692,7 +4713,15 @@
          || !(fringe_bitmap = lookup_fringe_bitmap (value)))
        /* If we return here, POSITION has been advanced
           across the text with this property.  */
-       return 1;
+       {
+         if (it && it->bidi_p)
+           {
+             it->position = *position;
+             iterate_out_of_display_property (it);
+             *position = it->position;
+           }
+         return 1;
+       }
 
       if (it)
        {
@@ -5611,7 +5640,7 @@
 static void
 iterate_out_of_display_property (struct it *it)
 {
-  int buffer_p = BUFFERP (it->object);
+  int buffer_p = !STRINGP (it->string);
   EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
   EMACS_INT bob = (buffer_p ? BEGV : 0);
 
@@ -6780,6 +6809,16 @@
               && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
        }
     }
+  /* If we reached the end of the object we've been iterating (e.g., a
+     display string or an overlay string), and there's something on
+     IT->stack, proceed with what's on the stack.  It doesn't make
+     sense to return zero if there's unprocessed stuff on the stack,
+     because otherwise that stuff will never be displayed.  */
+  if (!success_p && it->sp > 0)
+    {
+      set_iterator_to_next (it, 0);
+      success_p = get_next_display_element (it);
+    }
 
   /* Value is 0 if end of buffer or string reached.  */
   return success_p;
@@ -6961,7 +7000,7 @@
          display vector entry (these entries may contain faces).  */
       it->face_id = it->saved_face_id;
 
-      if (it->dpvec + it->current.dpvec_index == it->dpend)
+      if (it->dpvec + it->current.dpvec_index >= it->dpend)
        {
          int recheck_faces = it->ellipsis_p;
 
@@ -6999,6 +7038,26 @@
     case GET_FROM_STRING:
       /* Current display element is a character from a Lisp string.  */
       xassert (it->s == NULL && STRINGP (it->string));
+      /* Don't advance past string end.  These conditions are true
+        when set_iterator_to_next is called at the end of
+        get_next_display_element, in which case the Lisp string is
+        already exhausted, and all we want is pop the iterator
+        stack.  */
+      if (it->current.overlay_string_index >= 0)
+       {
+         /* This is an overlay string, so there's no padding with
+            spaces, and the number of characters in the string is
+            where the string ends.  */
+         if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
+           goto consider_string_end;
+       }
+      else
+       {
+         /* Not an overlay string.  There could be padding, so test
+            against it->end_charpos . */
+         if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
+           goto consider_string_end;
+       }
       if (it->cmp_it.id >= 0)
        {
          int i;


reply via email to

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