]> git.eshelyaron.com Git - emacs.git/commitdiff
nadvice.el: Avoid exponential blow up in interactive-form recursion
authorStefan Monnier <monnier@iro.umontreal.ca>
Sat, 13 Aug 2022 16:03:22 +0000 (12:03 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Sat, 13 Aug 2022 16:04:29 +0000 (12:04 -0400)
* lisp/emacs-lisp/nadvice.el (advice--interactive-form): Sink the call
to `commandp` into the autoloaded function case since it's redundant in
the other branch.
(advice--make-interactive-form): Take just the interactive forms rather
than the actual functions as arguments.
(oclosure-interactive-form): Use `advice--interactive-form` rather than
`commandp` since we'd call `advice--interactive-form` afterwards anyway.

lisp/emacs-lisp/nadvice.el

index 2d5a1b5e77b987318eda71355328abf17b0a6056..86f26fc0d84091f35d3c2c9ce3dac745cda0d194 100644 (file)
@@ -167,31 +167,31 @@ DOC is a string where \"FUNCTION\" and \"OLDFUN\" are expected.")
 
 (defun advice--interactive-form (function)
   "Like `interactive-form' but tries to avoid autoloading functions."
-  (when (commandp function)
-    (if (not (and (symbolp function) (autoloadp (indirect-function function))))
-        (interactive-form function)
-      `(interactive (advice-eval-interactive-spec
+  (if (not (and (symbolp function) (autoloadp (indirect-function function))))
+      (interactive-form function)
+    (when (commandp function)
+      `(interactive (advice--eval-interactive-spec
                      (cadr (interactive-form ',function)))))))
 
-(defun advice--make-interactive-form (function main)
+(defun advice--make-interactive-form (iff ifm)
   ;; TODO: make it so that interactive spec can be a constant which
   ;; dynamically checks the advice--car/cdr to do its job.
   ;; For that, advice-eval-interactive-spec needs to be more faithful.
-  (let* ((iff (advice--interactive-form function))
-         (ifm (advice--interactive-form main))
-         (fspec (cadr iff)))
+  (let* ((fspec (cadr iff)))
     (when (eq 'function (car-safe fspec)) ;; Macroexpanded lambda?
-      (setq fspec (nth 1 fspec)))
+      (setq fspec (eval fspec t)))
     (if (functionp fspec)
         `(funcall ',fspec ',(cadr ifm))
       (cadr (or iff ifm)))))
 
 
 (cl-defmethod oclosure-interactive-form ((ad advice) &optional _)
-  (let ((car (advice--car ad))
-        (cdr (advice--cdr ad)))
-    (when (or (commandp car) (commandp cdr))
-      `(interactive ,(advice--make-interactive-form car cdr)))))
+  (let* ((car (advice--car ad))
+         (cdr (advice--cdr ad))
+         (ifa (advice--interactive-form car))
+         (ifd (advice--interactive-form cdr)))
+    (when (or ifa ifd)
+      `(interactive ,(advice--make-interactive-form ifa ifd)))))
 
 (cl-defmethod cl-print-object ((object advice) stream)
   (cl-assert (advice--p object))