0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

updated for version 7.0183

This commit is contained in:
Bram Moolenaar 2006-01-20 23:10:18 +00:00
parent 2d3f489e09
commit b71eaaeaa8
19 changed files with 447 additions and 123 deletions

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 7.0aa. Last change: 2006 Jan 13
*eval.txt* For Vim version 7.0aa. Last change: 2006 Jan 20
VIM REFERENCE MANUAL by Bram Moolenaar
@ -28,6 +28,7 @@ done, the features in this document are not available. See |+eval| and
9. Examples |eval-examples|
10. No +eval feature |no-eval-feature|
11. The sandbox |eval-sandbox|
12. Textlock |textlock|
{Vi does not have any of these commands}
@ -6830,5 +6831,33 @@ This is not guaranteed 100% secure, but it should block most attacks.
option that may have been set from a modeline, e.g.
'foldexpr'.
*sandbox-option*
A few options contain an expression. When this expression is evaluated it may
have to be done in the sandbox to avoid trouble. But the sandbox is
restrictive, thus this only happens when the option was set from an insecure
location. Insecure in this context are:
- sourcing a .vimrc or .exrc in the current directlry
- while executing in the sandbox
- value coming from a modeline
Note that when in the sandbox and saving an option value and restoring it, the
option will still be marked as it was set in the sandbox.
==============================================================================
12. Textlock *textlock*
In a few situations it is not allowed to change the text in the buffer, jump
to another window and some other things that might confuse or break what Vim
is currently doing. This mostly applies to things that happen when Vim is
actually doing something else. For example, evaluating the 'balloonexpr' may
happen any moment the mouse cursor is resting at some position.
This is not allowed when the textlock is active:
- changing the buffer text
- jumping to another buffer or window
- editing another file
- closing a window or quitting Vim
- etc.
vim:tw=78:ts=8:ft=help:norl:

View File

@ -1,4 +1,4 @@
*options.txt* For Vim version 7.0aa. Last change: 2006 Jan 19
*options.txt* For Vim version 7.0aa. Last change: 2006 Jan 20
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1037,6 +1037,12 @@ A jump table for the options with a short description can be found at |Q_op|.
Vim does not try to send a message to an external debugger (Netbeans
or Sun Workshop).
The expression may be evaluated in the |sandbox|, see
|sandbox-option|.
It is not allowed to change text or jump to another window while
evaluating 'balloonexpr' |textlock|.
To check whether line breaks in the balloon text work use this check: >
if has("balloon_multiline")
<
@ -2771,8 +2777,13 @@ A jump table for the options with a short description can be found at |Q_op|.
{not available when compiled without the |+folding|
or |+eval| feature}
The expression used for when 'foldmethod' is "expr". It is evaluated
for each line to obtain its fold level. See |fold-expr|. Also see
|eval-sandbox|.
for each line to obtain its fold level. See |fold-expr|.
The expression may be evaluated in the |sandbox|, see
|sandbox-option|.
It is not allowed to change text or jump to another window while
evaluating 'foldexpr' |textlock|.
*'foldignore'* *'fdi'*
'foldignore' 'fdi' string (default: "#")
@ -2904,6 +2915,12 @@ A jump table for the options with a short description can be found at |Q_op|.
An expression which is used to specify the text displayed for a closed
fold. See |fold-foldtext|.
The expression may be evaluated in the |sandbox|, see
|sandbox-option|.
It is not allowed to change text or jump to another window while
evaluating 'foldtext' |textlock|.
*'formatoptions'* *'fo'*
'formatoptions' 'fo' string (Vim default: "tcq", Vi default: "vt")
local to buffer
@ -3696,11 +3713,17 @@ A jump table for the options with a short description can be found at |Q_op|.
option to a file name. Mostly useful to change "." to "/" for Java: >
:set includeexpr=substitute(v:fname,'\\.','/','g')
< The "v:fname" variable will be set to the file name that was detected.
Evaluated in the |sandbox|.
Also used for the |gf| command if an unmodified file name can't be
found. Allows doing "gf" on the name after an 'include' statement.
Also used for |<cfile>|.
The expression may be evaluated in the |sandbox|, see
|sandbox-option|.
It is not allowed to change text or jump to another window while
evaluating 'includeexpr' |textlock|.
*'incsearch'* *'is'* *'noincsearch'* *'nois'*
'incsearch' 'is' boolean (default off)
global
@ -3746,9 +3769,16 @@ A jump table for the options with a short description can be found at |Q_op|.
:set indentexpr=GetMyIndent()
< Error messages will be suppressed, unless the 'debug' option contains
"msg".
See |indent-expression|. Also see |eval-sandbox|.
See |indent-expression|.
NOTE: This option is made empty when 'compatible' is set.
The expression may be evaluated in the |sandbox|, see
|sandbox-option|.
It is not allowed to change text or jump to another window while
evaluating 'indentexpr' |textlock|.
*'indentkeys'* *'indk'*
'indentkeys' 'indk' string (default "0{,0},:,0#,!^F,o,O,e")
local to buffer
@ -6084,7 +6114,13 @@ A jump table for the options with a short description can be found at |Q_op|.
temporarily to that of the window (and buffer) whose statusline is
currently being drawn. The expression will evaluate in this context.
The variable "actual_curbuf" is set to the 'bufnr()' number of the
real current buffer. The expression is evaluated in the |sandbox|.
real current buffer.
The 'statusline' option may be evaluated in the |sandbox|, see
|sandbox-option|.
It is not allowed to change text or jump to another window while
evaluating 'statusline' |textlock|.
If the statusline is not updated when you want it (e.g., after setting
a variable that's used in an expression), you can force an update by

View File

@ -5349,6 +5349,7 @@ hebrew hebrew.txt /*hebrew*
hebrew.txt hebrew.txt /*hebrew.txt*
help various.txt /*help*
help-context help.txt /*help-context*
help-tags tags 1
help-translated various.txt /*help-translated*
help-xterm-window various.txt /*help-xterm-window*
help.txt help.txt /*help.txt*
@ -6404,6 +6405,7 @@ s:netrw_line pi_netrw.txt /*s:netrw_line*
s:var eval.txt /*s:var*
s<CR> change.txt /*s<CR>*
sandbox eval.txt /*sandbox*
sandbox-option eval.txt /*sandbox-option*
save-file editing.txt /*save-file*
save-settings starting.txt /*save-settings*
scheme.vim syntax.txt /*scheme.vim*
@ -6929,6 +6931,7 @@ tex-style syntax.txt /*tex-style*
tex.vim syntax.txt /*tex.vim*
text-objects motion.txt /*text-objects*
text-objects-changed version5.txt /*text-objects-changed*
textlock eval.txt /*textlock*
tf.vim syntax.txt /*tf.vim*
this_session-variable eval.txt /*this_session-variable*
throw-catch eval.txt /*throw-catch*

View File

@ -1,4 +1,4 @@
*todo.txt* For Vim version 7.0aa. Last change: 2006 Jan 19
*todo.txt* For Vim version 7.0aa. Last change: 2006 Jan 20
VIM REFERENCE MANUAL by Bram Moolenaar
@ -30,20 +30,6 @@ be worked on, but only if you sponsor Vim development. See |sponsor|.
*known-bugs*
-------------------- Known bugs and current work -----------------------
Evaluate 'balloonexpr' in the sandbox only when it was set from an unsafe
place (e.g., modeline)? Patch from Sumner Hayes, Jan 12. Also use for other
options?
":saveas asdf.c" should set 'filetype' to c when it's empty. Also for ":w
asdf.c" when it sets the buffer filename.
When ":cclose" is used the buffer is not wiped out and is no longer recognized
as a quickfix buffer, thus it's not reused either.
Patch to support lists and dicts for the Python interface. (G. Sumner Hayes,
Jan 12). Docs in a previous patch.
Use free_tv() instead of clear_tv() and vim_free().
ccomplete:
- When using page-up/page-down in menu it sometimes jumps more than a page.
- When an option is set: In completion mode and the user types (identifier)
@ -71,9 +57,9 @@ ccomplete:
Can't reproduce it right now...
spelling:
- Include script to cleanup a .add file. (Antonio Colombo, Jan 9)
- suggestions for "macARONI" doesn't include "macaroni", they are all allcap.
suggestion for "KG" to "kg" when it's keepcase.
- Use runtime/cleanadd script to cleanup .add files. When to invoke it?
After deleting a word and some timestamp difference perhaps?
- suggestion for "KG" to "kg" when it's keepcase.
- Autocommand event for when a spell file is missing. Allows making a plugin
that fetches the file over internet. Pattern == language.
- Using KEEPCASE flag still allows all-upper word, docs say it doesn't.

View File

@ -1,4 +1,4 @@
*version7.txt* For Vim version 7.0aa. Last change: 2006 Jan 19
*version7.txt* For Vim version 7.0aa. Last change: 2006 Jan 20
VIM REFERENCE MANUAL by Bram Moolenaar
@ -154,6 +154,9 @@ expr". "-=" and ".=" works in a similar way.
With the |:profile| command you can find out where your function or script
wastes its time.
In the Python interface vim.eval() also handles Dictionaries and Lists.
|python-eval| (G. Sumner Hayes)
Spell checking *new-spell*
--------------
@ -667,6 +670,15 @@ iterative mechanism. This avoids out-of-stack errors. State is stored in
allocated memory, running out of memory can always be detected. Allows
matching more complex things, but Vim may seem to hang while doing that.
Previously some options were always evaluated in the |sandbox|. Now that only
happens when the option was set from a modeline or in secure mode. Applies to
'balloonexpr', 'foldexpr', 'foldtext' and 'includeexpr'. (Sumner Hayes)
Some commands and expressions could have nasty side effects, such as using
CTRL-R = while editing a search pattern and the expression invokes a function
that jumps to another window. The |textlock| has been added to prevent this
from happening.
":breakadd here" and ":breakdel here" can be used to set or delete a
breakpoint at the cursor.
@ -925,6 +937,10 @@ and for supported autocommand events. (Yegappan Lakshmanan)
Allow using ":global" in the sandbox, it doesn't do anything harmful by
itself.
":saveas asdf.c" will set 'filetype' to c when it's empty. Also for ":w
asdf.c" when it sets the filename for the buffer.
==============================================================================
COMPILE TIME CHANGES *compile-changes-7*
@ -1528,8 +1544,8 @@ string, because it may cause trouble in Insert mode.
When evaluating an expression for CTRL-R = on the command line it was possible
to call a function that opens a new window, resulting in errors for
incremental search, and many other nasty things were possible. Now set
"cmdline_busy" and disallow changing the buffer or jumpting to another window
incremental search, and many other nasty things were possible. Now use the
|textlock| to disallow changing the buffer or jumping to another window
to protect from unexpected behavior. Same for CTRL-\ e.
"d(" deleted the character under the cursor, while the documentation specified
@ -1574,4 +1590,10 @@ When expanding a file name for a shell command, as in "!cmd foo<Tab>" or ":r
!cmd foo<Tab>" also escape characters that are special for the shell:
"!;&()<>".
When the name of the buffer was set by a ":r fname" command |cpo-f| no
autocommands were triggered to notify about the change in the buffer list.
In the quickfix buffer 'bufhidden' was set to "delete", which caused closing
the quickfix window to leave an unlisted "No Name" buffer behind every time.
vim:tw=78:ts=8:ft=help:norl:

View File

@ -291,7 +291,7 @@ edit(cmdchar, startln, count)
#endif
/* Don't allow changes in the buffer while editing the cmdline. The
* caller of getcmdline() may get confused. */
if (cmdline_busy)
if (textlock != 0)
{
EMSG(_(e_secure));
return FALSE;

View File

@ -420,8 +420,8 @@ static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef));
static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv));
static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID));
static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
static char_u *list2string __ARGS((typval_T *tv));
static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo));
static char_u *list2string __ARGS((typval_T *tv, int copyID));
static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
static void set_ref_in_list __ARGS((list_T *l, int copyID));
static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
@ -435,10 +435,10 @@ static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID));
static int dict_add __ARGS((dict_T *d, dictitem_T *item));
static long dict_len __ARGS((dict_T *d));
static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len));
static char_u *dict2string __ARGS((typval_T *tv));
static char_u *dict2string __ARGS((typval_T *tv, int copyID));
static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf));
static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf));
static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID));
static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID));
static char_u *string_quote __ARGS((char_u *str, int function));
static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
static int find_internal_func __ARGS((char_u *name));
@ -1175,20 +1175,26 @@ eval_to_string(arg, nextcmd)
}
/*
* Call eval_to_string() with "sandbox" set and not using local variables.
* Call eval_to_string() without using current local variables and using
* textlock. When "use_sandbox" is TRUE use the sandbox.
*/
char_u *
eval_to_string_safe(arg, nextcmd)
eval_to_string_safe(arg, nextcmd, use_sandbox)
char_u *arg;
char_u **nextcmd;
int use_sandbox;
{
char_u *retval;
void *save_funccalp;
save_funccalp = save_funccal();
++sandbox;
if (use_sandbox)
++sandbox;
++textlock;
retval = eval_to_string(arg, nextcmd);
--sandbox;
if (use_sandbox)
--sandbox;
--textlock;
restore_funccal(save_funccalp);
return retval;
}
@ -1566,9 +1572,12 @@ eval_foldexpr(arg, cp)
typval_T tv;
int retval;
char_u *s;
int use_sandbox = was_set_insecurely((char_u *)"foldexpr");
++emsg_off;
++sandbox;
if (use_sandbox)
++sandbox;
++textlock;
*cp = NUL;
if (eval0(arg, &tv, NULL, TRUE) == FAIL)
retval = 0;
@ -1591,7 +1600,9 @@ eval_foldexpr(arg, cp)
clear_tv(&tv);
}
--emsg_off;
--sandbox;
if (use_sandbox)
--sandbox;
--textlock;
return retval;
}
@ -1985,7 +1996,7 @@ list_arg_vars(eap, arg)
int c;
char_u *s;
s = echo_string(&tv, &tf, numbuf);
s = echo_string(&tv, &tf, numbuf, 0);
c = *arg;
*arg = NUL;
list_one_var_a((char_u *)"",
@ -5310,6 +5321,18 @@ list_equal(l1, l2, ic)
return item1 == NULL && item2 == NULL;
}
#if defined(FEAT_PYTHON) || defined(PROTO)
/*
* Return the dictitem that an entry in a hashtable points to.
*/
dictitem_T *
dict_lookup(hi)
hashitem_T *hi;
{
return HI2DI(hi);
}
#endif
/*
* Return TRUE when two dictionaries have exactly the same key/values.
*/
@ -5777,8 +5800,9 @@ list_remove(l, item, item2)
* May return NULL.
*/
static char_u *
list2string(tv)
list2string(tv, copyID)
typval_T *tv;
int copyID;
{
garray_T ga;
@ -5786,7 +5810,7 @@ list2string(tv)
return NULL;
ga_init2(&ga, (int)sizeof(char), 80);
ga_append(&ga, '[');
if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL)
if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL)
{
vim_free(ga.ga_data);
return NULL;
@ -5802,11 +5826,12 @@ list2string(tv)
* Return FAIL or OK.
*/
static int
list_join(gap, l, sep, echo)
list_join(gap, l, sep, echo, copyID)
garray_T *gap;
list_T *l;
char_u *sep;
int echo;
int copyID;
{
int first = TRUE;
char_u *tofree;
@ -5822,9 +5847,9 @@ list_join(gap, l, sep, echo)
ga_concat(gap, sep);
if (echo)
s = echo_string(&item->li_tv, &tofree, numbuf);
s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
else
s = tv2string(&item->li_tv, &tofree, numbuf);
s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
if (s != NULL)
ga_concat(gap, s);
vim_free(tofree);
@ -6355,8 +6380,9 @@ get_dict_number(d, key)
* May return NULL.
*/
static char_u *
dict2string(tv)
dict2string(tv, copyID)
typval_T *tv;
int copyID;
{
garray_T ga;
int first = TRUE;
@ -6391,7 +6417,7 @@ dict2string(tv)
vim_free(tofree);
}
ga_concat(&ga, (char_u *)": ");
s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf);
s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
if (s != NULL)
ga_concat(&ga, s);
vim_free(tofree);
@ -6535,13 +6561,15 @@ failret:
* If the memory is allocated "tofree" is set to it, otherwise NULL.
* "numbuf" is used for a number.
* Does not put quotes around strings, as ":echo" displays values.
* When "copyID" is not NULL replace recursive lists and dicts with "...".
* May return NULL;
*/
static char_u *
echo_string(tv, tofree, numbuf)
echo_string(tv, tofree, numbuf, copyID)
typval_T *tv;
char_u **tofree;
char_u *numbuf;
int copyID;
{
static int recurse = 0;
char_u *r = NULL;
@ -6560,19 +6588,51 @@ echo_string(tv, tofree, numbuf)
*tofree = NULL;
r = tv->vval.v_string;
break;
case VAR_LIST:
*tofree = list2string(tv);
r = *tofree;
if (tv->vval.v_list == NULL)
{
*tofree = NULL;
r = NULL;
}
else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
{
*tofree = NULL;
r = (char_u *)"[...]";
}
else
{
tv->vval.v_list->lv_copyID = copyID;
*tofree = list2string(tv, copyID);
r = *tofree;
}
break;
case VAR_DICT:
*tofree = dict2string(tv);
r = *tofree;
if (tv->vval.v_dict == NULL)
{
*tofree = NULL;
r = NULL;
}
else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
{
*tofree = NULL;
r = (char_u *)"{...}";
}
else
{
tv->vval.v_dict->dv_copyID = copyID;
*tofree = dict2string(tv, copyID);
r = *tofree;
}
break;
case VAR_STRING:
case VAR_NUMBER:
*tofree = NULL;
r = get_tv_string_buf(tv, numbuf);
break;
default:
EMSG2(_(e_intern2), "echo_string()");
*tofree = NULL;
@ -6590,10 +6650,11 @@ echo_string(tv, tofree, numbuf)
* May return NULL;
*/
static char_u *
tv2string(tv, tofree, numbuf)
tv2string(tv, tofree, numbuf, copyID)
typval_T *tv;
char_u **tofree;
char_u *numbuf;
int copyID;
{
switch (tv->v_type)
{
@ -6610,7 +6671,7 @@ tv2string(tv, tofree, numbuf)
default:
EMSG2(_(e_intern2), "tv2string()");
}
return echo_string(tv, tofree, numbuf);
return echo_string(tv, tofree, numbuf, copyID);
}
/*
@ -11302,7 +11363,7 @@ f_join(argvars, rettv)
if (sep != NULL)
{
ga_init2(&ga, (int)sizeof(char), 80);
list_join(&ga, argvars[0].vval.v_list, sep, TRUE);
list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
ga_append(&ga, NUL);
rettv->vval.v_string = (char_u *)ga.ga_data;
}
@ -11695,7 +11756,7 @@ find_some_match(argvars, rettv, type)
break;
}
vim_free(tofree);
str = echo_string(&li->li_tv, &tofree, strbuf);
str = echo_string(&li->li_tv, &tofree, strbuf,0);
if (str == NULL)
break;
}
@ -13734,8 +13795,8 @@ item_compare(s1, s2)
char_u numbuf1[NUMBUFLEN];
char_u numbuf2[NUMBUFLEN];
p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1);
p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2);
p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
if (item_compare_ic)
res = STRICMP(p1, p2);
else
@ -14212,7 +14273,7 @@ f_string(argvars, rettv)
char_u numbuf[NUMBUFLEN];
rettv->v_type = VAR_STRING;
rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf);
rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
if (tofree == NULL)
rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
}
@ -16407,7 +16468,7 @@ list_one_var(v, prefix)
char_u *s;
char_u numbuf[NUMBUFLEN];
s = echo_string(&v->di_tv, &tofree, numbuf);
s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID);
list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
s == NULL ? (char_u *)"" : s);
vim_free(tofree);
@ -16782,7 +16843,7 @@ ex_echo(eap)
}
else if (eap->cmdidx == CMD_echo)
msg_puts_attr((char_u *)" ", echo_attr);
p = echo_string(&rettv, &tofree, numbuf);
p = echo_string(&rettv, &tofree, numbuf, ++current_copyID);
if (p != NULL)
for ( ; *p != NUL && !got_int; ++p)
{
@ -18499,7 +18560,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
msg_outnum((long)argvars[i].vval.v_number);
else
{
trunc_string(tv2string(&argvars[i], &tofree, numbuf),
trunc_string(tv2string(&argvars[i], &tofree, numbuf, 0),
buf, MSG_BUF_CLEN);
msg_puts(buf);
vim_free(tofree);
@ -18584,7 +18645,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
/* The value may be very long. Skip the middle part, so that we
* have some idea how it starts and ends. smsg() would always
* truncate it at the end. */
trunc_string(tv2string(fc.rettv, &tofree, numbuf),
trunc_string(tv2string(fc.rettv, &tofree, numbuf, 0),
buf, MSG_BUF_CLEN);
smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
vim_free(tofree);
@ -18806,7 +18867,7 @@ get_return_cmd(rettv)
char_u numbuf[NUMBUFLEN];
if (rettv != NULL)
s = echo_string((typval_T *)rettv, &tofree, numbuf);
s = echo_string((typval_T *)rettv, &tofree, numbuf, 0);
if (s == NULL)
s = (char_u *)"";
@ -19076,7 +19137,7 @@ write_viminfo_varlist(fp)
default: continue;
}
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
p = echo_string(&this_var->di_tv, &tofree, numbuf);
p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
if (p != NULL)
viminfo_writestring(fp, p);
vim_free(tofree);

View File

@ -2583,11 +2583,19 @@ do_write(eap)
retval = FAIL;
goto theend;
}
/* If 'filetype' was empty try detecting it now. */
if (*curbuf->b_p_ft == NUL)
{
(void)do_doautocmd((char_u *)"filetypedetect BufRead", TRUE);
do_modelines(FALSE);
}
#endif
}
retval = buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
eap, eap->append, eap->forceit, TRUE, FALSE);
}
theend:
@ -2861,7 +2869,7 @@ getfile(fnum, ffname, sfname, setpm, lnum, forceit)
int retval;
char_u *free_me = NULL;
if (editing_cmdline())
if (text_locked())
return 1;
if (fnum == 0)

View File

@ -661,13 +661,13 @@ getcmdline(firstc, count, indent)
restore_cmdline(&save_ccline);
if (c == '=')
{
/* Need to save and restore ccline. And set cmdline_busy
/* Need to save and restore ccline. And set "textlock"
* to avoid nasty things like going to another buffer when
* evaluating an expression. */
save_cmdline(&save_ccline);
++cmdline_busy;
++textlock;
p = get_expr_line();
--cmdline_busy;
--textlock;
restore_cmdline(&save_ccline);
if (p != NULL && realloc_cmdbuff((int)STRLEN(p) + 1) == OK)
@ -1875,17 +1875,18 @@ getcmdline_prompt(firstc, prompt, attr, xp_context, xp_arg)
#endif
/*
* Return TRUE when the command line is being edited. That means the current
* buffer and window can't be changed.
* Return TRUE when the text must not be changed and we can't switch to
* another window or buffer. Used when editing the command line, evaluating
* 'balloonexpr', etc.
*/
int
editing_cmdline()
text_locked()
{
#ifdef FEAT_CMDWIN
if (cmdwin_type != 0)
return TRUE;
#endif
return cmdline_busy;
return textlock != 0;
}
/*
@ -1893,7 +1894,7 @@ editing_cmdline()
* window is open or editing the cmdline in another way.
*/
void
editing_cmdline_msg()
text_locked_msg()
{
#ifdef FEAT_CMDWIN
if (cmdwin_type != 0)
@ -2814,12 +2815,12 @@ cmdline_paste(regname, literally)
regname = may_get_selection(regname);
#endif
/* Need to save and restore ccline. And set cmdline_busy to avoid nasty
/* Need to save and restore ccline. And set "textlock" to avoid nasty
* things like going to another buffer when evaluating an expression. */
save_cmdline(&save_ccline);
++cmdline_busy;
++textlock;
i = get_spec_reg(regname, &arg, &allocated, TRUE);
--cmdline_busy;
--textlock;
restore_cmdline(&save_ccline);
if (i)
@ -3837,8 +3838,8 @@ addstar(fname, len, context)
/* Custom expansion takes care of special things, match
* backslashes literally (perhaps also for other types?) */
if ((context == EXPAND_USER_DEFINED ||
context == EXPAND_USER_LIST) && fname[i] == '\\')
if ((context == EXPAND_USER_DEFINED
|| context == EXPAND_USER_LIST) && fname[i] == '\\')
new_len++; /* '\' becomes "\\" */
}
retval = alloc(new_len);

View File

@ -1938,7 +1938,8 @@ get_foldtext(wp, lnum, lnume, foldinfo, buf)
curbuf = wp->w_buffer;
++emsg_off;
text = eval_to_string_safe(wp->w_p_fdt, NULL);
text = eval_to_string_safe(wp->w_p_fdt, NULL,
was_set_insecurely((char_u *)"foldtext"));
--emsg_off;
curwin = save_curwin;

View File

@ -86,7 +86,6 @@ EXTERN int clear_cmdline INIT(= FALSE); /* cmdline must be cleared */
#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */
#endif
EXTERN int cmdline_busy INIT(= FALSE); /* editing the cmdline */
EXTERN int exec_from_reg INIT(= FALSE); /* executing register */
@ -547,12 +546,16 @@ EXTERN int secure INIT(= FALSE);
* allowed, e.g. when sourcing .exrc or .vimrc
* in current directory */
EXTERN int textlock INIT(= 0);
/* non-zero when changing text and jumping to
* another window or buffer is not allowed */
#ifdef FEAT_EVAL
# define HAVE_SANDBOX
EXTERN int sandbox INIT(= 0);
/* non-zero when evaluating an expression in a
* "sandbox". Not allowed to change the
* buffer. */
/* Non-zero when evaluating an expression in a
* "sandbox". Several things are not allowed
* then. */
#endif
EXTERN int silent_mode INIT(= FALSE);
@ -1413,10 +1416,7 @@ EXTERN char_u e_invexprmsg[] INIT(= N_("E449: Invalid expression received"));
EXTERN char_u e_guarded[] INIT(= N_("E463: Region is guarded, cannot modify"));
EXTERN char_u e_nbreadonly[] INIT(= N_("E744: NetBeans does not allow changes in read-only files"));
#endif
#if defined(FEAT_INS_EXPAND) || defined(FEAT_EVAL) || defined(FEAT_SYN_HL) \
|| defined(PROTO)
EXTERN char_u e_intern2[] INIT(= N_("E685: Internal error: %s"));
#endif
EXTERN char_u e_maxmempat[] INIT(= N_("E363: pattern uses more memory than 'maxmempattern'"));
EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer"));

View File

@ -23,6 +23,7 @@ general_beval_cb(beval, state)
{
win_T *wp;
int col;
int use_sandbox;
linenr_T lnum;
char_u *text;
static char_u *result = NULL;
@ -50,10 +51,17 @@ general_beval_cb(beval, state)
set_vim_var_string(VV_BEVAL_TEXT, text, -1);
vim_free(text);
++sandbox;
use_sandbox = was_set_insecurely((char_u *)"balloonexpr");
if (use_sandbox)
++sandbox;
++textlock;
vim_free(result);
result = eval_to_string(p_bexpr, NULL);
--sandbox;
if (use_sandbox)
--sandbox;
--textlock;
set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
if (result != NULL && result[0] != NUL)

View File

@ -1082,35 +1082,137 @@ VimCommand(PyObject *self, PyObject *args)
return result;
}
/*
* Function to translate a typval_T into a PyObject; this will recursively
* translate lists/dictionaries into their Python equivalents.
*
* The depth parameter is too avoid infinite recursion, set it to 1 when
* you call VimToPython.
*/
static PyObject *
VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
{
PyObject *result;
PyObject *newObj;
char ptrBuf[NUMBUFLEN];
/* Avoid infinite recursion */
if (depth > 100)
{
Py_INCREF(Py_None);
result = Py_None;
return result;
}
/* Check if we run into a recursive loop. The item must be in lookupDict
* then and we can use it again. */
sprintf(ptrBuf, "%ld", (long)our_tv);
result = PyDict_GetItemString(lookupDict, ptrBuf);
if (result != NULL)
Py_INCREF(result);
else if (our_tv->v_type == VAR_STRING)
{
result = Py_BuildValue("s", our_tv->vval.v_string);
PyDict_SetItemString(lookupDict, ptrBuf, result);
}
else if (our_tv->v_type == VAR_NUMBER)
{
char buf[NUMBUFLEN];
/* For backwards compatibility numbers are stored as strings. */
sprintf(buf, "%ld", (long)our_tv->vval.v_number);
result = Py_BuildValue("s", buf);
PyDict_SetItemString(lookupDict, ptrBuf, result);
}
else if (our_tv->v_type == VAR_LIST)
{
list_T *list = our_tv->vval.v_list;
listitem_T *curr;
result = PyList_New(0);
PyDict_SetItemString(lookupDict, ptrBuf, result);
if (list != NULL)
{
for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
{
newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
PyList_Append(result, newObj);
Py_DECREF(newObj);
}
}
}
else if (our_tv->v_type == VAR_DICT)
{
result = PyDict_New();
PyDict_SetItemString(lookupDict, ptrBuf, result);
if (our_tv->vval.v_dict != NULL)
{
hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
int todo = ht->ht_used;
hashitem_T *hi;
dictitem_T *di;
for (hi = ht->ht_array; todo > 0; ++hi)
{
if (!HASHITEM_EMPTY(hi))
{
--todo;
di = dict_lookup(hi);
newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
Py_DECREF(newObj);
}
}
}
}
else
{
Py_INCREF(Py_None);
result = Py_None;
}
return result;
}
/*ARGSUSED*/
static PyObject *
VimEval(PyObject *self, PyObject *args)
{
#ifdef FEAT_EVAL
char *expr;
char *str;
typval_T *our_tv;
PyObject *result;
PyObject *lookup_dict;
if (!PyArg_ParseTuple(args, "s", &expr))
return NULL;
Py_BEGIN_ALLOW_THREADS
Python_Lock_Vim();
str = (char *)eval_to_string((char_u *)expr, NULL);
our_tv = eval_expr((char_u *)expr, NULL);
Python_Release_Vim();
Py_END_ALLOW_THREADS
if (str == NULL)
if (our_tv == NULL)
{
PyErr_SetVim(_("invalid expression"));
return NULL;
}
result = Py_BuildValue("s", str);
/* Convert the Vim type into a Python type. Create a dictionary that's
* used to check for recursive loops. */
lookup_dict = PyDict_New();
result = VimToPython(our_tv, 1, lookup_dict);
Py_DECREF(lookup_dict);
Py_BEGIN_ALLOW_THREADS
Python_Lock_Vim();
vim_free(str);
free_tv(our_tv);
Python_Release_Vim();
Py_END_ALLOW_THREADS

View File

@ -7673,12 +7673,17 @@ get_expr_indent()
int indent;
pos_T pos;
int save_State;
int use_sandbox = was_set_insecurely((char_u *)"indentexpr");
pos = curwin->w_cursor;
set_vim_var_nr(VV_LNUM, curwin->w_cursor.lnum);
++sandbox;
if (use_sandbox)
++sandbox;
++textlock;
indent = eval_to_number(curbuf->b_p_inde);
--sandbox;
if (use_sandbox)
--sandbox;
--textlock;
/* Restore the cursor position so that 'indentexpr' doesn't need to.
* Pretend to be in Insert mode, allow cursor past end of line for "o"

View File

@ -317,6 +317,7 @@ struct vimoption
#define P_GETTEXT 0x80000L/* expand default value with _() */
#define P_NOGLOB 0x100000L/* do not use local value for global vimrc */
#define P_NFNAME 0x200000L/* only normal file name chars allowed */
#define P_INSECURE 0x400000L/* option was set from a modeline */
/*
* options[] is initialized here.
@ -1460,7 +1461,7 @@ static struct vimoption
{"magic", NULL, P_BOOL|P_VI_DEF,
(char_u *)&p_magic, PV_NONE,
{(char_u *)TRUE, (char_u *)0L}},
{"makeef", "mef", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
{"makeef", "mef", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
#ifdef FEAT_QUICKFIX
(char_u *)&p_mef, PV_NONE,
{(char_u *)"", (char_u *)0L}
@ -2632,6 +2633,7 @@ static char *(p_cot_values[]) = {"menu", NULL};
static void set_option_default __ARGS((int, int opt_flags, int compatible));
static void set_options_default __ARGS((int opt_flags));
static void did_set_option __ARGS((int opt_idx, int opt_flags, int new_value));
static char_u *illegal_char __ARGS((char_u *, int));
static int string_to_key __ARGS((char_u *arg));
#ifdef FEAT_CMDWIN
@ -3157,6 +3159,9 @@ set_option_default(opt_idx, opt_flags, compatible)
*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
*(int *)varp;
}
/* the default value is not insecure */
options[opt_idx].flags &= ~P_INSECURE;
}
#ifdef FEAT_EVAL
@ -3790,6 +3795,12 @@ do_set(arg, opt_flags)
}
}
/* Skip all options that are not window-local (used when showing
* an already loaded buffer in a window). */
if ((opt_flags & OPT_WINONLY)
&& (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
goto skip;
/* Disallow changing some options from modelines */
if ((opt_flags & OPT_MODELINE) && (flags & P_SECURE))
{
@ -3797,15 +3808,9 @@ do_set(arg, opt_flags)
goto skip;
}
/* Skip all options that are not window-local (used when showing
* an already loaded buffer in a window). */
if ((opt_flags & OPT_WINONLY)
&& (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
goto skip;
#ifdef HAVE_SANDBOX
/* Disallow changing some options in the sandbox */
if (sandbox > 0 && (flags & P_SECURE))
if (sandbox != 0 && (flags & P_SECURE))
{
errmsg = (char_u *)_(e_sandbox);
goto skip;
@ -4343,8 +4348,10 @@ do_set(arg, opt_flags)
redraw_all_later(CLEAR);
}
}
if (opt_idx >= 0)
options[opt_idx].flags |= P_WAS_SET;
did_set_option(opt_idx, opt_flags,
!prepending && !adding && !removing);
}
skip:
@ -4405,6 +4412,31 @@ theend:
return OK;
}
/*
* Call this when an option has been given a new value through a user command.
* Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
*/
static void
did_set_option(opt_idx, opt_flags, new_value)
int opt_idx;
int opt_flags; /* possibly with OPT_MODELINE */
int new_value; /* value was replaced completely */
{
options[opt_idx].flags |= P_WAS_SET;
/* When an option is set in the sandbox, from a modeline or in secure mode
* set the P_INSECURE flag. Otherwise, if a new value is stored reset the
* flag. */
if (secure
#ifdef HAVE_SANDBOX
|| sandbox != 0
#endif
|| (opt_flags & OPT_MODELINE))
options[opt_idx].flags |= P_INSECURE;
else if (new_value)
options[opt_idx].flags &= ~P_INSECURE;
}
static char_u *
illegal_char(errbuf, c)
char_u *errbuf;
@ -4837,6 +4869,25 @@ set_term_option_alloced(p)
return; /* cannot happen: didn't find it! */
}
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* Return TRUE when option "opt" was set from a modeline or in secure mode.
* Return FALSE when it wasn't.
* Return -1 for an unknown option.
*/
int
was_set_insecurely(opt)
char_u *opt;
{
int idx = findoption(opt);
if (idx >= 0)
return (options[idx].flags & P_INSECURE) != 0;
EMSG2(_(e_intern2), "was_set_insecurely()");
return -1;
}
#endif
/*
* Set a string option to a new value (without checking the effect).
* The string is copied into allocated memory.
@ -4938,9 +4989,9 @@ set_string_option(opt_idx, value, opt_flags)
: opt_flags);
oldval = *varp;
*varp = s;
options[opt_idx].flags |= P_WAS_SET;
(void)did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
opt_flags);
if (did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
opt_flags) == NULL)
did_set_option(opt_idx, opt_flags, TRUE);
}
}
@ -6571,10 +6622,6 @@ set_bool_option(opt_idx, varp, value, opt_flags)
{
int old_value = *(int *)varp;
#ifdef FEAT_GUI
need_mouse_correct = TRUE;
#endif
/* Disallow changing some options from secure mode */
if ((secure
#ifdef HAVE_SANDBOX
@ -6589,6 +6636,10 @@ set_bool_option(opt_idx, varp, value, opt_flags)
options[opt_idx].scriptID = current_SID;
#endif
#ifdef FEAT_GUI
need_mouse_correct = TRUE;
#endif
/* May set global value for local option. */
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
@ -7077,15 +7128,22 @@ set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags)
long old_Columns = Columns; /* remember old Columns */
long *pp = (long *)varp;
#ifdef FEAT_GUI
need_mouse_correct = TRUE;
/* Disallow changing some options from secure mode. */
if ((secure
#ifdef HAVE_SANDBOX
|| sandbox != 0
#endif
) && (options[opt_idx].flags & P_SECURE))
return e_secure;
*pp = value;
#ifdef FEAT_EVAL
/* Remember where the option was set. */
options[opt_idx].scriptID = current_SID;
#endif
#ifdef FEAT_GUI
need_mouse_correct = TRUE;
#endif
if (curbuf->b_p_sw <= 0)
{
@ -7690,10 +7748,12 @@ set_option_value(name, number, string, opt_flags)
#ifdef HAVE_SANDBOX
/* Disallow changing some options in the sandbox */
if (sandbox > 0 && (flags & P_SECURE))
{
EMSG(_(e_sandbox));
else
return;
}
#endif
if (flags & P_STRING)
if (flags & P_STRING)
set_string_option(opt_idx, string, opt_flags);
else
{
@ -7704,7 +7764,8 @@ set_option_value(name, number, string, opt_flags)
(void)set_num_option(opt_idx, varp, number,
NULL, 0, opt_flags);
else
(void)set_bool_option(opt_idx, varp, (int)number, opt_flags);
(void)set_bool_option(opt_idx, varp, (int)number,
opt_flags);
}
}
}

View File

@ -18,7 +18,7 @@ int eval_to_bool __ARGS((char_u *arg, int *error, char_u **nextcmd, int skip));
char_u *eval_to_string_skip __ARGS((char_u *arg, char_u **nextcmd, int skip));
int skip_expr __ARGS((char_u **pp));
char_u *eval_to_string __ARGS((char_u *arg, char_u **nextcmd));
char_u *eval_to_string_safe __ARGS((char_u *arg, char_u **nextcmd));
char_u *eval_to_string_safe __ARGS((char_u *arg, char_u **nextcmd, int use_sandbox));
int eval_to_number __ARGS((char_u *expr));
list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr));
int get_spellword __ARGS((list_T *list, char_u **pp));
@ -43,6 +43,7 @@ int do_unlet __ARGS((char_u *name, int forceit));
void del_menutrans_vars __ARGS((void));
char_u *get_user_var_name __ARGS((expand_T *xp, int idx));
void list_unref __ARGS((list_T *l));
dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
int list_append_dict __ARGS((list_T *list, dict_T *dict));
int garbage_collect __ARGS((void));
dict_T *dict_alloc __ARGS((void));

View File

@ -1880,7 +1880,7 @@ ex_copen(eap)
set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
OPT_LOCAL);
set_option_value((char_u *)"bh", 0L, (char_u *)"delete", OPT_LOCAL);
set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
}
else if (buf != curbuf)

View File

@ -182,7 +182,7 @@ undo_allowed()
/* Don't allow changes in the buffer while editing the cmdline. The
* caller of getcmdline() may get confused. */
if (cmdline_busy)
if (textlock != 0)
{
EMSG(_(e_secure));
return FALSE;

View File

@ -36,5 +36,5 @@
#define VIM_VERSION_NODOT "vim70aa"
#define VIM_VERSION_SHORT "7.0aa"
#define VIM_VERSION_MEDIUM "7.0aa ALPHA"
#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 19)"
#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 19, compiled "
#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 20)"
#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 20, compiled "