aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Yidong2011-01-08 14:19:55 -0500
committerChong Yidong2011-01-08 14:19:55 -0500
commit278f68456b8c25fff6d2274476cdc8ee3609f68b (patch)
treea3366a2afbb024409409486534f43e053e643039
parent3ef01959de6b49dc0db5a930154a6f915f7a2678 (diff)
downloademacs-278f68456b8c25fff6d2274476cdc8ee3609f68b.tar.gz
emacs-278f68456b8c25fff6d2274476cdc8ee3609f68b.zip
Load themes using `load', querying if theme file not known safe.
* custom.el (custom-safe-theme-files): New defcustom. (custom-theme-load-confirm): New function. (load-theme): Load theme using `load', confirming with custom-theme-load-confirm if necessary.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/custom.el111
3 files changed, 88 insertions, 32 deletions
diff --git a/etc/NEWS b/etc/NEWS
index eaacfac4d49..0fd74252601 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -219,6 +219,10 @@ Emacs no longer looks for custom themes in `load-path'. The default
219is to search in `custom-theme-directory', followed by a built-in theme 219is to search in `custom-theme-directory', followed by a built-in theme
220directory named "themes/" in `data-directory'. 220directory named "themes/" in `data-directory'.
221 221
222*** New option `custom-safe-theme-files' lists known-safe theme files.
223If a theme is not in this list, Emacs queries before loading it.
224The default value treats all themes included in Emacs as safe.
225
222** The user option `remote-file-name-inhibit-cache' controls whether 226** The user option `remote-file-name-inhibit-cache' controls whether
223the remote file-name cache is used for read access. 227the remote file-name cache is used for read access.
224 228
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 0f84b977d56..86f9e8fa0b9 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,10 @@
12011-01-08 Chong Yidong <cyd@stupidchicken.com> 12011-01-08 Chong Yidong <cyd@stupidchicken.com>
2 2
3 * custom.el (custom-safe-theme-files): New defcustom.
4 (custom-theme-load-confirm): New function.
5 (load-theme): Load theme using `load', confirming with
6 custom-theme-load-confirm if necessary.
7
3 * subr.el (read-char-choice): New function, factored out from 8 * subr.el (read-char-choice): New function, factored out from
4 dired-query and hack-local-variables-confirm. 9 dired-query and hack-local-variables-confirm.
5 10
diff --git a/lisp/custom.el b/lisp/custom.el
index bcb78e46a3c..f984d132dd1 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1105,15 +1105,26 @@ property `theme-feature' (which is usually a symbol created by
1105 (let ((custom-enabling-themes t)) 1105 (let ((custom-enabling-themes t))
1106 (enable-theme 'user)))) 1106 (enable-theme 'user))))
1107 1107
1108(defcustom custom-safe-theme-files '(default)
1109 "List of theme files that are considered safe to load.
1110Each list element should be either an absolute file name, or the
1111symbol `default', which stands for the built-in Emacs theme
1112directory (a directory named \"themes\" in `data-directory'."
1113 :type '(repeat
1114 (choice file (const :tag "Built-in theme directory" default)))
1115 :group 'customize
1116 :version "24.1")
1117
1108(defvar safe-functions) ; From unsafep.el 1118(defvar safe-functions) ; From unsafep.el
1109 1119
1110(defun load-theme (theme &optional no-enable) 1120(defun load-theme (theme &optional no-enable)
1111 "Load a theme's settings from its file. 1121 "Load a theme's settings from its file.
1112Normally, this also enables the theme; use `disable-theme' to 1122Normally, this also enables the theme; use `disable-theme' to
1113disable it. If optional arg NO-ENABLE is non-nil, don't enable 1123disable it. If optional arg NO-ENABLE is non-nil, don't enable
1114the theme." 1124the theme.
1115 ;; Note we do no check for validity of the theme here. 1125
1116 ;; This allows to pull in themes by a file-name convention 1126A theme file is named THEME-theme.el, where THEME is the theme name,
1127in one of the directories specified by `custom-theme-load-path'."
1117 (interactive 1128 (interactive
1118 (list 1129 (list
1119 (intern (completing-read "Load custom theme: " 1130 (intern (completing-read "Load custom theme: "
@@ -1132,35 +1143,71 @@ the theme."
1132 '("" "c")))) 1143 '("" "c"))))
1133 (unless fn 1144 (unless fn
1134 (error "Unable to find theme file for `%s'." theme)) 1145 (error "Unable to find theme file for `%s'." theme))
1135 ;; Instead of simply loading the theme file, read it manually. 1146 ;; Check file safety.
1136 (with-temp-buffer 1147 (when (or (and (memq 'default custom-safe-theme-files)
1137 (insert-file-contents fn) 1148 (equal (file-name-directory fn)
1138 (require 'unsafep) 1149 (expand-file-name "themes/" data-directory)))
1139 (let ((custom--inhibit-theme-enable no-enable) 1150 (member fn custom-safe-theme-files)
1140 (safe-functions (append '(custom-theme-set-variables 1151 ;; If the file is not in the builtin theme directory or
1141 custom-theme-set-faces) 1152 ;; in `custom-safe-theme-files', check it with unsafep.
1142 safe-functions)) 1153 (with-temp-buffer
1143 form scar) 1154 (require 'unsafep)
1144 (while (setq form (let ((read-circle nil)) 1155 (insert-file-contents fn)
1145 (condition-case nil 1156 (let ((safe-functions (append '(provide-theme deftheme
1146 (read (current-buffer)) 1157 custom-theme-set-variables
1147 (end-of-file nil)))) 1158 custom-theme-set-faces)
1148 (cond 1159 safe-functions))
1149 ;; Check `deftheme' expressions. 1160 unsafep form)
1150 ((eq (setq scar (car form)) 'deftheme) 1161 (while (and (setq form (condition-case nil
1151 (unless (eq (cadr form) theme) 1162 (let ((read-circle nil))
1152 (error "Incorrect theme name in `deftheme'")) 1163 (read (current-buffer)))
1153 (and (symbolp (nth 1 form)) 1164 (end-of-file nil)))
1154 (stringp (nth 2 form)) 1165 (null (setq unsafep (unsafep form)))))
1155 (eval (list scar (nth 1 form) (nth 2 form))))) 1166 (or (null unsafep)
1156 ;; Check `provide-theme' expressions. 1167 (custom-theme-load-confirm fn)))))
1157 ((and (eq scar 'provide-theme) 1168 (let ((custom--inhibit-theme-enable no-enable))
1158 (equal (cadr form) `(quote ,theme)) 1169 (load fn)))))
1159 (= (length form) 2)) 1170
1160 (eval form)) 1171(defun custom-theme-load-confirm (filename)
1161 ;; All other expressions need to be safe. 1172 (if noninteractive
1162 ((not (unsafep form)) 1173 nil
1163 (eval form)))))))) 1174 (let ((existing-buffer (find-buffer-visiting filename))
1175 (exit-chars '(?y ?n ?\s ?\C-g))
1176 prompt char)
1177 (save-window-excursion
1178 (if existing-buffer
1179 (pop-to-buffer existing-buffer)
1180 (find-file filename))
1181 (unwind-protect
1182 (progn
1183 (setq prompt
1184 (format "This theme is not guaranteed to be safe. Really load? %s"
1185 (if (< (line-number-at-pos (point-max))
1186 (window-body-height))
1187 "(y or n) "
1188 (push ?\C-v exit-chars)
1189 "Type y or n, or C-v to scroll: ")))
1190 (goto-char (point-min))
1191 (while (null char)
1192 (setq char (read-char-choice prompt exit-chars t))
1193 (when (eq char ?\C-v)
1194 (condition-case nil
1195 (scroll-up)
1196 (error (goto-char (point-min))))
1197 (setq char nil)))
1198 (when (memq char '(?\s ?y))
1199 (push filename custom-safe-theme-files)
1200 ;; Offer to save to `custom-safe-theme-files'.
1201 (and (or custom-file user-init-file)
1202 (y-or-n-p "Treat %s as safe for future loads? "
1203 (file-name-nondirectory filename))
1204 (let ((coding-system-for-read nil))
1205 (customize-save-variable
1206 'custom-safe-theme-files
1207 custom-safe-theme-files)))
1208 t))
1209 ;; Unwind form.
1210 (unless existing-buffer (kill-buffer)))))))
1164 1211
1165(defun custom-theme-name-valid-p (name) 1212(defun custom-theme-name-valid-p (name)
1166 "Return t if NAME is a valid name for a Custom theme, nil otherwise. 1213 "Return t if NAME is a valid name for a Custom theme, nil otherwise.