]> git.eshelyaron.com Git - emacs.git/commitdiff
* src/keyboard.c (safe_run_hook_funcall): Fix recent regression
authorStefan Monnier <monnier@iro.umontreal.ca>
Thu, 8 Sep 2022 20:12:01 +0000 (16:12 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Thu, 8 Sep 2022 20:12:01 +0000 (16:12 -0400)
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

src/keyboard.c

index 77280d08c5bf77c72cace0c44df276aac9a2946e..f562b71d3179c91044360855b63908d976ce3434 100644 (file)
@@ -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;
 }