emacs-diffs
[Top][All Lists]
Advanced

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

master 97c2bca: Avoid segfaults in pos_visible_p


From: Eli Zaretskii
Subject: master 97c2bca: Avoid segfaults in pos_visible_p
Date: Thu, 10 Dec 2020 10:11:22 -0500 (EST)

branch: master
commit 97c2bca729862ef5f50b03997e47b63b97b0d2c2
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    Avoid segfaults in pos_visible_p
    
    * src/xdisp.c (pos_visible_p): Don't try accessing the glyphs
    produced by iterator whose glyph_row was set to NULL; instead,
    record the X coordinate before the display string when moving past
    it, and use the recorded coordinate if needed.  (Bug#45156)
---
 src/xdisp.c | 40 ++++++++++++++++++----------------------
 1 file changed, 18 insertions(+), 22 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index ed1d476..689b87d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1925,12 +1925,12 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int 
*x, int *y,
                  /* If it3_moved stays false after the 'while' loop
                     below, that means we already were at a newline
                     before the loop (e.g., the display string begins
-                    with a newline), so we don't need to (and cannot)
-                    inspect the glyphs of it3.glyph_row, because
-                    PRODUCE_GLYPHS will not produce anything for a
-                    newline, and thus it3.glyph_row stays at its
-                    stale content it got at top of the window.  */
+                    with a newline), so we don't need to return to
+                    the last position before the display string,
+                    because PRODUCE_GLYPHS will not produce anything
+                    for a newline.  */
                  bool it3_moved = false;
+                 int top_x_before_string = it3.current_x;
                  /* Finally, advance the iterator until we hit the
                     first display element whose character position is
                     CHARPOS, or until the first newline from the
@@ -1938,6 +1938,8 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int 
*x, int *y,
                     display line.  */
                  while (get_next_display_element (&it3))
                    {
+                     if (!EQ (it3.object, string))
+                       top_x_before_string = it3.current_x;
                      PRODUCE_GLYPHS (&it3);
                      if (IT_CHARPOS (it3) == charpos
                          || ITERATOR_AT_END_OF_LINE_P (&it3))
@@ -1952,32 +1954,26 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int 
*x, int *y,
                  if (!it3.line_number_produced_p)
                    {
                      if (it3.lnum_pixel_width > 0)
-                       top_x += it3.lnum_pixel_width;
+                       {
+                         top_x += it3.lnum_pixel_width;
+                         top_x_before_string += it3.lnum_pixel_width;
+                       }
                      else if (it.line_number_produced_p)
-                       top_x += it.lnum_pixel_width;
+                       {
+                         top_x += it.lnum_pixel_width;
+                         top_x_before_string += it3.lnum_pixel_width;
+                       }
                    }
                  /* Normally, we would exit the above loop because we
                     found the display element whose character
                     position is CHARPOS.  For the contingency that we
                     didn't, and stopped at the first newline from the
-                    display string, move back over the glyphs
-                    produced from the string, until we find the
-                    rightmost glyph not from the string.  */
+                    display string, reset top_x to the coordinate of
+                    the rightmost glyph not from the string.  */
                  if (it3_moved
                      && newline_in_string
                      && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
-                   {
-                     struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
-                                       + it3.glyph_row->used[TEXT_AREA];
-
-                     while (EQ ((g - 1)->object, string))
-                       {
-                         --g;
-                         top_x -= g->pixel_width;
-                       }
-                     eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
-                                   + it3.glyph_row->used[TEXT_AREA]);
-                   }
+                   top_x = top_x_before_string;
                }
            }
 



reply via email to

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