changeset 107809:b4880c984e2f

Fix bug#5856: don't dereference glyphs beyond end of glyph_row. xdisp.c (set_cursor_from_row): Don't dereference glyphs beyond the end of TEXT_AREA. (Bug#5856)
author Eli Zaretskii <eliz@gnu.org>
date Fri, 09 Apr 2010 00:14:33 +0300
parents 0a321c28c1b4
children 03ef65bf2e25 29a7e4af9d84 0346e41d1e53
files src/ChangeLog src/xdisp.c
diffstat 2 files changed, 18 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Thu Apr 08 15:59:46 2010 -0400
+++ b/src/ChangeLog	Fri Apr 09 00:14:33 2010 +0300
@@ -1,3 +1,8 @@
+2010-04-08  Eli Zaretskii  <eliz@gnu.org>
+
+	* xdisp.c (set_cursor_from_row): Don't dereference glyphs beyond
+	the end of TEXT_AREA.  (Bug#5856)
+
 2010-04-08  Jan Djärv  <jan.h.d@swipnet.se>
 
 	* xsettings.c (XSETTINGS_FONT_NAME): Move XSETTINGS_FONT_NAME out of
--- a/src/xdisp.c	Thu Apr 08 15:59:46 2010 -0400
+++ b/src/xdisp.c	Fri Apr 09 00:14:33 2010 +0300
@@ -12553,6 +12553,9 @@
   EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
   EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
   struct glyph *glyph_before = glyph - 1, *glyph_after = end;
+  /* A glyph beyond the edge of TEXT_AREA which we should never
+     touch.  */
+  struct glyph *glyphs_end = end;
   /* Non-zero means we've found a match for cursor position, but that
      glyph has the avoid_cursor_p flag set.  */
   int match_with_avoid_cursor = 0;
@@ -12594,7 +12597,7 @@
 
 	  /* If the glyph row is reversed, we need to process it from back
 	     to front, so swap the edge pointers.  */
-	  end = glyph - 1;
+	  glyphs_end = end = glyph - 1;
 	  glyph += row->used[TEXT_AREA] - 1;
 	  /* Reverse the known positions in the row.  */
 	  last_pos = pos_after = MATRIX_ROW_START_CHARPOS (row) + delta;
@@ -12772,7 +12775,8 @@
   /* Step 2: If we didn't find an exact match for point, we need to
      look for a proper place to put the cursor among glyphs between
      GLYPH_BEFORE and GLYPH_AFTER.  */
-  if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
+  if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
+	&& BUFFERP (glyph->object) && glyph->charpos == pt_old)
       && bpos_covered < pt_old)
     {
       if (row->ends_in_ellipsis_p && pos_after == last_pos)
@@ -12938,9 +12942,15 @@
       struct glyph *g1 =
 	MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
 
+      /* Don't consider glyphs that are outside TEXT_AREA.  */
+      if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
+	return 0;
       /* Keep the candidate whose buffer position is the closest to
 	 point.  */
-      if (BUFFERP (g1->object)
+      if (/* previous candidate is a glyph in TEXT_AREA of that row */
+	  w->cursor.hpos >= 0
+	  && w->cursor.hpos < MATRIX_ROW_USED(matrix, w->cursor.vpos)
+	  && BUFFERP (g1->object)
 	  && (g1->charpos == pt_old /* an exact match always wins */
 	      || (BUFFERP (glyph->object)
 		  && eabs (g1->charpos - pt_old)