From: Stefan Monnier Date: Thu, 8 Sep 2022 20:12:01 +0000 (-0400) Subject: * src/keyboard.c (safe_run_hook_funcall): Fix recent regression X-Git-Tag: emacs-29.0.90~1856^2~660 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=15e09908053400815e1b4127fa7a4e1ed9ef6253;p=emacs.git * src/keyboard.c (safe_run_hook_funcall): Fix recent regression The mutation of `args` was unsafe because that array was later reused (and assumed unchanged) by the caller. https://lists.gnu.org/archive/html/emacs-devel/2022-09/msg00329.html --- diff --git a/src/keyboard.c b/src/keyboard.c index 77280d08c5b..f562b71d317 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1880,13 +1880,22 @@ safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) static Lisp_Object safe_run_hook_funcall (ptrdiff_t nargs, Lisp_Object *args) { - eassert (nargs >= 2); /* We need to swap args[0] and args[1] here or in `safe_run_hooks_1`. It's more convenient to do it here. */ + eassert (nargs >= 2); Lisp_Object fun = args[0], hook = args[1]; - args[0] = hook, args[1] = fun; - internal_condition_case_n (safe_run_hooks_1, nargs, args, + /* The `nargs` array cannot be mutated safely here because it is + reused by our caller `run_hook_with_args`. + We could arguably change it temporarily if we set it back + to its original state before returning, but it's too ugly. */ + USE_SAFE_ALLOCA; + Lisp_Object *newargs; + SAFE_ALLOCA_LISP (newargs, nargs); + newargs[0] = hook, newargs[1] = fun; + memcpy (args + 2, newargs + 2, (nargs - 2) * word_size); + internal_condition_case_n (safe_run_hooks_1, nargs, newargs, Qt, safe_run_hooks_error); + SAFE_FREE (); return Qnil; }