emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Possible emacs bug when type password fields


From: Borja Tarraso
Subject: Re: Possible emacs bug when type password fields
Date: Thu, 14 May 2009 01:35:26 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.91 (gnu/linux)

Hi Stefan,

I was looking at the code with some friend. Adding some extra condition
to catch C-g problem is fixed.

The problem was in read-key function; this function does not control C-g as
it is using read-key-sequence (as documentation is menction: "A C-g
typed while in this function is treated like any other character, and
`quit-flag' is not set") so it explains why this is happening, as
is not reading each key and inserting, instead of that, it allows to the
user writing on that buffer and obtaining the content later.

Probably lots of things have dependency of read-key, for this reason it
was added this extra condition... but i don't know really if it's the
best solution.


==> Full 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 ----
  

  ;;;; 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

Stefan Monnier <address@hidden> writes:

>> Near :-) this time works fine, i can write from the beginning, however
>> C-g stills does not work, when I press C-g it writes another additional
>> character.
>
> Hmm... this is odd, I cannot reproduce it.  Can you try and single-step
> through that code to see why the (eq c ?\C-g) test fails?
> To do that, just move point to inside the function and hit C-u M-C-x
> (which marks the function for interactive debugging) and then do
> M-: (read-password "toto: ").
> Once in the debugger, use `n' or SPC to advance through the code.
>
>
>         Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]