Merge from origin/emacs-31

df2508a8f6 Remove from CC Mode code that modifies 'major-mode-remap-...
3106dc7766 Assert we don't double-free timers (bug#81108)
90314895dd Don't cancel random timers in x_get_foreign_selection (bu...
5cd7785b0a Fix use-after-free in Ffuncall_with_delayed_message (bug#...
This commit is contained in:
Sean Whitton 2026-06-08 15:36:23 +01:00
commit 8636e39abb
5 changed files with 52 additions and 32 deletions

View file

@ -3401,22 +3401,6 @@ Key bindings:
(insert (format "Buffer Style: %s\nc-emacs-features: %s\n"
style c-features)))))))
;; Make entries in `major-mode-remap-defaults' to ensure that when CC
;; Mode has been loaded, the symbols `c-mode' etc., will call CC Mode's
;; modes rather than c-ts-mode etc..
(when (boundp 'major-mode-remap-defaults)
(add-to-list 'major-mode-remap-defaults '(c++-mode . c++-ts-mode))
(add-to-list 'major-mode-remap-defaults '(c-mode . c-ts-mode))
(add-to-list 'major-mode-remap-defaults '(c-or-c++-mode . c-or-c++-ts-mode))
(let (entry)
(dolist (mode '(c-mode c++-mode c-or-c++-mode))
(if (and (setq entry (assq mode major-mode-remap-defaults))
(null (cdr entry)))
(setq major-mode-remap-defaults
(delq entry major-mode-remap-defaults)))
(push (cons mode nil) major-mode-remap-defaults))))
(cc-provide 'cc-mode)

View file

@ -201,6 +201,9 @@ cancel_atimer (struct atimer *timer)
}
}
/* We shouldn't be called with timers which aren't on either list. */
eassert (i != 2);
unblock_atimers (&oldset);
}

View file

@ -1220,17 +1220,34 @@ usage: (while TEST BODY...) */)
return Qnil;
}
struct funcall_with_delayed_message_data
{
Lisp_Object *message;
struct atimer *timer;
};
static void
with_delayed_message_display (struct atimer *timer)
{
message3 (build_string (timer->client_data));
struct funcall_with_delayed_message_data *data
= timer->client_data;
if (data->timer)
{
message3 (*data->message);
data->timer = NULL;
}
}
static void
with_delayed_message_cancel (void *timer)
with_delayed_message_cancel (void *datap)
{
xfree (((struct atimer *) timer)->client_data);
cancel_atimer (timer);
struct funcall_with_delayed_message_data *data
= datap;
if (data->timer)
{
cancel_atimer (data->timer);
data->timer = NULL;
}
}
DEFUN ("funcall-with-delayed-message",
@ -1251,10 +1268,12 @@ is not displayed. */)
/* Set up the atimer. */
struct timespec interval = dtotimespec (XFLOATINT (timeout));
struct atimer *timer = start_atimer (ATIMER_RELATIVE, interval,
with_delayed_message_display,
xstrdup (SSDATA (message)));
record_unwind_protect_ptr (with_delayed_message_cancel, timer);
struct funcall_with_delayed_message_data data
= { .message = &message };
data.timer = start_atimer (ATIMER_RELATIVE, interval,
with_delayed_message_display,
&data);
record_unwind_protect_ptr (with_delayed_message_cancel, &data);
Lisp_Object result = calln (function);

View file

@ -981,15 +981,22 @@ static void
pgtk_display_selection_waiting_message (struct atimer *timer)
{
Lisp_Object val;
struct atimer **atimerp = timer->client_data;
val = build_string ("Waiting for reply from selection owner...");
message3_nolog (val);
*atimerp = NULL;
}
static void
pgtk_cancel_atimer (void *atimer)
pgtk_cancel_atimer (void *atimerp)
{
cancel_atimer (atimer);
struct atimer **atimer = atimerp;
if (*atimer)
{
cancel_atimer (*atimer);
*atimer = NULL;
}
}
@ -1044,8 +1051,8 @@ pgtk_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_typ
message_interval = make_timespec (1, 0);
delayed_message = start_atimer (ATIMER_RELATIVE, message_interval,
pgtk_display_selection_waiting_message,
NULL);
record_unwind_protect_ptr (pgtk_cancel_atimer, delayed_message);
&delayed_message);
record_unwind_protect_ptr (pgtk_cancel_atimer, &delayed_message);
/* This allows quits. Also, don't wait forever. */
intmax_t timeout = max (0, pgtk_selection_timeout);

View file

@ -1631,15 +1631,22 @@ static void
x_display_selection_waiting_message (struct atimer *timer)
{
Lisp_Object val;
struct atimer **atimerp = timer->client_data;
val = build_string ("Waiting for reply from selection owner...");
message3_nolog (val);
*atimerp = NULL;
}
static void
x_cancel_atimer (void *atimer)
x_cancel_atimer (void *atimerp)
{
cancel_atimer (atimer);
struct atimer **atimer = atimerp;
if (*atimer)
{
cancel_atimer (*atimer);
*atimer = NULL;
}
}
@ -1708,8 +1715,8 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
message_interval = make_timespec (1, 0);
delayed_message = start_atimer (ATIMER_RELATIVE, message_interval,
x_display_selection_waiting_message,
NULL);
record_unwind_protect_ptr (x_cancel_atimer, delayed_message);
&delayed_message);
record_unwind_protect_ptr (x_cancel_atimer, &delayed_message);
/* This allows quits. Also, don't wait forever. */
intmax_t timeout = max (0, x_selection_timeout);