# HG changeset patch # User Chong Yidong # Date 1294549196 18000 # Node ID 2b3091d1425544704f9a4248e6729d293d1726ed # Parent 882d6cbb91a2326c1895381a98f10b59defa311a Record "safe themes" as sha1 hashes, as suggested by Stefan Monnier. * lisp/custom.el (custom-safe-themes): Rename from custom-safe-theme-files. Add :risky tag. (load-theme, custom-theme-load-confirm): Save sha1 hashes to custom-safe-themes, not filenames. Suggested by Stefan Monnier. diff -r 882d6cbb91a2 -r 2b3091d14255 etc/NEWS --- a/etc/NEWS Sat Jan 08 23:13:47 2011 -0500 +++ b/etc/NEWS Sat Jan 08 23:59:56 2011 -0500 @@ -219,9 +219,10 @@ is to search in `custom-theme-directory', followed by a built-in theme directory named "themes/" in `data-directory'. -*** New option `custom-safe-theme-files' lists known-safe theme files. -If a theme is not in this list, Emacs queries before loading it. -The default value treats all themes included in Emacs as safe. +*** New option `custom-safe-themes' records known-safe theme files. +If a theme is not in this list, Emacs queries before loading it, and +offers to save the theme to `custom-safe-themes' automatically. By +default, all themes included in Emacs are treated as safe. ** The user option `remote-file-name-inhibit-cache' controls whether the remote file-name cache is used for read access. diff -r 882d6cbb91a2 -r 2b3091d14255 lisp/ChangeLog --- a/lisp/ChangeLog Sat Jan 08 23:13:47 2011 -0500 +++ b/lisp/ChangeLog Sat Jan 08 23:59:56 2011 -0500 @@ -1,3 +1,10 @@ +2011-01-09 Chong Yidong + + * custom.el (custom-safe-themes): Rename from + custom-safe-theme-files. Add :risky tag. + (load-theme, custom-theme-load-confirm): Save sha1 hashes to + custom-safe-themes, not filenames. Suggested by Stefan Monnier. + 2011-01-09 Chong Yidong * tool-bar.el (tool-bar-setup): Remove Help button. Remove label diff -r 882d6cbb91a2 -r 2b3091d14255 lisp/custom.el --- a/lisp/custom.el Sat Jan 08 23:13:47 2011 -0500 +++ b/lisp/custom.el Sat Jan 08 23:59:56 2011 -0500 @@ -1105,14 +1105,16 @@ (let ((custom-enabling-themes t)) (enable-theme 'user)))) -(defcustom custom-safe-theme-files '(default) - "List of theme files that are considered safe to load. -Each list element should be either an absolute file name, or the -symbol `default', which stands for the built-in Emacs theme -directory (a directory named \"themes\" in `data-directory'." +(defcustom custom-safe-themes '(default) + "List of themes that are considered safe to load. +Each list element should be the `sha1' hash of a theme file, or +the symbol `default', which stands for any theme in the built-in +Emacs theme directory (a directory named \"themes\" in +`data-directory')." :type '(repeat - (choice file (const :tag "Built-in theme directory" default))) + (choice string (const :tag "Built-in themes" default))) :group 'customize + :risky t :version "24.1") (defvar safe-functions) ; From unsafep.el @@ -1140,74 +1142,74 @@ (put theme 'theme-documentation nil)) (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") (custom-theme--load-path) - '("" "c")))) + '("" "c"))) + hash) (unless fn (error "Unable to find theme file for `%s'." theme)) - ;; Check file safety. - (when (or (and (memq 'default custom-safe-theme-files) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (member fn custom-safe-theme-files) - ;; If the file is not in the builtin theme directory or - ;; in `custom-safe-theme-files', check it with unsafep. - (with-temp-buffer - (require 'unsafep) - (insert-file-contents fn) - (let ((safe-functions (append '(provide-theme deftheme - custom-theme-set-variables - custom-theme-set-faces) - safe-functions)) - unsafep form) - (while (and (setq form (condition-case nil - (let ((read-circle nil)) - (read (current-buffer))) - (end-of-file nil))) - (null (setq unsafep (unsafep form))))) - (or (null unsafep) - (custom-theme-load-confirm fn))))) - (let ((custom--inhibit-theme-enable no-enable)) - (load fn))))) + (with-temp-buffer + (insert-file-contents fn) + (setq hash (sha1 (current-buffer))) + ;; Check file safety. + (when (or (and (memq 'default custom-safe-themes) + (equal (file-name-directory fn) + (expand-file-name "themes/" data-directory))) + (member hash custom-safe-themes) + ;; If the theme is not in `custom-safe-themes', check + ;; it with unsafep. + (progn + (require 'unsafep) + (let ((safe-functions + (append '(provide-theme deftheme + custom-theme-set-variables + custom-theme-set-faces) + safe-functions)) + unsafep form) + (while (and (setq form (condition-case nil + (let ((read-circle nil)) + (read (current-buffer))) + (end-of-file nil))) + (null (setq unsafep (unsafep form))))) + (or (null unsafep) + (custom-theme-load-confirm hash))))) + (let ((custom--inhibit-theme-enable no-enable)) + (eval-buffer)))))) -(defun custom-theme-load-confirm (filename) +(defun custom-theme-load-confirm (hash) + "Query the user about loading a Custom theme that may not be safe. +The theme should be in the current buffer. If the user agrees, +query also about adding HASH to `custom-safe-themes'." (if noninteractive nil - (let ((existing-buffer (find-buffer-visiting filename)) - (exit-chars '(?y ?n ?\s ?\C-g)) + (let ((exit-chars '(?y ?n ?\s)) prompt char) (save-window-excursion - (if existing-buffer - (pop-to-buffer existing-buffer) - (find-file filename)) - (unwind-protect - (progn - (setq prompt - (format "This theme is not guaranteed to be safe. Really load? %s" - (if (< (line-number-at-pos (point-max)) - (window-body-height)) - "(y or n) " - (push ?\C-v exit-chars) - "Type y or n, or C-v to scroll: "))) - (goto-char (point-min)) - (while (null char) - (setq char (read-char-choice prompt exit-chars t)) - (when (eq char ?\C-v) - (condition-case nil - (scroll-up) - (error (goto-char (point-min)))) - (setq char nil))) - (when (memq char '(?\s ?y)) - (push filename custom-safe-theme-files) - ;; Offer to save to `custom-safe-theme-files'. - (and (or custom-file user-init-file) - (y-or-n-p "Treat %s as safe for future loads? " - (file-name-nondirectory filename)) - (let ((coding-system-for-read nil)) - (customize-save-variable - 'custom-safe-theme-files - custom-safe-theme-files))) - t)) - ;; Unwind form. - (unless existing-buffer (kill-buffer))))))) + (rename-buffer "*Custom Theme*" t) + (emacs-lisp-mode) + (display-buffer (current-buffer)) + (setq prompt + (format "This theme is not guaranteed to be safe. Really load? %s" + (if (< (line-number-at-pos (point-max)) + (window-body-height)) + "(y or n) " + (push ?\C-v exit-chars) + "Type y or n, or C-v to scroll: "))) + (goto-char (point-min)) + (while (null char) + (setq char (read-char-choice prompt exit-chars)) + (when (eq char ?\C-v) + (condition-case nil + (scroll-up) + (error (goto-char (point-min)))) + (setq char nil))) + (when (memq char '(?\s ?y)) + (push hash custom-safe-themes) + ;; Offer to save to `custom-safe-themes'. + (and (or custom-file user-init-file) + (y-or-n-p "Treat this theme as safe for future loads? ") + (let ((coding-system-for-read nil)) + (customize-save-variable 'custom-safe-themes + custom-safe-themes))) + t))))) (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise.