patch 8.1.1366: using expressions in a modeline is unsafe

Problem:    Using expressions in a modeline is unsafe.
Solution:   Disallow using expressions in a modeline, unless the
            'modelineexpr' option is set.  Update help, add more tests.
This commit is contained in:
Bram Moolenaar
2019-05-23 15:38:06 +02:00
parent 5357552140
commit 110289e781
6 changed files with 169 additions and 34 deletions

View File

@ -1,4 +1,4 @@
*options.txt* For Vim version 8.1. Last change: 2019 May 08 *options.txt* For Vim version 8.1. Last change: 2019 May 23
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -578,14 +578,17 @@ backslash in front of the ':' will be removed. Example:
/* vi:set dir=c\:\tmp: */ ~ /* vi:set dir=c\:\tmp: */ ~
This sets the 'dir' option to "c:\tmp". Only a single backslash before the This sets the 'dir' option to "c:\tmp". Only a single backslash before the
':' is removed. Thus to include "\:" you have to specify "\\:". ':' is removed. Thus to include "\:" you have to specify "\\:".
*E992*
No other commands than "set" are supported, for security reasons (somebody No other commands than "set" are supported, for security reasons (somebody
might create a Trojan horse text file with modelines). And not all options might create a Trojan horse text file with modelines). And not all options
can be set. For some options a flag is set, so that when it's used the can be set. For some options a flag is set, so that when the value is used
|sandbox| is effective. Still, there is always a small risk that a modeline the |sandbox| is effective. Some options can only be set from the modeline
causes trouble. E.g., when some joker sets 'textwidth' to 5 all your lines when 'modelineexpr' is set (the default is off).
are wrapped unexpectedly. So disable modelines before editing untrusted text.
The mail ftplugin does this, for example. Still, there is always a small risk that a modeline causes trouble. E.g.,
when some joker sets 'textwidth' to 5 all your lines are wrapped unexpectedly.
So disable modelines before editing untrusted text. The mail ftplugin does
this, for example.
Hint: If you would like to do something else than setting an option, you could Hint: If you would like to do something else than setting an option, you could
define an autocommand that checks the file for a specific string. For define an autocommand that checks the file for a specific string. For
@ -1149,6 +1152,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|. modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while It is not allowed to change text or jump to another window while
evaluating 'balloonexpr' |textlock|. evaluating 'balloonexpr' |textlock|.
@ -3226,7 +3230,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| if set from a The expression will be evaluated in the |sandbox| if set from a
modeline, see |sandbox-option|. modeline, see |sandbox-option|.
This option can't be set from a |modeline| when the 'diff' option is This option can't be set from a |modeline| when the 'diff' option is
on. on or the 'modelineexpr' option is off.
It is not allowed to change text or jump to another window while It is not allowed to change text or jump to another window while
evaluating 'foldexpr' |textlock|. evaluating 'foldexpr' |textlock|.
@ -3359,6 +3363,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| if set from a The expression will be evaluated in the |sandbox| if set from a
modeline, see |sandbox-option|. modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while It is not allowed to change text or jump to another window while
evaluating 'foldtext' |textlock|. evaluating 'foldtext' |textlock|.
@ -3396,6 +3401,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|. That stops the option from working, modeline, see |sandbox-option|. That stops the option from working,
since changing the buffer text is not allowed. since changing the buffer text is not allowed.
This option cannot be set in a modeline when 'modelineexpr' is off.
NOTE: This option is set to "" when 'compatible' is set. NOTE: This option is set to "" when 'compatible' is set.
*'formatlistpat'* *'flp'* *'formatlistpat'* *'flp'*
@ -3452,6 +3458,8 @@ A jump table for the options with a short description can be found at |Q_op|.
Also see 'swapsync' for controlling fsync() on swap files. Also see 'swapsync' for controlling fsync() on swap files.
'fsync' also applies to |writefile()|, unless a flag is used to 'fsync' also applies to |writefile()|, unless a flag is used to
overrule it. overrule it.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'gdefault'* *'gd'* *'nogdefault'* *'nogd'* *'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
'gdefault' 'gd' boolean (default off) 'gdefault' 'gd' boolean (default off)
@ -3619,7 +3627,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'guiheadroom'* *'ghr'* *'guiheadroom'* *'ghr'*
'guiheadroom' 'ghr' number (default 50) 'guiheadroom' 'ghr' number (default 50)
global global
- {only for GTK and X11 GUI} {only for GTK and X11 GUI}
The number of pixels subtracted from the screen height when fitting The number of pixels subtracted from the screen height when fitting
the GUI window on the screen. Set this before the GUI is started, the GUI window on the screen. Set this before the GUI is started,
e.g., in your |gvimrc| file. When zero, the whole screen height will e.g., in your |gvimrc| file. When zero, the whole screen height will
@ -3777,6 +3785,7 @@ A jump table for the options with a short description can be found at |Q_op|.
'guitabtooltip' is used for the tooltip, see below. 'guitabtooltip' is used for the tooltip, see below.
The expression will be evaluated in the |sandbox| when set from a The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|. modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
Only used when the GUI tab pages line is displayed. 'e' must be Only used when the GUI tab pages line is displayed. 'e' must be
present in 'guioptions'. For the non-GUI tab pages line 'tabline' is present in 'guioptions'. For the non-GUI tab pages line 'tabline' is
@ -4027,6 +4036,7 @@ A jump table for the options with a short description can be found at |Q_op|.
When this option contains printf-style '%' items, they will be When this option contains printf-style '%' items, they will be
expanded according to the rules used for 'statusline'. See expanded according to the rules used for 'statusline'. See
'titlestring' for example settings. 'titlestring' for example settings.
This option cannot be set in a modeline when 'modelineexpr' is off.
{not available when compiled without the |+statusline| feature} {not available when compiled without the |+statusline| feature}
*'ignorecase'* *'ic'* *'noignorecase'* *'noic'* *'ignorecase'* *'ic'* *'noignorecase'* *'noic'*
@ -4044,6 +4054,8 @@ A jump table for the options with a short description can be found at |Q_op|.
This option specifies a function that will be called to This option specifies a function that will be called to
activate or deactivate the Input Method. activate or deactivate the Input Method.
It is not used in the GUI. It is not used in the GUI.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
Example: > Example: >
function ImActivateFunc(active) function ImActivateFunc(active)
@ -4160,6 +4172,8 @@ A jump table for the options with a short description can be found at |Q_op|.
set imstatusfunc=ImStatusFunc set imstatusfunc=ImStatusFunc
< <
NOTE: This function is invoked very often. Keep it fast. NOTE: This function is invoked very often. Keep it fast.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
*'imstyle'* *'imst'* *'imstyle'* *'imst'*
'imstyle' 'imst' number (default 1) 'imstyle' 'imst' number (default 1)
@ -4176,6 +4190,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|single-repeat|, etc. Therefore over-the-spot style becomes the |single-repeat|, etc. Therefore over-the-spot style becomes the
default now. This should work fine for most people, however if you default now. This should work fine for most people, however if you
have any problem with it, try using on-the-spot style. have any problem with it, try using on-the-spot style.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
*'include'* *'inc'* *'include'* *'inc'*
'include' 'inc' string (default "^\s*#\s*include") 'include' 'inc' string (default "^\s*#\s*include")
@ -4210,6 +4226,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|. modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while It is not allowed to change text or jump to another window while
evaluating 'includeexpr' |textlock|. evaluating 'includeexpr' |textlock|.
@ -4297,6 +4314,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|. modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while It is not allowed to change text or jump to another window while
evaluating 'indentexpr' |textlock|. evaluating 'indentexpr' |textlock|.
@ -4893,6 +4911,12 @@ A jump table for the options with a short description can be found at |Q_op|.
< This option cannot be set from a |modeline| or in the |sandbox|, for < This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons. security reasons.
*'makespellmem'* *'msm'*
'makespellmem' 'msm' string (default "460000,2000,500")
global
Values relevant only when compressing a spell file, see |spell|.
This option cannot be set from a |modeline| or in the |sandbox|.
*'matchpairs'* *'mps'* *'matchpairs'* *'mps'*
'matchpairs' 'mps' string (default "(:),{:},[:]") 'matchpairs' 'mps' string (default "(:),{:},[:]")
local to buffer local to buffer
@ -4915,7 +4939,6 @@ A jump table for the options with a short description can be found at |Q_op|.
*'matchtime'* *'mat'* *'matchtime'* *'mat'*
'matchtime' 'mat' number (default 5) 'matchtime' 'mat' number (default 5)
global global
{in Nvi}
Tenths of a second to show the matching paren, when 'showmatch' is Tenths of a second to show the matching paren, when 'showmatch' is
set. Note that this is not in milliseconds, like other options that set. Note that this is not in milliseconds, like other options that
set a time. This is to be compatible with Nvi. set a time. This is to be compatible with Nvi.
@ -5049,6 +5072,17 @@ A jump table for the options with a short description can be found at |Q_op|.
'modeline' 'ml' boolean (Vim default: on (off for root), 'modeline' 'ml' boolean (Vim default: on (off for root),
Vi default: off) Vi default: off)
local to buffer local to buffer
If 'modeline' is on 'modelines' gives the number of lines that is
checked for set commands. If 'modeline' is off or 'modelines' is zero
no lines are checked. See |modeline|.
*'modelineexpr'* *'mle'* *'nomodelineexpr'* *'nomle'*
'modelineexpr' 'mle' boolean (default: off)
global
When on allow some options that are an expression to be set in the
modeline. Check the option for whether it is affected by
'modelineexpr'. Also see |modeline|.
*'modelines'* *'mls'* *'modelines'* *'mls'*
'modelines' 'mls' number (default 5) 'modelines' 'mls' number (default 5)
global global
@ -5059,9 +5093,9 @@ A jump table for the options with a short description can be found at |Q_op|.
set and to the Vim default value when 'compatible' is reset. set and to the Vim default value when 'compatible' is reset.
*'modifiable'* *'ma'* *'nomodifiable'* *'noma'* *'modifiable'* *'ma'* *'nomodifiable'* *'noma'*
*E21*
'modifiable' 'ma' boolean (default on) 'modifiable' 'ma' boolean (default on)
local to buffer local to buffer
*E21*
When off the buffer contents cannot be changed. The 'fileformat' and When off the buffer contents cannot be changed. The 'fileformat' and
'fileencoding' options also can't be changed. 'fileencoding' options also can't be changed.
Can be reset on startup with the |-M| command line argument. Can be reset on startup with the |-M| command line argument.
@ -6058,6 +6092,8 @@ A jump table for the options with a short description can be found at |Q_op|.
When this option is not empty, it determines the content of the ruler When this option is not empty, it determines the content of the ruler
string, as displayed for the 'ruler' option. string, as displayed for the 'ruler' option.
The format of this option is like that of 'statusline'. The format of this option is like that of 'statusline'.
This option cannot be set in a modeline when 'modelineexpr' is off.
The default ruler width is 17 characters. To make the ruler 15 The default ruler width is 17 characters. To make the ruler 15
characters wide, put "%15(" at the start and "%)" at the end. characters wide, put "%15(" at the start and "%)" at the end.
Example: > Example: >
@ -6598,7 +6634,8 @@ A jump table for the options with a short description can be found at |Q_op|.
"Pattern not found", "Back at original", etc. "Pattern not found", "Back at original", etc.
q use "recording" instead of "recording @a" q use "recording" instead of "recording @a"
F don't give the file info when editing a file, like `:silent` F don't give the file info when editing a file, like `:silent`
was used for the command was used for the command; note that this also affects messages
from autocommands
S do not show search count message when searching, e.g. S do not show search count message when searching, e.g.
"[1/5]" "[1/5]"
@ -7165,6 +7202,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The 'statusline' option will be evaluated in the |sandbox| if set from The 'statusline' option will be evaluated in the |sandbox| if set from
a modeline, see |sandbox-option|. a modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.
It is not allowed to change text or jump to another window while It is not allowed to change text or jump to another window while
evaluating 'statusline' |textlock|. evaluating 'statusline' |textlock|.
@ -7345,6 +7383,7 @@ A jump table for the options with a short description can be found at |Q_op|.
When changing something that is used in 'tabline' that does not When changing something that is used in 'tabline' that does not
trigger it to be updated, use |:redrawtabline|. trigger it to be updated, use |:redrawtabline|.
This option cannot be set in a modeline when 'modelineexpr' is off.
Keep in mind that only one of the tab pages is the current one, others Keep in mind that only one of the tab pages is the current one, others
are invisible and you can't jump to their windows. are invisible and you can't jump to their windows.
@ -7873,8 +7912,11 @@ A jump table for the options with a short description can be found at |Q_op|.
non-empty 't_ts' option). non-empty 't_ts' option).
When Vim was compiled with HAVE_X11 defined, the original title will When Vim was compiled with HAVE_X11 defined, the original title will
be restored if possible, see |X11|. be restored if possible, see |X11|.
When this option contains printf-style '%' items, they will be When this option contains printf-style '%' items, they will be
expanded according to the rules used for 'statusline'. expanded according to the rules used for 'statusline'.
This option cannot be set in a modeline when 'modelineexpr' is off.
Example: > Example: >
:auto BufEnter * let &titlestring = hostname() . "/" . expand("%:p") :auto BufEnter * let &titlestring = hostname() . "/" . expand("%:p")
:set title titlestring=%<%F%=%l/%L-%P titlelen=70 :set title titlestring=%<%F%=%l/%L-%P titlelen=70
@ -8060,6 +8102,8 @@ A jump table for the options with a short description can be found at |Q_op|.
undo file that exists is used. When it cannot be read an error is undo file that exists is used. When it cannot be read an error is
given, no further entry is used. given, no further entry is used.
See |undo-persistence|. See |undo-persistence|.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'undofile'* *'noundofile'* *'udf'* *'noudf'* *'undofile'* *'noundofile'* *'udf'* *'noudf'*
'undofile' 'udf' boolean (default off) 'undofile' 'udf' boolean (default off)
@ -8369,6 +8413,8 @@ A jump table for the options with a short description can be found at |Q_op|.
When equal to "NONE" no viminfo file will be read or written. When equal to "NONE" no viminfo file will be read or written.
This option can be set with the |-i| command line flag. The |--clean| This option can be set with the |-i| command line flag. The |--clean|
command line flag sets it to "NONE". command line flag sets it to "NONE".
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'virtualedit'* *'ve'* *'virtualedit'* *'ve'*
'virtualedit' 've' string (default "") 'virtualedit' 've' string (default "")

View File

@ -467,6 +467,7 @@ struct vimoption
* there is a redraw flag */ * there is a redraw flag */
#define P_NDNAME 0x8000000L /* only normal dir name chars allowed */ #define P_NDNAME 0x8000000L /* only normal dir name chars allowed */
#define P_RWINONLY 0x10000000L /* only redraw current window */ #define P_RWINONLY 0x10000000L /* only redraw current window */
#define P_MLE 0x20000000L /* under control of 'modelineexpr' */
#define ISK_LATIN1 (char_u *)"@,48-57,_,192-255" #define ISK_LATIN1 (char_u *)"@,48-57,_,192-255"
@ -650,7 +651,7 @@ static struct vimoption options[] =
{(char_u *)0L, (char_u *)0L} {(char_u *)0L, (char_u *)0L}
#endif #endif
SCTX_INIT}, SCTX_INIT},
{"balloonexpr", "bexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM, {"balloonexpr", "bexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_MLE,
#if defined(FEAT_BEVAL) && defined(FEAT_EVAL) #if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
(char_u *)&p_bexpr, PV_BEXPR, (char_u *)&p_bexpr, PV_BEXPR,
{(char_u *)"", (char_u *)0L} {(char_u *)"", (char_u *)0L}
@ -727,7 +728,7 @@ static struct vimoption options[] =
(char_u *)&p_cmp, PV_NONE, (char_u *)&p_cmp, PV_NONE,
{(char_u *)"internal,keepascii", (char_u *)0L} {(char_u *)"internal,keepascii", (char_u *)0L}
SCTX_INIT}, SCTX_INIT},
{"cdpath", "cd", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP, {"cdpath", "cd", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE|P_COMMA|P_NODUP,
#ifdef FEAT_SEARCHPATH #ifdef FEAT_SEARCHPATH
(char_u *)&p_cdpath, PV_NONE, (char_u *)&p_cdpath, PV_NONE,
{(char_u *)",,", (char_u *)0L} {(char_u *)",,", (char_u *)0L}
@ -1175,7 +1176,7 @@ static struct vimoption options[] =
{(char_u *)NULL, (char_u *)0L} {(char_u *)NULL, (char_u *)0L}
#endif #endif
SCTX_INIT}, SCTX_INIT},
{"foldexpr", "fde", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN, {"foldexpr", "fde", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN|P_MLE,
#if defined(FEAT_FOLDING) && defined(FEAT_EVAL) #if defined(FEAT_FOLDING) && defined(FEAT_EVAL)
(char_u *)VAR_WIN, PV_FDE, (char_u *)VAR_WIN, PV_FDE,
{(char_u *)"0", (char_u *)NULL} {(char_u *)"0", (char_u *)NULL}
@ -1258,7 +1259,7 @@ static struct vimoption options[] =
{(char_u *)NULL, (char_u *)0L} {(char_u *)NULL, (char_u *)0L}
#endif #endif
SCTX_INIT}, SCTX_INIT},
{"foldtext", "fdt", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN, {"foldtext", "fdt", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN|P_MLE,
#if defined(FEAT_FOLDING) && defined(FEAT_EVAL) #if defined(FEAT_FOLDING) && defined(FEAT_EVAL)
(char_u *)VAR_WIN, PV_FDT, (char_u *)VAR_WIN, PV_FDT,
{(char_u *)"foldtext()", (char_u *)NULL} {(char_u *)"foldtext()", (char_u *)NULL}
@ -1267,7 +1268,7 @@ static struct vimoption options[] =
{(char_u *)NULL, (char_u *)0L} {(char_u *)NULL, (char_u *)0L}
#endif #endif
SCTX_INIT}, SCTX_INIT},
{"formatexpr", "fex", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM, {"formatexpr", "fex", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_MLE,
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
(char_u *)&p_fex, PV_FEX, (char_u *)&p_fex, PV_FEX,
{(char_u *)"", (char_u *)0L} {(char_u *)"", (char_u *)0L}
@ -1406,7 +1407,7 @@ static struct vimoption options[] =
(char_u *)NULL, PV_NONE, (char_u *)NULL, PV_NONE,
#endif #endif
{(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT},
{"guitablabel", "gtl", P_STRING|P_VI_DEF|P_RWIN, {"guitablabel", "gtl", P_STRING|P_VI_DEF|P_RWIN|P_MLE,
#if defined(FEAT_GUI_TABLINE) #if defined(FEAT_GUI_TABLINE)
(char_u *)&p_gtl, PV_NONE, (char_u *)&p_gtl, PV_NONE,
{(char_u *)"", (char_u *)0L} {(char_u *)"", (char_u *)0L}
@ -1477,7 +1478,7 @@ static struct vimoption options[] =
(char_u *)NULL, PV_NONE, (char_u *)NULL, PV_NONE,
#endif #endif
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"iconstring", NULL, P_STRING|P_VI_DEF, {"iconstring", NULL, P_STRING|P_VI_DEF|P_MLE,
#ifdef FEAT_TITLE #ifdef FEAT_TITLE
(char_u *)&p_iconstring, PV_NONE, (char_u *)&p_iconstring, PV_NONE,
#else #else
@ -1549,7 +1550,7 @@ static struct vimoption options[] =
{(char_u *)0L, (char_u *)0L} {(char_u *)0L, (char_u *)0L}
#endif #endif
SCTX_INIT}, SCTX_INIT},
{"includeexpr", "inex", P_STRING|P_ALLOCED|P_VI_DEF, {"includeexpr", "inex", P_STRING|P_ALLOCED|P_VI_DEF|P_MLE,
#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL) #if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
(char_u *)&p_inex, PV_INEX, (char_u *)&p_inex, PV_INEX,
{(char_u *)"", (char_u *)0L} {(char_u *)"", (char_u *)0L}
@ -1561,7 +1562,7 @@ static struct vimoption options[] =
{"incsearch", "is", P_BOOL|P_VI_DEF|P_VIM, {"incsearch", "is", P_BOOL|P_VI_DEF|P_VIM,
(char_u *)&p_is, PV_NONE, (char_u *)&p_is, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"indentexpr", "inde", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM, {"indentexpr", "inde", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM|P_MLE,
#if defined(FEAT_CINDENT) && defined(FEAT_EVAL) #if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
(char_u *)&p_inde, PV_INDE, (char_u *)&p_inde, PV_INDE,
{(char_u *)"", (char_u *)0L} {(char_u *)"", (char_u *)0L}
@ -1888,6 +1889,9 @@ static struct vimoption options[] =
{"modeline", "ml", P_BOOL|P_VIM, {"modeline", "ml", P_BOOL|P_VIM,
(char_u *)&p_ml, PV_ML, (char_u *)&p_ml, PV_ML,
{(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT}, {(char_u *)FALSE, (char_u *)TRUE} SCTX_INIT},
{"modelineexpr", "mle", P_BOOL|P_VI_DEF,
(char_u *)&p_mle, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"modelines", "mls", P_NUM|P_VI_DEF, {"modelines", "mls", P_NUM|P_VI_DEF,
(char_u *)&p_mls, PV_NONE, (char_u *)&p_mls, PV_NONE,
{(char_u *)5L, (char_u *)0L} SCTX_INIT}, {(char_u *)5L, (char_u *)0L} SCTX_INIT},
@ -2311,7 +2315,7 @@ static struct vimoption options[] =
(char_u *)NULL, PV_NONE, (char_u *)NULL, PV_NONE,
#endif #endif
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"rulerformat", "ruf", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT, {"rulerformat", "ruf", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT|P_MLE,
#ifdef FEAT_STL_OPT #ifdef FEAT_STL_OPT
(char_u *)&p_ruf, PV_NONE, (char_u *)&p_ruf, PV_NONE,
#else #else
@ -2577,7 +2581,7 @@ static struct vimoption options[] =
{"startofline", "sol", P_BOOL|P_VI_DEF|P_VIM, {"startofline", "sol", P_BOOL|P_VI_DEF|P_VIM,
(char_u *)&p_sol, PV_NONE, (char_u *)&p_sol, PV_NONE,
{(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT},
{"statusline" ,"stl", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT, {"statusline" ,"stl", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT|P_MLE,
#ifdef FEAT_STL_OPT #ifdef FEAT_STL_OPT
(char_u *)&p_stl, PV_STL, (char_u *)&p_stl, PV_STL,
#else #else
@ -2624,7 +2628,7 @@ static struct vimoption options[] =
{(char_u *)0L, (char_u *)0L} {(char_u *)0L, (char_u *)0L}
#endif #endif
SCTX_INIT}, SCTX_INIT},
{"tabline", "tal", P_STRING|P_VI_DEF|P_RALL, {"tabline", "tal", P_STRING|P_VI_DEF|P_RALL|P_MLE,
#ifdef FEAT_STL_OPT #ifdef FEAT_STL_OPT
(char_u *)&p_tal, PV_NONE, (char_u *)&p_tal, PV_NONE,
#else #else
@ -2802,7 +2806,7 @@ static struct vimoption options[] =
{(char_u *)0L, (char_u *)0L} {(char_u *)0L, (char_u *)0L}
#endif #endif
SCTX_INIT}, SCTX_INIT},
{"titlestring", NULL, P_STRING|P_VI_DEF, {"titlestring", NULL, P_STRING|P_VI_DEF|P_MLE,
#ifdef FEAT_TITLE #ifdef FEAT_TITLE
(char_u *)&p_titlestring, PV_NONE, (char_u *)&p_titlestring, PV_NONE,
#else #else
@ -4549,6 +4553,11 @@ do_set(
errmsg = _("E520: Not allowed in a modeline"); errmsg = _("E520: Not allowed in a modeline");
goto skip; goto skip;
} }
if ((flags & P_MLE) && !p_mle)
{
errmsg = _("E992: Not allowed in a modeline when 'modelineexpr' is off");
goto skip;
}
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
/* In diff mode some options are overruled. This avoids that /* In diff mode some options are overruled. This avoids that
* 'foldmethod' becomes "marker" instead of "diff" and that * 'foldmethod' becomes "marker" instead of "diff" and that

View File

@ -631,6 +631,7 @@ EXTERN long p_mis; /* 'menuitems' */
#ifdef FEAT_SPELL #ifdef FEAT_SPELL
EXTERN char_u *p_msm; /* 'mkspellmem' */ EXTERN char_u *p_msm; /* 'mkspellmem' */
#endif #endif
EXTERN long p_mle; /* 'modelineexpr' */
EXTERN long p_mls; /* 'modelines' */ EXTERN long p_mls; /* 'modelines' */
EXTERN char_u *p_mouse; /* 'mouse' */ EXTERN char_u *p_mouse; /* 'mouse' */
#ifdef FEAT_GUI #ifdef FEAT_GUI

View File

@ -5,7 +5,7 @@ test49.failed, try to add one or more "G"s at the line ending in "test.out"
STARTTEST STARTTEST
:so small.vim :so small.vim
:se nocp nomore viminfo+=nviminfo :se nocp nomore viminfo+=nviminfo modelineexpr
:lang mess C :lang mess C
:so test49.vim :so test49.vim
:" Go back to this file and append the results from register r. :" Go back to this file and append the results from register r.

View File

@ -60,14 +60,17 @@ func Test_modeline_keymap()
set keymap= iminsert=0 imsearch=-1 set keymap= iminsert=0 imsearch=-1
endfunc endfunc
func s:modeline_fails(what, text) func s:modeline_fails(what, text, error)
if !exists('+' .. a:what)
return
endif
let fname = "Xmodeline_fails_" . a:what let fname = "Xmodeline_fails_" . a:what
call writefile(['vim: set ' . a:text . ' :', 'nothing'], fname) call writefile(['vim: set ' . a:text . ' :', 'nothing'], fname)
let modeline = &modeline let modeline = &modeline
set modeline set modeline
filetype plugin on filetype plugin on
syntax enable syntax enable
call assert_fails('split ' . fname, 'E474:') call assert_fails('split ' . fname, a:error)
call assert_equal("", &filetype) call assert_equal("", &filetype)
call assert_equal("", &syntax) call assert_equal("", &syntax)
@ -79,16 +82,90 @@ func s:modeline_fails(what, text)
endfunc endfunc
func Test_modeline_filetype_fails() func Test_modeline_filetype_fails()
call s:modeline_fails('filetype', 'ft=evil$CMD') call s:modeline_fails('filetype', 'ft=evil$CMD', 'E474:')
endfunc endfunc
func Test_modeline_syntax_fails() func Test_modeline_syntax_fails()
call s:modeline_fails('syntax', 'syn=evil$CMD') call s:modeline_fails('syntax', 'syn=evil$CMD', 'E474:')
endfunc endfunc
func Test_modeline_keymap_fails() func Test_modeline_keymap_fails()
if !has('keymap') call s:modeline_fails('keymap', 'keymap=evil$CMD', 'E474:')
return endfunc
endif
call s:modeline_fails('keymap', 'keymap=evil$CMD') func Test_modeline_fails_always()
call s:modeline_fails('backupdir', 'backupdir=Something()', 'E520:')
call s:modeline_fails('cdpath', 'cdpath=Something()', 'E520:')
call s:modeline_fails('charconvert', 'charconvert=Something()', 'E520:')
call s:modeline_fails('completefunc', 'completefunc=Something()', 'E520:')
call s:modeline_fails('cscopeprg', 'cscopeprg=Something()', 'E520:')
call s:modeline_fails('diffexpr', 'diffexpr=Something()', 'E520:')
call s:modeline_fails('directory', 'directory=Something()', 'E520:')
call s:modeline_fails('equalprg', 'equalprg=Something()', 'E520:')
call s:modeline_fails('errorfile', 'errorfile=Something()', 'E520:')
call s:modeline_fails('exrc', 'exrc=Something()', 'E520:')
call s:modeline_fails('formatprg', 'formatprg=Something()', 'E520:')
call s:modeline_fails('fsync', 'fsync=Something()', 'E520:')
call s:modeline_fails('grepprg', 'grepprg=Something()', 'E520:')
call s:modeline_fails('helpfile', 'helpfile=Something()', 'E520:')
call s:modeline_fails('imactivatefunc', 'imactivatefunc=Something()', 'E520:')
call s:modeline_fails('imstatusfunc', 'imstatusfunc=Something()', 'E520:')
call s:modeline_fails('imstyle', 'imstyle=Something()', 'E520:')
call s:modeline_fails('keywordprg', 'keywordprg=Something()', 'E520:')
call s:modeline_fails('langmap', 'langmap=Something()', 'E520:')
call s:modeline_fails('luadll', 'luadll=Something()', 'E520:')
call s:modeline_fails('makeef', 'makeef=Something()', 'E520:')
call s:modeline_fails('makeprg', 'makeprg=Something()', 'E520:')
call s:modeline_fails('makespellmem', 'makespellmem=Something()', 'E520:')
call s:modeline_fails('mzschemedll', 'mzschemedll=Something()', 'E520:')
call s:modeline_fails('mzschemegcdll', 'mzschemegcdll=Something()', 'E520:')
call s:modeline_fails('omnifunc', 'omnifunc=Something()', 'E520:')
call s:modeline_fails('operatorfunc', 'operatorfunc=Something()', 'E520:')
call s:modeline_fails('perldll', 'perldll=Something()', 'E520:')
call s:modeline_fails('printdevice', 'printdevice=Something()', 'E520:')
call s:modeline_fails('patchexpr', 'patchexpr=Something()', 'E520:')
call s:modeline_fails('printexpr', 'printexpr=Something()', 'E520:')
call s:modeline_fails('pythondll', 'pythondll=Something()', 'E520:')
call s:modeline_fails('pythonhome', 'pythondll=Something()', 'E520:')
call s:modeline_fails('pythonthreedll', 'pythonthreedll=Something()', 'E520:')
call s:modeline_fails('pythonthreehome', 'pythonthreehome=Something()', 'E520:')
call s:modeline_fails('pyxversion', 'pyxversion=Something()', 'E520:')
call s:modeline_fails('rubydll', 'rubydll=Something()', 'E520:')
call s:modeline_fails('runtimepath', 'runtimepath=Something()', 'E520:')
call s:modeline_fails('secure', 'secure=Something()', 'E520:')
call s:modeline_fails('shell', 'shell=Something()', 'E520:')
call s:modeline_fails('shellcmdflag', 'shellcmdflag=Something()', 'E520:')
call s:modeline_fails('shellpipe', 'shellpipe=Something()', 'E520:')
call s:modeline_fails('shellquote', 'shellquote=Something()', 'E520:')
call s:modeline_fails('shellredir', 'shellredir=Something()', 'E520:')
call s:modeline_fails('shellxquote', 'shellxquote=Something()', 'E520:')
call s:modeline_fails('spellfile', 'spellfile=Something()', 'E520:')
call s:modeline_fails('spellsuggest', 'spellsuggest=Something()', 'E520:')
call s:modeline_fails('tcldll', 'tcldll=Something()', 'E520:')
call s:modeline_fails('titleold', 'titleold=Something()', 'E520:')
call s:modeline_fails('viewdir', 'viewdir=Something()', 'E520:')
call s:modeline_fails('viminfo', 'viminfo=Something()', 'E520:')
call s:modeline_fails('viminfofile', 'viminfofile=Something()', 'E520:')
call s:modeline_fails('winptydll', 'winptydll=Something()', 'E520:')
call s:modeline_fails('undodir', 'undodir=Something()', 'E520:')
" only check a few terminal options
call s:modeline_fails('t_AB', 't_AB=Something()', 'E520:')
call s:modeline_fails('t_ce', 't_ce=Something()', 'E520:')
call s:modeline_fails('t_sr', 't_sr=Something()', 'E520:')
call s:modeline_fails('t_8b', 't_8b=Something()', 'E520:')
endfunc
func Test_modeline_fails_modelineexpr()
call s:modeline_fails('balloonexpr', 'balloonexpr=Something()', 'E992:')
call s:modeline_fails('foldexpr', 'foldexpr=Something()', 'E992:')
call s:modeline_fails('foldtext', 'foldtext=Something()', 'E992:')
call s:modeline_fails('formatexpr', 'formatexpr=Something()', 'E992:')
call s:modeline_fails('guitablabel', 'guitablabel=Something()', 'E992:')
call s:modeline_fails('iconstring', 'iconstring=Something()', 'E992:')
call s:modeline_fails('includeexpr', 'includeexpr=Something()', 'E992:')
call s:modeline_fails('indentexpr', 'indentexpr=Something()', 'E992:')
call s:modeline_fails('rulerformat', 'rulerformat=Something()', 'E992:')
call s:modeline_fails('statusline', 'statusline=Something()', 'E992:')
call s:modeline_fails('tabline', 'tabline=Something()', 'E992:')
call s:modeline_fails('titlestring', 'titlestring=Something()', 'E992:')
endfunc endfunc

View File

@ -767,6 +767,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1366,
/**/ /**/
1365, 1365,
/**/ /**/