From 5e56adc338001d425415fa52b65054669849cced Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 1 Aug 2024 14:01:17 +0300 Subject: [PATCH] Avoid aborts when buffer is modified during its redisplay * src/xdisp.c (redisplay_window): Restore point from saved byte position only if the buffer was not changed meanwhile. (Bug#72165) (cherry picked from commit ef5466c267542970f28548c820783f3257c1b0cf) --- src/xdisp.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/xdisp.c b/src/xdisp.c index 491ce9cc970..6f29f159d16 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -20007,6 +20007,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) int frame_line_height, margin; bool use_desired_matrix; void *itdata = NULL; + modiff_count lchars_modiff = CHARS_MODIFF, ochars_modiff = lchars_modiff; SET_TEXT_POS (lpoint, PT, PT_BYTE); opoint = lpoint; @@ -20100,6 +20101,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) end_unchanged = END_UNCHANGED; SET_TEXT_POS (opoint, PT, PT_BYTE); + ochars_modiff = CHARS_MODIFF; specbind (Qinhibit_point_motion_hooks, Qt); @@ -21132,14 +21134,28 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE); else if (CHARPOS (opoint) > ZV) TEMP_SET_PT_BOTH (Z, Z_BYTE); - else + else if (ochars_modiff == CHARS_MODIFF) TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint)); - + else + { + /* If the buffer was modified while we were redisplaying it, we + cannot trust the correspondence between character and byte + positions. This can happen, for example, if we are + redisplaying *Messages* and some Lisp, perhaps invoked by + display_mode_lines, signals an error which caused something + added/deleted to/from the buffer text. */ + TEMP_SET_PT_BOTH (CHARPOS (opoint), CHAR_TO_BYTE (CHARPOS (opoint))); + } set_buffer_internal_1 (old); /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become shorter. This can be caused by log truncation in *Messages*. */ if (CHARPOS (lpoint) <= ZV) - TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); + { + if (lchars_modiff == CHARS_MODIFF) + TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); + else + TEMP_SET_PT_BOTH (CHARPOS (lpoint), CHAR_TO_BYTE (CHARPOS (lpoint))); + } unbind_to (count, Qnil); } -- 2.39.2