From fbcaa2f3880fc9fc3a84182a0061fbdcf32ba19e Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 28 Sep 2011 17:37:27 +0300 Subject: [PATCH] Fix bug #9624 with crashes in Muse mode. src/xdisp.c (compute_display_string_end): If there's no display string at CHARPOS, return -1. src/bidi.c (bidi_fetch_char): When compute_display_string_end returns a negative value, treat the character as a normal character not covered by a display string. --- src/ChangeLog | 9 +++++++++ src/bidi.c | 10 ++++++++++ src/xdisp.c | 23 +++++++++++++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c6a321de2d..f26754d113 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2011-09-28 Eli Zaretskii + + * xdisp.c (compute_display_string_end): If there's no display + string at CHARPOS, return -1. + + * bidi.c (bidi_fetch_char): When compute_display_string_end + returns a negative value, treat the character as a normal + character not covered by a display string. (Bug#9624) + 2011-09-28 Juanma Barranquero * lread.c (Fread_from_string): Fix typo in docstring. diff --git a/src/bidi.c b/src/bidi.c index 599c00449b..e3fc03f4a9 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -974,6 +974,15 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, ch = 0xFFFC; } disp_end_pos = compute_display_string_end (*disp_pos, string); + if (disp_end_pos < 0) + { + /* Somebody removed the display string from the buffer + behind our back. Recover by processing this buffer + position as if no display property were present there to + begin with. */ + *disp_prop = 0; + goto normal_char; + } *nchars = disp_end_pos - *disp_pos; if (*nchars <= 0) abort (); @@ -988,6 +997,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, } else { + normal_char: if (string->s) { int len; diff --git a/src/xdisp.c b/src/xdisp.c index 75f266ff73..a072ff2c17 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -3386,9 +3386,10 @@ compute_display_string_pos (struct text_pos *position, } /* Return the character position of the end of the display string that - started at CHARPOS. A display string is either an overlay with - `display' property whose value is a string or a `display' text - property whose value is a string. */ + started at CHARPOS. If there's no display string at CHARPOS, + return -1. A display string is either an overlay with `display' + property whose value is a string or a `display' text property whose + value is a string. */ EMACS_INT compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string) { @@ -3402,8 +3403,22 @@ compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string) if (charpos >= eob || (string->s && !STRINGP (object))) return eob; + /* It could happen that the display property or overlay was removed + since we found it in compute_display_string_pos above. One way + this can happen is if JIT font-lock was called (through + handle_fontified_prop), and jit-lock-functions remove text + properties or overlays from the portion of buffer that includes + CHARPOS. Muse mode is known to do that, for example. In this + case, we return -1 to the caller, to signal that no display + string is actually present at CHARPOS. See bidi_fetch_char for + how this is handled. + + An alternative would be to never look for display properties past + it->stop_charpos. But neither compute_display_string_pos nor + bidi_fetch_char that calls it know or care where the next + stop_charpos is. */ if (NILP (Fget_char_property (pos, Qdisplay, object))) - abort (); + return -1; /* Look forward for the first character where the `display' property changes. */ -- 2.20.1