Why is Emacs complaining about risky file-local variables? - security

Trying to use purescript-mode with GNU Emacs 24.5.1, whenever I return a newline in a purescript file, Emacs opens a new window to tell me:
purescript-mode-hook is a variable defined in `purescript-mode.el'.
Its value is (capitalized-words-mode)
Original value was nil
This variable may be risky if used as a file-local variable.
After a bit of research, I added the following to my .emacs file:
(add-to-list 'safe-local-variable-values
'(purescript-mode-hook . capitalized-words-mode))
Now, when I return a newline in a purescript file, Emacs still opens a new window to tell me:
purescript-mode-hook is a variable defined in `purescript-mode.el'.
Its value is (capitalized-words-mode)
Original value was nil
This variable may be risky if used as a file-local variable.
However, you have added it to `safe-local-variable-values'.
If I've explicitly told Emacs that it's safe, why is it still complaining? How can I suppress this behavior?

I am fighting the same dragon... purescript-mode-hook is considered risky because risky-local-variable-p is returning non-nil.
risky-local-variable-p is a byte-compiled Lisp function in ‘files.el’.
(risky-local-variable-p SYM &optional IGNORED)
Non-nil if SYM could be dangerous as a file-local variable.
It is dangerous if either of these conditions are met:
Its ‘risky-local-variable’ property is non-nil.
Its name ends with "hook(s)", "function(s)", "form(s)", "map",
"program", "command(s)", "predicate(s)", "frame-alist",
"mode-alist", "font-lock-(syntactic-)keyword*",
"map-alist", or "bindat-spec".
Probably introduced at or before Emacs version 22.1.
It appears for risky variables, the only choice you have is to set enable-local-variables to :all. BUT:
enable-local-variables is a variable defined in ‘files.el’.
Its value is t
Control use of local variables in files you visit.
The value can be t, nil, :safe, :all, or something else.
A value of t means file local variables specifications are obeyed
if all the specified variable values are safe; if any values are
not safe, Emacs queries you, once, whether to set them all.
(When you say yes to certain values, they are remembered as safe.)
:safe means set the safe variables, and ignore the rest.
:all means set all variables, whether safe or not.
(Don’t set it permanently to :all.)
A value of nil means always ignore the file local variables.
Any other value means always query you once whether to set them all.
(When you say yes to certain values, they are remembered as safe, but
this has no effect when ‘enable-local-variables’ is "something else".)
This variable also controls use of major modes specified in
a -*- line.
The command M-x 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.
This variable may be risky if used as a file-local variable.
You can customize this variable.
Probably introduced at or before Emacs version 19.20.

Related

What does the operator colon in the satement "export variable=lib:/dev/input/event0" mean in linux environment??

first time see such statement by exporting a variable. How to use it and what does it mean?
The : character itself doesn't mean anything on its own. An environment variable is just that - a variable, either unset or containing some value. The value is then used by another program, so what the : means depends on what program is using the variable.
Often it is used as a separator, as with the $PATH variable - you list various directories you want checked when you execute a command in a shell without specifying a full path (eg, /bin:/usr/bin:/usr/sbin - each directory is checked).
In the example you give, lib: looks like it might be a prefix of some sort. But in the end, it really depends on what will be using the variable.

how to understand these vim scripts

I have two question about understand those vim script. please give some help,
Question 1:
I download a.vim plugin, and i try to read this plugin, how to understand the below variable definition? the first line I can understand, but the second line, I don't know exactly "g:alternateExtensions_{'aspx.cs'}" means.
" E.g. let g:alternateExtensions_CPP = "inc,h,H,HPP,hpp"
" let g:alternateExtensions_{'aspx.cs'} = "aspx"
Question 2:
how to understand "SID" before the function name, using like below function definition and function call.
function! <SID>AddAlternateExtensionMapping(extension, alternates)
//omit define body
call <SID>AddAlternateExtensionMapping('h',"c,cpp,cxx,cc,CC")
call <SID>AddAlternateExtensionMapping('H',"C,CPP,CXX,CC")
thanks for you kindly help.
let g:alternateExtensions_{'aspx.cs'} = "aspx"
That is an inline expansion of a Vimscript expression into a variable name, a rather obscure feature that is rarely used since Vim version 7. See :help curly-braces-names for details. It is usually used to interpolate a variable, not a string literal like here ('aspx.cs'). Furthermore, this here yields an error, because periods are forbidden in variable names. Newer plugins would use a List or Dictionary variable, but those data types weren't available when a.vim was written.
To avoid polluting the function namespace, plugin-internal functions should be script-local, i.e. have the prefix s:. To invoke these from a mapping, the special <SID> prefix has to be used instead of s:, because <SID> internally gets translated into something that keeps the script's ID, whereas the pure s:, when executed as part of the mapping, has lost its association to the script that defined it.
Some plugin authors don't fully understand this unfortunate and accidental complexity of Vim's scoping implementation either, and they put the <SID> prefix also in front of the function name (which works, too). Though it's slightly more correct and recommended to write it like this:
" Define and invoke script-local function.
function! s:AddAlternateExtensionMapping(extension, alternates)
...
call s:AddAlternateExtensionMapping('h',"c,cpp,cxx,cc,CC")
" Only in a mapping, the special <SID> prefix is actually necessary.
nmap <Leader>a :call <SID>AddAlternateExtensionMapping('h',"c,cpp,cxx,cc,CC")
<SID> is explained in :help <SID>:
When defining a function in a script, "s:" can be prepended to the name to
make it local to the script. But when a mapping is executed from outside of
the script, it doesn't know in which script the function was defined. To
avoid this problem, use "<SID>" instead of "s:". The same translation is done
as for mappings. This makes it possible to define a call to the function in
a mapping.
When a local function is executed, it runs in the context of the script it was
defined in. This means that new functions and mappings it defines can also
use "s:" or "<SID>" and it will use the same unique number as when the
function itself was defined. Also, the "s:var" local script variables can be
used.
That number is the one you see on the left when you do :scriptnames, IIRC.

How to set back to the original value interactively if a variable's value is changed?

Sometimes the defvar/defcustom variable is changed by another expression in other elisp scripts with setq and the like, or they are altered by the directory/file local settings. Indeed I can use describe-variable to see its original value and then set it manually; however it is still a bit verbose.
In Vim, there is always a way to revert back to the default value of some variable by using !. And I believe that Emacs also has a way to achieve that goal.
So is there any simpler and interactive way to do so? Thanks.
Update: using set-default won't work. For instance, the original value of goto-address-mail-face is italic in goto-addr.el, and suppose I (setq goto-address-mail-face 'link) in ~/emacs.d/init.el. However when I (setq goto-address-mail-face (default-value 'goto-address-mail-face)) in the minibuffer, the result is still link.
For defcustom variables you can use the M-x customize-variable interface.
For defvar, I don't think the INITVALUE argument is remembered (and I don't think it is even evaluated in instances where the variable is already bound).
Variables can have "default" values, but this refers to the global value (as opposed to buffer-local bindings), and can of course be modified.
You can interactively set a buffer-local variable to its default value with M-: (setq SYMBOL (default-value 'SYMBOL))
See C-hig (elisp) Default Value RET

visualize dependence on global variables using vim, ctags potentially

I'd like to highlight variables in my (Maple-code, but doesn't matter much) code which are global for routines.
e.g. I have
global_var1:=1;
global_var2:=2;
...
some_proc:=proc()
local local_var1, global_var2;
local_var1:=1;
local_var2:=local_var1*global_var1+global_var2;
end proc;
I want to highlight global_var1 inside of some_proc() in this example. Obviously the naming is not so trivial in general as in the example.
Can I use ctags to do this?
It depends on ctags. With some languages it is unable to extract local variables (viml), with other languages, it doesn't detect all local variables (C++). Hence, the first thing you'll have to do is to see what ctags can do for your language (Maple).
The other difficulty is to restrict the highlighting to one specific function, and to stay synchronized every time newlines are inserted to the edited file. I know no easy way to do this -- may be with a vim syntax region that starts at local.*{global-name} and ends at end proc to neutralize the highlighting of all global variables?
One task that'll be much more easier would be to highlight variable masking, i.e. highlight global_var2 at the point in the function where it is declared local. Alas, it's not what you're looking for.

vim functions with script scope

I had installed Janus with my MacVim setup. In order to learn about how vim scripts work, I've been reading through the vimrc file that Janus uses, and I don't understand how the author of this is using functions. For example, here's one of the functions in the vimrc:
function s:setupWrapping()
set wrap
set wrapmargin=2
set textwidth=72
endfunction
Now, according to the Defining a function section of the vim manual, 'Function names must begin with a capital letter.' According to the Local mappings and functions section of the manual, 'When defining a function in a script, "s:" can be prepended to the name to make it local to the script.' However, there's no mention of being able to begin a function name with a lower case letter when specifying its scope as local to the script.
So, is the function as written syntactically incorrect but works anyway, or is it syntactically correct but I can't find the documentation that says so?
As I understand it, the rule about capitalizing function names is intended to avoid conflicts with vim's built-in functions. There's no possibility of conflict from script-local functions, so it seems reasonable that the restriction would not apply to them, since you must always prefix them with their namespace qualifier.
ZyX corrected me in the comments, pointing out that, contradictory to an earlier revision of this answer, vim does not allow buffer-scope functions to be declared. You can declare a global function with a name like b:function_name, or for that matter _:function_name, but this is confusing and probably a terrible idea, for reasons mentioned in the comments.
Functions declared within a dictionary do not need to be capitalized.
Buffer-scope Funcrefs, and presumably other Funcrefs outside of global or function-level scope ("local" Funcrefs) do not need to be capitalized. But they have limited usefulness anyway, since a Funcref must reference either a global or script-scope function (the latter being syntactically awkward) or a dictionary function; in the latter case you have to call it with call(funcref, args, dict).
But anyway, you're looking for documentation, so I did a :helpgrep capital and found these nuggets of wisdom:
E704: A Funcref variable must start with a capital, "s:", "w:", "t:" or "b:".
E124: « Define a new function by the name {name}. The name must be made of alphanumeric characters and '_', and must start with a capital or "s:" (see above). » The "see above" pointer refers to the sections user-functions and local-function, which provide more detail but don't mention anything about the non-capitalization of script-scope functions. user-functions mentions that The function name must start with an uppercase letter, to avoid confusion with builtin functions.
It may be that the strict rule of always starting a function name with a capital was true before the advent of other scopes, of which script scope seems to have been the first, or at least the first capable of including function declarations. I'm guessing that the parts of the manual which assert such a rule have just not been updated to reflect the state of modern vim.
I suppose you'll never know if there's documentation but you can't find it.
However, I looked at Derek Wyatt's vimrc file on his blog and he consistently uses a capital first letter in function names.
This just proves, only, that he's read the manual too.

Resources