Subject: bug#3287: GNU/Emacs bug when typed in prompt password fields using keypad

From: Borja Tarraso Hueso <[email-masked]>
Date: Thu, 14 May 2009 16:52:51 +0100

Hi people,

I just found a bug when is used keypad under password input field in emacs,
that's not doing anything, so these diffs provided by Stefan and slightly
modified by us, to handle C-g case, fix the problem<[email-masked]>
.

==> Bug:

Under GNU/Linux trying to write numbers using keypad in a prompt input
password field does not works. This is not happening under Windows OS. Not
other OS tested.

This is reproducible in any gnu/emacs version from cvs (e.g. 23.0.90.2).

==> Fix:

Usage of read-key instead read-event. As read-key is getting each key but
not inserted and handled until pressed return, so we should take care about
C-g case as well to provide user's cancellation.

==> Diffs:

*** emacs/lisp/subr.el  2009-02-14 09:06:56.000000000 +0000
--- emacs_hack/lisp/subr.el     2009-05-14 01:29:52.000000000 +0100
***************
*** 1721,1726 ****
--- 1721,1767 ----
- Mostrar texto citado -

 ;;;; Input and display facilities.

+ (defconst read-key-empty-map (make-sparse-keymap))
+ (defvar read-key-delay 0.1)
+
+ (defun read-key (&optional prompt)
+   "Read a key from the keyboard.
+ Contrary to `read-event' this will not return a raw event but instead will
+ obey the input decoding and translations usually done by
`read-key-sequence'.
+ So escape sequences and keyboard encoding are taken into account.
+ When there's an ambiguity because the key looks like the prefix of
+ some sort of escape sequence, the ambiguity is resolved via
`read-key-delay'."
+   (let ((overriding-terminal-local-map read-key-empty-map)
+       (overriding-local-map nil)
+       (old-global-map (current-global-map))
+         (timer (run-with-idle-timer
+                 ;; Wait long enough that Emacs has the time to receive and
+                 ;; process all the raw events associated with the
single-key.
+                 ;; But don't wait too long, or the user may find the delay
+                 ;; annoying (or keep hitting more keys which may then get
+                 ;; lost or misinterpreted).
+                 ;; This is only relevant for keys which Emacs perceives as
+                 ;; "prefixes", such as C-x (because of the C-x 8 map in
+                 ;; key-translate-table and the C-x @ map in
function-key-map)
+                 ;; or ESC (because of terminal escape sequences in
+                 ;; input-decode-map).
+                 read-key-delay t
+                 (lambda ()
+                   (let ((keys (this-command-keys-vector)))
+                     (unless (zerop (length keys))
+                       ;; `keys' is non-empty, so the user has hit at least
+                       ;; one key; there's no point waiting any longer,
even
+                       ;; though read-key-sequence thinks we should wait
+                       ;; for more input to decide how to interpret the
+                       ;; current input.
+                       (throw 'read-key keys)))))))
+     (unwind-protect
+         (progn
+         (use-global-map read-key-empty-map)
+         (aref (catch 'read-key (read-key-sequence prompt nil t)) 0))
+       (cancel-timer timer)
+       (use-global-map old-global-map))))
+
 (defvar read-quoted-char-radix 8
   "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
 Legitimate radix values are 8, 10 and 16.")
***************
*** 1837,1846 ****
        (while (progn (message "%s%s"
                              prompt
                              (make-string (length pass) ?.))
!                     ;; We used to use read-char-exclusive, but that
!                     ;; gives funny behavior when the user presses,
!                     ;; e.g., the arrow keys.
!                     (setq c (read-event nil t))
                      (not (memq c stop-keys)))
         (clear-this-command-keys)
         (cond ((memq c rubout-keys) ; rubout
--- 1878,1884 ----
        (while (progn (message "%s%s"
                              prompt
                              (make-string (length pass) ?.))
!                     (setq c (read-key))
                      (not (memq c stop-keys)))
         (clear-this-command-keys)
         (cond ((memq c rubout-keys) ; rubout
***************
*** 1848,1855 ****
                  (let ((new-pass (substring pass 0 -1)))
                     (and (arrayp pass) (clear-string pass))
                    (setq pass new-pass))))
               ((not (numberp c)))
!               ((= c ?\C-u) ; kill line
                (and (arrayp pass) (clear-string pass))
                 (setq pass ""))
               ((= c ?\C-y) ; yank
--- 1886,1895 ----
                  (let ((new-pass (substring pass 0 -1)))
                     (and (arrayp pass) (clear-string pass))
                    (setq pass new-pass))))
+               ((eq c ?\C-g)
+                (keyboard-quit))
               ((not (numberp c)))
!               ((eq c ?\C-u) ; kill line
                 (and (arrayp pass) (clear-string pass))
                 (setq pass ""))
               ((= c ?\C-y) ; yank

==> End.

Thanks!

Borja Tarraso