GNU bug report logs - #26699
26.0.50; Allow non-string keys in password-cache

Previous Next

Package: emacs;

Reported by: Stefan Monnier <monnier <at> iro.umontreal.ca>

Date: Fri, 28 Apr 2017 16:43:02 UTC

Severity: minor

Tags: patch

Found in version 26.0.50

Done: Stefan Monnier <monnier <at> IRO.UMontreal.CA>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 26699 in the body.
You can then email your comments to 26699 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#26699; Package emacs. (Fri, 28 Apr 2017 16:43:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 28 Apr 2017 16:43:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: bug-gnu-emacs <at> gnu.org
Subject: 26.0.50; Allow non-string keys in password-cache
Date: Fri, 28 Apr 2017 12:42:40 -0400
Package: Emacs
Version: 26.0.50

I suggest the patch below to make password-cache use a hash-table rather
than an obarray and at the same occasion allow non-string keys, which
simplifies auth-source's code.

Any objection?

Should I add a `password-map` function while I'm at it (alias to
`maphash`) so as to avoid auth-source depending on those internals of
password-cache?


        Stefan


diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 01d12c2614..798011e6ff 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -200,8 +200,6 @@ auth-source-netrc-use-gpg-tokens
                            (const :tag "Save GPG-encrypted password tokens" gpg)
                            (const :tag "Don't encrypt tokens" never))))))
 
-(defvar auth-source-magic "auth-source-magic ")
-
 (defcustom auth-source-do-cache t
   "Whether auth-source should cache information with `password-cache'."
   :group 'auth-source
@@ -782,16 +780,16 @@ auth-source-netrc-cache
 (defun auth-source-forget-all-cached ()
   "Forget all cached auth-source data."
   (interactive)
-  (cl-do-symbols (sym password-data)
-    ;; when the symbol name starts with auth-source-magic
-    (when (string-match (concat "^" auth-source-magic) (symbol-name sym))
-      ;; remove that key
-      (password-cache-remove (symbol-name sym))))
+  (maphash (lambda (key password)
+             (when (eq 'auth-source (car-safe key))
+               ;; remove that key
+               (password-cache-remove key)))
+           password-data)
   (setq auth-source-netrc-cache nil))
 
 (defun auth-source-format-cache-entry (spec)
   "Format SPEC entry to put it in the password cache."
-  (concat auth-source-magic (format "%S" spec)))
+  `(auth-source . ,spec))
 
 (defun auth-source-remember (spec found)
   "Remember FOUND search results for SPEC."
@@ -824,16 +822,15 @@ auth-source-forget+
 while \(:host t) would find all host entries."
   (let ((count 0)
         sname)
-    (cl-do-symbols (sym password-data)
-      ;; when the symbol name matches with auth-source-magic
-      (when (and (setq sname (symbol-name sym))
-                 (string-match (concat "^" auth-source-magic "\\(.+\\)")
-                               sname)
-                 ;; and the spec matches what was stored in the cache
-                 (auth-source-specmatchp spec (read (match-string 1 sname))))
-        ;; remove that key
-        (password-cache-remove sname)
-        (cl-incf count)))
+    (maphash
+     (lambda (key password)
+       (when (and (eq 'auth-source (car-safe key))
+                  ;; and the spec matches what was stored in the cache
+                  (auth-source-specmatchp spec (cdr key)))
+         ;; remove that key
+         (password-cache-remove key)
+         (cl-incf count)))
+     password-data)
     count))
 
 (defun auth-source-specmatchp (spec stored)
diff --git a/lisp/password-cache.el b/lisp/password-cache.el
index 7be3c6fdb6..cbc248b9ec 100644
--- a/lisp/password-cache.el
+++ b/lisp/password-cache.el
@@ -66,7 +66,7 @@ password-cache-expiry
   :type '(choice (const :tag "Never" nil)
 		 (integer :tag "Seconds")))
 
-(defvar password-data (make-vector 7 0))
+(defvar password-data (make-hash-table :test #'equal))
 
 (defun password-read-from-cache (key)
   "Obtain passphrase for KEY from time-limited passphrase cache.
@@ -74,20 +74,20 @@ password-read-from-cache
 regulate cache behavior."
   (and password-cache
        key
-       (symbol-value (intern-soft key password-data))))
+       (gethash key password-data)))
 
 ;;;###autoload
 (defun password-in-cache-p (key)
   "Check if KEY is in the cache."
   (and password-cache
        key
-       (intern-soft key password-data)))
+       (gethash key password-data)))
 
 (defun password-read (prompt &optional key)
   "Read password, for use with KEY, from user, or from cache if wanted.
 KEY indicate the purpose of the password, so the cache can
-separate passwords.  The cache is not used if KEY is nil.  It is
-typically a string.
+separate passwords.  The cache is not used if KEY is nil.
+KEY is typically a string but can be anything (compared via `equal').
 The variable `password-cache' control whether the cache is used."
   (or (password-read-from-cache key)
       (read-passwd prompt)))
@@ -115,29 +115,27 @@ password-cache-remove
 from the cache.  This may be useful when it has been detected
 that a password is invalid, so that `password-read' query the
 user again."
-  (let ((sym (intern-soft key password-data)))
-    (when sym
-      (let ((password (symbol-value sym)))
-        (when (stringp password)
-          (if (fboundp 'clear-string)
-              (clear-string password)
-            (fillarray password ?_)))
-        (unintern key password-data)))))
+  (let ((password (gethash key password-data)))
+    (when (stringp password)
+      (if (fboundp 'clear-string)
+          (clear-string password)
+        (fillarray password ?_)))
+    (remhash key password-data)))
 
 (defun password-cache-add (key password)
   "Add password to cache.
 The password is removed by a timer after `password-cache-expiry' seconds."
-  (when (and password-cache-expiry (null (intern-soft key password-data)))
+  (when (and password-cache-expiry (null (gethash key password-data)))
     (run-at-time password-cache-expiry nil
 		 #'password-cache-remove
 		 key))
-  (set (intern key password-data) password)
+  (puthash key password password-data)
   nil)
 
 (defun password-reset ()
   "Clear the password cache."
   (interactive)
-  (fillarray password-data 0))
+  (clrhash password-data))
 
 (provide 'password-cache)
 




Reply sent to Stefan Monnier <monnier <at> IRO.UMontreal.CA>:
You have taken responsibility. (Fri, 28 Jul 2017 16:28:01 GMT) Full text and rfc822 format available.

Notification sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
bug acknowledged by developer. (Fri, 28 Jul 2017 16:28:02 GMT) Full text and rfc822 format available.

Message #10 received at 26699-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: 26699-done <at> debbugs.gnu.org
Subject: Re: bug#26699: 26.0.50; Allow non-string keys in password-cache
Date: Fri, 28 Jul 2017 12:27:44 -0400
Installed into trunk,


        Stefan




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 26 Aug 2017 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 8 years and 16 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.