From 25f537216682eecedf3905c4e005f02be007ed9c Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Fri, 23 Aug 2024 10:27:12 +0200 Subject: [PATCH 1/3] Avoid putting a dead buffer in the minibuffer window (Bug#72487) * src/minibuf.c (minibuffer_unwind): Make sure that the buffer referenced by the first element of the list of previous buffers of the minibuffer window is live before assigning it to the minibuffer window (Bug#72487). * src/window.c (set_window_buffer): Assert that BUFFER is live. --- src/minibuf.c | 39 ++++++++++++++++++++++++--------------- src/window.c | 3 +++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/minibuf.c b/src/minibuf.c index 1dfee0a59c9..f16880011f7 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -63,7 +63,7 @@ Lisp_Object last_minibuf_string; static Lisp_Object minibuf_prompt; -/* The frame containinug the most recently opened Minibuffer. This is +/* The frame containing the most recently opened minibuffer. This is used only when `minibuffer-follows-selected-frame' is neither nil nor t. */ @@ -1248,27 +1248,36 @@ static void minibuffer_unwind (void) { struct frame *f; - struct window *w; - Lisp_Object window; - Lisp_Object entry; if (NILP (exp_MB_frame)) return; /* "Can't happen." */ f = XFRAME (exp_MB_frame); - window = f->minibuffer_window; - w = XWINDOW (window); if (FRAME_LIVE_P (f)) { - /* minibuf_window = sf->minibuffer_window; */ - if (!NILP (w->prev_buffers)) + Lisp_Object window = f->minibuffer_window; + + if (WINDOW_LIVE_P (window)) { - entry = Fcar (w->prev_buffers); - w->prev_buffers = Fcdr (w->prev_buffers); - set_window_buffer (window, Fcar (entry), 0, 0); - Fset_window_start (window, Fcar (Fcdr (entry)), Qnil); - Fset_window_point (window, Fcar (Fcdr (Fcdr (entry)))); + struct window *w = XWINDOW (window); + + /* minibuf_window = sf->minibuffer_window; */ + if (!NILP (w->prev_buffers)) + { + Lisp_Object entry = Fcar (w->prev_buffers); + + if (BUFFERP (Fcar (entry)) + && BUFFER_LIVE_P (XBUFFER (Fcar (entry)))) + { + wset_prev_buffers (w, Fcdr (w->prev_buffers)); + set_window_buffer (window, Fcar (entry), 0, 0); + Fset_window_start (window, Fcar (Fcdr (entry)), Qnil); + Fset_window_point (window, Fcar (Fcdr (Fcdr (entry)))); + } + else + set_window_buffer (window, nth_minibuffer (0), 0, 0); + } + else + set_window_buffer (window, nth_minibuffer (0), 0, 0); } - else - set_window_buffer (window, nth_minibuffer (0), 0, 0); } } diff --git a/src/window.c b/src/window.c index ff28bac5306..dba2d6a3523 100644 --- a/src/window.c +++ b/src/window.c @@ -4123,6 +4123,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, specpdl_ref count = SPECPDL_INDEX (); bool samebuf = EQ (buffer, w->contents); + /* It's never OK to assign WINDOW a dead buffer. */ + eassert (BUFFER_LIVE_P (b)); + wset_buffer (w, buffer); if (EQ (window, selected_window)) From 44c26140b6e86f67f99d4ed9cc30e95f46708641 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Fri, 23 Aug 2024 17:15:32 +0200 Subject: [PATCH 2/3] ; Fix infloop in checkdoc-next-docstring * lisp/emacs-lisp/checkdoc.el (checkdoc-next-docstring): Use 'beginning-of-defun-raw' instead of 'beginning-of-defun', as the latter always moves back to beginning of line and thus is not guaranteed to advance point when 'open-paren-in-column-0-is-defun-start' is non-nil. (Bug#72759) --- lisp/emacs-lisp/checkdoc.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index fd25b0f981f..21d40c56e74 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -986,7 +986,7 @@ buffer and save warnings in a separate buffer." Return nil if there are no more doc strings." (let (found) (while (and (not (setq found (checkdoc--next-docstring))) - (beginning-of-defun -1))) + (beginning-of-defun-raw -1))) found)) (defun checkdoc--next-docstring () From 4211d85eec0858583bd9d35f8de9cd6e358d6c72 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 24 Aug 2024 12:07:02 +0300 Subject: [PATCH 3/3] Fix rare segfaults due to freed fontsets * src/xfaces.c (recompute_basic_faces): Force complete recalculation of all the faces. (Bug#72692) --- src/xfaces.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/xfaces.c b/src/xfaces.c index 684b6ccfac7..34897817ffd 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -736,6 +736,11 @@ recompute_basic_faces (struct frame *f) clear_face_cache (false); if (!realize_basic_faces (f)) emacs_abort (); + /* Force complete face recalculation next time we use the display + code, because realize_basic_faces could free the fontset used + by non-ASCII faces corresponding to ASCII faces of the basic + faces, and attempt to use that fontset might segfault. */ + f->face_change = true; } }