Subject: Re: bug#32257: 26.1; read-multiple-choice inf loops on mouse clicks

From: Noam Postavsky <[email-masked]>
Date: Wed, 25 Jul 2018 21:25:46 -0400

Noam Postavsky <[email-masked]> writes:

> X-Debbugs-CC: Andy Moreton <[email-masked]>, Lars Ingebrigtsen <[email-masked]>
>
> Starting from emacs -Q, evaluate:
>
>     (require 'rmc)
>     (read-multiple-choice "choice? " '((?a "ay") (?b "bee") (?c "see")))
>
> then click the mouse somewhere instead of answering the prompt, notice
> Emacs maxing out CPU, hit C-g.  *Messages* will have a log of the prompt
> being repeated many times:
>
>     choice?  (ay, bee, [c] see, ?):  [4435 times]

The problem seems to be that read-char doesn't "use up" non-character
events, e.g., with the following:

(defun read-char-or-err ()
  (condition-case err
      (read-char)
    (error err)))

(list (read-char-or-err)
      (read-char-or-err)
      (read-char-or-err)
      (read-char-or-err)
      (read-char-or-err))

this returns ((error "Non-character input-event") (error "Non-character
input-event") ...) regardless of how many calls to read-char-or-err
there are.

The patch below fixes the inf looping, although it still doesn't allow
any other user interaction (unlike read-from-minibuffer).

--- i/lisp/emacs-lisp/rmc.el
+++ w/lisp/emacs-lisp/rmc.el
@@ -118,8 +118,10 @@ read-multiple-choice
                             choices)))
                   (condition-case nil
                       (let ((cursor-in-echo-area t))
-                        (read-char))
+                        (read-event))
                     (error nil))))
+          (unless (characterp tchar)
+            (setq tchar nil))
           (setq answer (lookup-key query-replace-map (vector tchar) t))
           (setq tchar
                 (cond