diff options
| author | Eli Zaretskii | 2011-09-28 17:37:27 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-09-28 17:37:27 +0300 |
| commit | fbcaa2f3880fc9fc3a84182a0061fbdcf32ba19e (patch) | |
| tree | 9816adc66a3bb1b20332f4463613a34c9e14cd93 | |
| parent | 0a40c0609bf7dc47b68f13178ff07334f7dde349 (diff) | |
| download | emacs-fbcaa2f3880fc9fc3a84182a0061fbdcf32ba19e.tar.gz emacs-fbcaa2f3880fc9fc3a84182a0061fbdcf32ba19e.zip | |
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.
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/bidi.c | 10 | ||||
| -rw-r--r-- | src/xdisp.c | 23 |
3 files changed, 38 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c6a321de2dd..f26754d1135 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2011-09-28 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (compute_display_string_end): If there's no display | ||
| 4 | string at CHARPOS, return -1. | ||
| 5 | |||
| 6 | * bidi.c (bidi_fetch_char): When compute_display_string_end | ||
| 7 | returns a negative value, treat the character as a normal | ||
| 8 | character not covered by a display string. (Bug#9624) | ||
| 9 | |||
| 1 | 2011-09-28 Juanma Barranquero <lekktu@gmail.com> | 10 | 2011-09-28 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 11 | ||
| 3 | * lread.c (Fread_from_string): Fix typo in docstring. | 12 | * lread.c (Fread_from_string): Fix typo in docstring. |
diff --git a/src/bidi.c b/src/bidi.c index 599c00449b5..e3fc03f4a9b 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, | |||
| 974 | ch = 0xFFFC; | 974 | ch = 0xFFFC; |
| 975 | } | 975 | } |
| 976 | disp_end_pos = compute_display_string_end (*disp_pos, string); | 976 | disp_end_pos = compute_display_string_end (*disp_pos, string); |
| 977 | if (disp_end_pos < 0) | ||
| 978 | { | ||
| 979 | /* Somebody removed the display string from the buffer | ||
| 980 | behind our back. Recover by processing this buffer | ||
| 981 | position as if no display property were present there to | ||
| 982 | begin with. */ | ||
| 983 | *disp_prop = 0; | ||
| 984 | goto normal_char; | ||
| 985 | } | ||
| 977 | *nchars = disp_end_pos - *disp_pos; | 986 | *nchars = disp_end_pos - *disp_pos; |
| 978 | if (*nchars <= 0) | 987 | if (*nchars <= 0) |
| 979 | abort (); | 988 | abort (); |
| @@ -988,6 +997,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, | |||
| 988 | } | 997 | } |
| 989 | else | 998 | else |
| 990 | { | 999 | { |
| 1000 | normal_char: | ||
| 991 | if (string->s) | 1001 | if (string->s) |
| 992 | { | 1002 | { |
| 993 | int len; | 1003 | int len; |
diff --git a/src/xdisp.c b/src/xdisp.c index 75f266ff739..a072ff2c171 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3386,9 +3386,10 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3386 | } | 3386 | } |
| 3387 | 3387 | ||
| 3388 | /* Return the character position of the end of the display string that | 3388 | /* Return the character position of the end of the display string that |
| 3389 | started at CHARPOS. A display string is either an overlay with | 3389 | started at CHARPOS. If there's no display string at CHARPOS, |
| 3390 | `display' property whose value is a string or a `display' text | 3390 | return -1. A display string is either an overlay with `display' |
| 3391 | property whose value is a string. */ | 3391 | property whose value is a string or a `display' text property whose |
| 3392 | value is a string. */ | ||
| 3392 | EMACS_INT | 3393 | EMACS_INT |
| 3393 | compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string) | 3394 | compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string) |
| 3394 | { | 3395 | { |
| @@ -3402,8 +3403,22 @@ compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string) | |||
| 3402 | if (charpos >= eob || (string->s && !STRINGP (object))) | 3403 | if (charpos >= eob || (string->s && !STRINGP (object))) |
| 3403 | return eob; | 3404 | return eob; |
| 3404 | 3405 | ||
| 3406 | /* It could happen that the display property or overlay was removed | ||
| 3407 | since we found it in compute_display_string_pos above. One way | ||
| 3408 | this can happen is if JIT font-lock was called (through | ||
| 3409 | handle_fontified_prop), and jit-lock-functions remove text | ||
| 3410 | properties or overlays from the portion of buffer that includes | ||
| 3411 | CHARPOS. Muse mode is known to do that, for example. In this | ||
| 3412 | case, we return -1 to the caller, to signal that no display | ||
| 3413 | string is actually present at CHARPOS. See bidi_fetch_char for | ||
| 3414 | how this is handled. | ||
| 3415 | |||
| 3416 | An alternative would be to never look for display properties past | ||
| 3417 | it->stop_charpos. But neither compute_display_string_pos nor | ||
| 3418 | bidi_fetch_char that calls it know or care where the next | ||
| 3419 | stop_charpos is. */ | ||
| 3405 | if (NILP (Fget_char_property (pos, Qdisplay, object))) | 3420 | if (NILP (Fget_char_property (pos, Qdisplay, object))) |
| 3406 | abort (); | 3421 | return -1; |
| 3407 | 3422 | ||
| 3408 | /* Look forward for the first character where the `display' property | 3423 | /* Look forward for the first character where the `display' property |
| 3409 | changes. */ | 3424 | changes. */ |