comparison lisp/custom.el @ 112170:2b3091d14255

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.
author Chong Yidong <cyd@stupidchicken.com>
date Sat, 08 Jan 2011 23:59:56 -0500
parents afa244de82cd
children 417b1e4d63cd
comparison
equal deleted inserted replaced
112169:882d6cbb91a2 112170:2b3091d14255
1103 ;; Make that remain true. (This has the effect of making user 1103 ;; Make that remain true. (This has the effect of making user
1104 ;; settings override the ones just loaded, too.) 1104 ;; settings override the ones just loaded, too.)
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) 1108 (defcustom custom-safe-themes '(default)
1109 "List of theme files that are considered safe to load. 1109 "List of themes that are considered safe to load.
1110 Each list element should be either an absolute file name, or the 1110 Each list element should be the `sha1' hash of a theme file, or
1111 symbol `default', which stands for the built-in Emacs theme 1111 the symbol `default', which stands for any theme in the built-in
1112 directory (a directory named \"themes\" in `data-directory'." 1112 Emacs theme directory (a directory named \"themes\" in
1113 `data-directory')."
1113 :type '(repeat 1114 :type '(repeat
1114 (choice file (const :tag "Built-in theme directory" default))) 1115 (choice string (const :tag "Built-in themes" default)))
1115 :group 'customize 1116 :group 'customize
1117 :risky t
1116 :version "24.1") 1118 :version "24.1")
1117 1119
1118 (defvar safe-functions) ; From unsafep.el 1120 (defvar safe-functions) ; From unsafep.el
1119 1121
1120 (defun load-theme (theme &optional no-enable) 1122 (defun load-theme (theme &optional no-enable)
1138 (put theme 'theme-settings nil) 1140 (put theme 'theme-settings nil)
1139 (put theme 'theme-feature nil) 1141 (put theme 'theme-feature nil)
1140 (put theme 'theme-documentation nil)) 1142 (put theme 'theme-documentation nil))
1141 (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") 1143 (let ((fn (locate-file (concat (symbol-name theme) "-theme.el")
1142 (custom-theme--load-path) 1144 (custom-theme--load-path)
1143 '("" "c")))) 1145 '("" "c")))
1146 hash)
1144 (unless fn 1147 (unless fn
1145 (error "Unable to find theme file for `%s'." theme)) 1148 (error "Unable to find theme file for `%s'." theme))
1146 ;; Check file safety. 1149 (with-temp-buffer
1147 (when (or (and (memq 'default custom-safe-theme-files) 1150 (insert-file-contents fn)
1148 (equal (file-name-directory fn) 1151 (setq hash (sha1 (current-buffer)))
1149 (expand-file-name "themes/" data-directory))) 1152 ;; Check file safety.
1150 (member fn custom-safe-theme-files) 1153 (when (or (and (memq 'default custom-safe-themes)
1151 ;; If the file is not in the builtin theme directory or 1154 (equal (file-name-directory fn)
1152 ;; in `custom-safe-theme-files', check it with unsafep. 1155 (expand-file-name "themes/" data-directory)))
1153 (with-temp-buffer 1156 (member hash custom-safe-themes)
1154 (require 'unsafep) 1157 ;; If the theme is not in `custom-safe-themes', check
1155 (insert-file-contents fn) 1158 ;; it with unsafep.
1156 (let ((safe-functions (append '(provide-theme deftheme 1159 (progn
1157 custom-theme-set-variables 1160 (require 'unsafep)
1158 custom-theme-set-faces) 1161 (let ((safe-functions
1159 safe-functions)) 1162 (append '(provide-theme deftheme
1160 unsafep form) 1163 custom-theme-set-variables
1161 (while (and (setq form (condition-case nil 1164 custom-theme-set-faces)
1162 (let ((read-circle nil)) 1165 safe-functions))
1163 (read (current-buffer))) 1166 unsafep form)
1164 (end-of-file nil))) 1167 (while (and (setq form (condition-case nil
1165 (null (setq unsafep (unsafep form))))) 1168 (let ((read-circle nil))
1166 (or (null unsafep) 1169 (read (current-buffer)))
1167 (custom-theme-load-confirm fn))))) 1170 (end-of-file nil)))
1168 (let ((custom--inhibit-theme-enable no-enable)) 1171 (null (setq unsafep (unsafep form)))))
1169 (load fn))))) 1172 (or (null unsafep)
1170 1173 (custom-theme-load-confirm hash)))))
1171 (defun custom-theme-load-confirm (filename) 1174 (let ((custom--inhibit-theme-enable no-enable))
1175 (eval-buffer))))))
1176
1177 (defun custom-theme-load-confirm (hash)
1178 "Query the user about loading a Custom theme that may not be safe.
1179 The theme should be in the current buffer. If the user agrees,
1180 query also about adding HASH to `custom-safe-themes'."
1172 (if noninteractive 1181 (if noninteractive
1173 nil 1182 nil
1174 (let ((existing-buffer (find-buffer-visiting filename)) 1183 (let ((exit-chars '(?y ?n ?\s))
1175 (exit-chars '(?y ?n ?\s ?\C-g))
1176 prompt char) 1184 prompt char)
1177 (save-window-excursion 1185 (save-window-excursion
1178 (if existing-buffer 1186 (rename-buffer "*Custom Theme*" t)
1179 (pop-to-buffer existing-buffer) 1187 (emacs-lisp-mode)
1180 (find-file filename)) 1188 (display-buffer (current-buffer))
1181 (unwind-protect 1189 (setq prompt
1182 (progn 1190 (format "This theme is not guaranteed to be safe. Really load? %s"
1183 (setq prompt 1191 (if (< (line-number-at-pos (point-max))
1184 (format "This theme is not guaranteed to be safe. Really load? %s" 1192 (window-body-height))
1185 (if (< (line-number-at-pos (point-max)) 1193 "(y or n) "
1186 (window-body-height)) 1194 (push ?\C-v exit-chars)
1187 "(y or n) " 1195 "Type y or n, or C-v to scroll: ")))
1188 (push ?\C-v exit-chars) 1196 (goto-char (point-min))
1189 "Type y or n, or C-v to scroll: "))) 1197 (while (null char)
1190 (goto-char (point-min)) 1198 (setq char (read-char-choice prompt exit-chars))
1191 (while (null char) 1199 (when (eq char ?\C-v)
1192 (setq char (read-char-choice prompt exit-chars t)) 1200 (condition-case nil
1193 (when (eq char ?\C-v) 1201 (scroll-up)
1194 (condition-case nil 1202 (error (goto-char (point-min))))
1195 (scroll-up) 1203 (setq char nil)))
1196 (error (goto-char (point-min)))) 1204 (when (memq char '(?\s ?y))
1197 (setq char nil))) 1205 (push hash custom-safe-themes)
1198 (when (memq char '(?\s ?y)) 1206 ;; Offer to save to `custom-safe-themes'.
1199 (push filename custom-safe-theme-files) 1207 (and (or custom-file user-init-file)
1200 ;; Offer to save to `custom-safe-theme-files'. 1208 (y-or-n-p "Treat this theme as safe for future loads? ")
1201 (and (or custom-file user-init-file) 1209 (let ((coding-system-for-read nil))
1202 (y-or-n-p "Treat %s as safe for future loads? " 1210 (customize-save-variable 'custom-safe-themes
1203 (file-name-nondirectory filename)) 1211 custom-safe-themes)))
1204 (let ((coding-system-for-read nil)) 1212 t)))))
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)))))))
1211 1213
1212 (defun custom-theme-name-valid-p (name) 1214 (defun custom-theme-name-valid-p (name)
1213 "Return t if NAME is a valid name for a Custom theme, nil otherwise. 1215 "Return t if NAME is a valid name for a Custom theme, nil otherwise.
1214 NAME should be a symbol." 1216 NAME should be a symbol."
1215 (and (symbolp name) 1217 (and (symbolp name)