From: Antero Mejr via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: eliz@gnu.org
Cc: 61901@debbugs.gnu.org
Subject: bug#61901: 30.0.50; [PATCH v3] Add safe-local-variable-directories variable.
Date: Tue, 09 May 2023 21:29:54 +0000 [thread overview]
Message-ID: <87r0rpi46l.fsf@mailbox.org> (raw)
In-Reply-To: 83jzxzvpsm.fsf@gnu.org
[-- Attachment #1: Type: text/plain, Size: 3136 bytes --]
>> +@defvar safe-local-variable-directories
>> +This is a list of directories where local variables are always enabled.
>> +Directory-local variables loaded from these directories, such as the
>> +variables in @file{.dir-locals.el}, will be enabled even if they are
>> +risky.
>> +@end defvar
>
>This variable should also be documented in the Emacs user manual, not
>only in the ELisp Reference manual -- it's a user option, and a very
>important one at that.
Added to the manual in custom.texi "Safe File Variables" subsection.
>> ++++
>> +** New variable 'safe-local-variable-directories'.
>> +This variable is used to to permanently trust directories containing
>> +risky directory-local variables.
>
>I would rephrase:
>
> This variable names directories in which Emacs will treat all
> directory-local variables as safe.
Fixed in attached patch.
>> ALL-VARS is the list of all variables to be set up.
>> @@ -3734,7 +3744,9 @@ n -- to ignore the local variables list.")
>> ! -- to apply the local variables list, and permanently mark these
>> values (*) as safe (in the future, they will be set automatically.)
>> i -- to ignore the local variables list, and permanently mark these
>> - values (*) as ignored\n\n")
>> + values (*) as ignored
>> ++ -- to apply the local variables list, and permanently trust all
>> + directory-local variables in this directory\n\n")
>
>I would remove the "permanently" part, it would just confuse here.
Fixed.
>> @@ -3908,6 +3924,7 @@ DIR-NAME is the name of the associated directory.
>> Otherwise it is nil."
>> (null unsafe-vars)
>> (null risky-vars))
>> (memq enable-local-variables '(:all :safe))
>> + (member dir-name safe-local-variable-directories)
>
>If you use 'member' for this test, then (a) the documentation of
>safe-local-variable-directories should explicitly say that the
>directories in the list must be in full absolute form, and (b) we
>should consider the various issues with file names that are not
>'equal' as strings, but still name the same directory, such as
>letter-case differences on case-insensitive filesystems. And what
>about equality of "foo/" "and "foo"?
Clarified the documentation. The directory path requires a trailing
separator, and is case-sensitive regardless of the filesystem (tested
on vFAT).
>Also, is 'dir-name' above guaranteed to be a fully-expanded absolute
>file name?
Yes. For TRAMP connections it's a string with text properties, but it's
the same equality-wise.
#("/ssh:user:/home/user/src/" 5 6 (tramp-default t))
>> +(ert-deftest files-tests-safe-local-variable-directories ()
>> + ;; safe-local-variable-directories should be risky,
>> + ;; so use it as an arbitrary risky variable.
>> + (let ((test-alist '((safe-local-variable-directories . "some_val")))
>> + (fakedir "test1/test2")
>> + (enable-local-eval t))
>> + (with-temp-buffer
>> + (setq safe-local-variable-directories (list fakedir))
>
>The test should use absolute directory names for directories you put
>into safe-local-variable-directories.
Fixed.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-safe-local-variable-directories-variable.patch --]
[-- Type: text/x-patch, Size: 9984 bytes --]
From 4ecb9ebc01c856f896ed2fee110b491209e23c4e Mon Sep 17 00:00:00 2001
From: Antero Mejr <antero@mailbox.org>
Date: Tue, 9 May 2023 20:51:14 +0000
Subject: [PATCH] Add safe-local-variable-directories variable.
This variable can be set to automatically load risky dir-local
variables from a list of trusted directories.
* lisp/emacs-lisp/files.el (safe-local-variable-directories,
hack-local-variables-filter, hack-local-variables-confirm): New
variable and associated logic.
* test/lisp/files-tests.el
(files-tests-safe-local-variable-directories): Add tests for same.
* doc/emacs/custom.texi (Safe File Variables): Add documentation for
same.
* doc/lispref/variables.texi (File Local Variables): Add documentation
for same.
* etc/NEWS (Lisp Changes in Emacs 30.1): Add news entry for
same. (Bug#61901)
---
doc/emacs/custom.texi | 22 ++++++++++++++++++++++
doc/lispref/variables.texi | 12 ++++++++++++
etc/NEWS | 5 +++++
lisp/files.el | 34 +++++++++++++++++++++++++++++-----
test/lisp/files-tests.el | 21 +++++++++++++++++++++
5 files changed, 89 insertions(+), 5 deletions(-)
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 87290734cc9..2ddd39be31f 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1328,6 +1328,13 @@ pairs in the file, by typing @kbd{i} at the confirmation prompt --
these pairs will thereafter be ignored in this file and in all other
files.
+ For directory-local variable/value pairs
+(@pxref{Directory Variables}), typing @kbd{+} at the confirmation
+prompt will set all the variable/value pairs, and recognize all
+variables in that directory as safe in the future. This option should
+only be used for directories whose contents you trust. The @kbd{+}
+confirmation prompt option is not available for file-local variables.
+
@vindex safe-local-variable-values
@vindex ignored-local-variable-values
@cindex risky variable
@@ -1344,6 +1351,21 @@ record safe values for risky variables, do it directly by customizing
Similarly, if you want to record values of risky variables that should
be permanently ignored, customize @code{ignored-local-variable-values}.
+@vindex safe-local-variable-directories
+ Sometimes it is helpful to always trust risky variables in a certain
+directory, and skip the confirmation prompt when directory-local
+variables are loaded there. When @kbd{+} is pressed at the risky
+variable confirmation prompt, the directory in question is added to
+the @samp{safe-local-variable-directories} variable, and risky
+directory-local variables there will be loaded without prompting in
+the future. If customizing @samp{safe-local-variable-directories}
+manually, the directories in this list must be fully-expanded absolute
+paths that end in a directory separator character. Directory paths
+may be remote directory paths (@pxref{Remote Files}), if the
+@code{enable-remote-dir-locals} variable is set to @code{t}.
+Directory paths in this list are case-sensitive, even if the
+filesystem is not.
+
@vindex enable-local-variables
The variable @code{enable-local-variables} allows you to change the
way Emacs processes local variables. Its default value is @code{t},
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index eadb5c36de6..52a94db3703 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -1977,6 +1977,18 @@ this can be controlled by using this variable, which is a list of
symbols.
@end defvar
+@defvar safe-local-variable-directories
+This is a list of directories where local variables are always
+enabled. Directory-local variables loaded from these directories,
+such as the variables in @file{.dir-locals.el}, will be enabled even
+if they are risky. The directories in this list must be
+fully-expanded absolute paths that end in a directory separator
+character. They may also be remote directory paths if the
+@code{enable-remote-dir-locals} variable is set to @code{t}.
+Directory paths in this list are case-sensitive, even if the
+filesystem is not.
+@end defvar
+
@defun hack-local-variables &optional handle-mode
This function parses, and binds or evaluates as appropriate, any local
variables specified by the contents of the current buffer. The variable
diff --git a/etc/NEWS b/etc/NEWS
index 3c71e52fff4..3bef9d2ed2a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -380,6 +380,11 @@ hooks named after the feature name, like 'esh-mode-unload-hook'.
\f
* Lisp Changes in Emacs 30.1
++++
+** New variable 'safe-local-variable-directories'.
+This variable names directories in which Emacs will treat all
+directory-local variables as safe.
+
** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill.
** Functions and variables to transpose sexps
diff --git a/lisp/files.el b/lisp/files.el
index c6f53e5eaf8..aa01e638c98 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -681,7 +681,8 @@ The command \\[normal-mode], when used interactively,
always obeys file local variable specifications and the -*- line,
and ignores this variable.
-Also see the `permanently-enabled-local-variables' variable."
+Also see the `permanently-enabled-local-variables' and
+`safe-local-variable-directories' variables."
:risky t
:type '(choice (const :tag "Query Unsafe" t)
(const :tag "Safe Only" :safe)
@@ -3696,6 +3697,15 @@ variable to set.")
"A list of file-local variables that are always enabled.
This overrides any `enable-local-variables' setting.")
+(defcustom safe-local-variable-directories '()
+ "A list of directories where local variables are always enabled.
+Directory-local variables loaded from these directories, such as the
+variables in .dir-locals.el, will be enabled even if they are risky."
+ :version "30.1"
+ :type '(repeat string)
+ :risky t
+ :group 'find-file)
+
(defun hack-local-variables-confirm (all-vars unsafe-vars risky-vars dir-name)
"Get confirmation before setting up local variable values.
ALL-VARS is the list of all variables to be set up.
@@ -3734,7 +3744,11 @@ n -- to ignore the local variables list.")
! -- to apply the local variables list, and permanently mark these
values (*) as safe (in the future, they will be set automatically.)
i -- to ignore the local variables list, and permanently mark these
- values (*) as ignored\n\n")
+ values (*) as ignored"
+ (if dir-name "
++ -- to apply the local variables list, and trust all directory-local
+ variables in this directory\n\n"
+ "\n\n"))
(insert "\n\n"))
(dolist (elt all-vars)
(cond ((member elt unsafe-vars)
@@ -3758,7 +3772,11 @@ i -- to ignore the local variables list, and permanently mark these
(pop-to-buffer buf '(display-buffer--maybe-at-bottom))
(let* ((exit-chars '(?y ?n ?\s))
(prompt (format "Please type %s%s: "
- (if offer-save "y, n, ! or i" "y or n")
+ (if offer-save
+ (if dir-name
+ "y, n, !, i, +"
+ "y, n, !, i")
+ "y or n")
(if (< (line-number-at-pos (point-max))
(window-body-height))
""
@@ -3766,8 +3784,13 @@ i -- to ignore the local variables list, and permanently mark these
char)
(when offer-save
(push ?i exit-chars)
- (push ?! exit-chars))
+ (push ?! exit-chars)
+ (when dir-name
+ (push ?+ exit-chars)))
(setq char (read-char-choice prompt exit-chars))
+ (when (and offer-save dir-name (= char ?+))
+ (customize-push-and-save 'safe-local-variable-directories
+ (list dir-name)))
(when (and offer-save
(or (= char ?!) (= char ?i))
unsafe-vars)
@@ -3776,7 +3799,7 @@ i -- to ignore the local variables list, and permanently mark these
'safe-local-variable-values
'ignored-local-variable-values)
unsafe-vars))
- (prog1 (memq char '(?! ?\s ?y))
+ (prog1 (memq char '(?! ?\s ?y ?+))
(quit-window t)))))))
(defconst hack-local-variable-regexp
@@ -3908,6 +3931,7 @@ DIR-NAME is the name of the associated directory. Otherwise it is nil."
(null unsafe-vars)
(null risky-vars))
(memq enable-local-variables '(:all :safe))
+ (member dir-name safe-local-variable-directories)
(hack-local-variables-confirm all-vars unsafe-vars
risky-vars dir-name))
(dolist (elt all-vars)
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index aadb60e1de7..e87bb3cfa0a 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -166,6 +166,27 @@ form.")
(hack-local-variables)
(should (eq lexical-binding nil)))))
+(ert-deftest files-tests-safe-local-variable-directories ()
+ ;; safe-local-variable-directories should be risky,
+ ;; so use it as an arbitrary risky variable.
+ (let ((test-alist '((safe-local-variable-directories . "some_val")))
+ (fakedir "/test1/test2/")
+ (enable-local-eval t))
+ (with-temp-buffer
+ (setq safe-local-variable-directories (list fakedir))
+ (hack-local-variables-filter test-alist fakedir)
+ (should (equal file-local-variables-alist test-alist)))
+ (with-temp-buffer
+ (setq safe-local-variable-directories (list fakedir))
+ (setq noninteractive t)
+ (hack-local-variables-filter test-alist "wrong")
+ (should-not (equal file-local-variables-alist test-alist)))
+ (with-temp-buffer
+ (setq safe-local-variable-directories '())
+ (setq noninteractive t)
+ (hack-local-variables-filter test-alist fakedir)
+ (should-not (equal file-local-variables-alist test-alist)))))
+
(defvar files-test-bug-18141-file
(ert-resource-file "files-bug18141.el.gz")
"Test file for bug#18141.")
--
2.39.2
next prev parent reply other threads:[~2023-05-09 21:29 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-01 22:20 bug#61901: 30.0.50; [PATCH] Add permanently-enabled-local-variable-dirs variable Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-03-02 6:57 ` Eli Zaretskii
2023-03-02 17:09 ` Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-03-02 18:04 ` Eli Zaretskii
2023-03-14 18:46 ` Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-03-14 19:48 ` Eli Zaretskii
2023-04-25 16:40 ` bug#61901: 30.0.50; [PATCH v3] Add safe-local-variable-directories variable Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-25 17:23 ` Eli Zaretskii
2023-05-09 21:29 ` Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2023-05-11 13:55 ` Eli Zaretskii
[not found] ` <87ilcy3mdt.fsf@mailbox.org>
2023-05-11 16:10 ` Eli Zaretskii
2023-05-11 17:49 ` Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-11 18:11 ` Eli Zaretskii
2023-05-11 20:11 ` Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-11 21:38 ` Antero Mejr via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-12 11:09 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87r0rpi46l.fsf@mailbox.org \
--to=bug-gnu-emacs@gnu.org \
--cc=61901@debbugs.gnu.org \
--cc=antero@mailbox.org \
--cc=eliz@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.