aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2020-12-10 17:10:06 +0200
committerEli Zaretskii2020-12-10 17:10:06 +0200
commit97c2bca729862ef5f50b03997e47b63b97b0d2c2 (patch)
tree4e1679f014b17835cdd2fdfe5b9d157824e40ea3
parent6596b5541dd147749e2091953ac77bcd73c8d404 (diff)
downloademacs-97c2bca729862ef5f50b03997e47b63b97b0d2c2.tar.gz
emacs-97c2bca729862ef5f50b03997e47b63b97b0d2c2.zip
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)
-rw-r--r--src/xdisp.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index ed1d4761b95..689b87df421 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,
1925 /* If it3_moved stays false after the 'while' loop 1925 /* If it3_moved stays false after the 'while' loop
1926 below, that means we already were at a newline 1926 below, that means we already were at a newline
1927 before the loop (e.g., the display string begins 1927 before the loop (e.g., the display string begins
1928 with a newline), so we don't need to (and cannot) 1928 with a newline), so we don't need to return to
1929 inspect the glyphs of it3.glyph_row, because 1929 the last position before the display string,
1930 PRODUCE_GLYPHS will not produce anything for a 1930 because PRODUCE_GLYPHS will not produce anything
1931 newline, and thus it3.glyph_row stays at its 1931 for a newline. */
1932 stale content it got at top of the window. */
1933 bool it3_moved = false; 1932 bool it3_moved = false;
1933 int top_x_before_string = it3.current_x;
1934 /* Finally, advance the iterator until we hit the 1934 /* Finally, advance the iterator until we hit the
1935 first display element whose character position is 1935 first display element whose character position is
1936 CHARPOS, or until the first newline from the 1936 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,
1938 display line. */ 1938 display line. */
1939 while (get_next_display_element (&it3)) 1939 while (get_next_display_element (&it3))
1940 { 1940 {
1941 if (!EQ (it3.object, string))
1942 top_x_before_string = it3.current_x;
1941 PRODUCE_GLYPHS (&it3); 1943 PRODUCE_GLYPHS (&it3);
1942 if (IT_CHARPOS (it3) == charpos 1944 if (IT_CHARPOS (it3) == charpos
1943 || ITERATOR_AT_END_OF_LINE_P (&it3)) 1945 || ITERATOR_AT_END_OF_LINE_P (&it3))
@@ -1952,32 +1954,26 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1952 if (!it3.line_number_produced_p) 1954 if (!it3.line_number_produced_p)
1953 { 1955 {
1954 if (it3.lnum_pixel_width > 0) 1956 if (it3.lnum_pixel_width > 0)
1955 top_x += it3.lnum_pixel_width; 1957 {
1958 top_x += it3.lnum_pixel_width;
1959 top_x_before_string += it3.lnum_pixel_width;
1960 }
1956 else if (it.line_number_produced_p) 1961 else if (it.line_number_produced_p)
1957 top_x += it.lnum_pixel_width; 1962 {
1963 top_x += it.lnum_pixel_width;
1964 top_x_before_string += it3.lnum_pixel_width;
1965 }
1958 } 1966 }
1959 /* Normally, we would exit the above loop because we 1967 /* Normally, we would exit the above loop because we
1960 found the display element whose character 1968 found the display element whose character
1961 position is CHARPOS. For the contingency that we 1969 position is CHARPOS. For the contingency that we
1962 didn't, and stopped at the first newline from the 1970 didn't, and stopped at the first newline from the
1963 display string, move back over the glyphs 1971 display string, reset top_x to the coordinate of
1964 produced from the string, until we find the 1972 the rightmost glyph not from the string. */
1965 rightmost glyph not from the string. */
1966 if (it3_moved 1973 if (it3_moved
1967 && newline_in_string 1974 && newline_in_string
1968 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string)) 1975 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1969 { 1976 top_x = top_x_before_string;
1970 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1971 + it3.glyph_row->used[TEXT_AREA];
1972
1973 while (EQ ((g - 1)->object, string))
1974 {
1975 --g;
1976 top_x -= g->pixel_width;
1977 }
1978 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1979 + it3.glyph_row->used[TEXT_AREA]);
1980 }
1981 } 1977 }
1982 } 1978 }
1983 1979