Hi Nikolai!
On Di, 26 Jul 2016, Nikolai Aleksandrovich Pavlov wrote:
> Consider the following script:
>
> vim -u NONE -i NONE -N --cmd 's/^/\=execute("s#^##gn")' --cmd cq
>
> It is expected to quit Vim after doing a substitution, but instead it displays
>
> ```
> 1 match on 1 line
> Error detected while processing pre-vimrc command line:
> E48: Not allowed in sandbox: cq
> ```
>
> Further attempts to quit result in same E48.
This happens because the recursive call to do_sub() changes some static
variables and this messes up the internal state.
Attached patch fixes the obvious case, not sure if it is still a good
idea to call :s recursively.
(Patch not visible in github, only in the list-archive)
PS: I don't want to know, how many other functions suffer from the same
bug.
Best,
Christian
--
Ein Autor wird am dunkelsten, wenn er Sätze sagt, die er 1000mal
dachte und die, in seinem Innern lang erzogen, er nicht erst auf dem
Pulte erfand, wo er sie gab. Andere entwickeln sich und dem Leser
zugleich die Sache.
-- Jean Paul
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 7d8196c..779de7e 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4788,6 +4788,14 @@ do_sub(exarg_T *eap)
int start_nsubs;
#ifdef FEAT_EVAL
int save_ma = 0;
+ int cur_do_all;
+ int cur_do_ask;
+ int cur_do_count;
+ int cur_do_error;
+ int cur_do_print;
+ int cur_do_list;
+ int cur_do_number;
+ int cur_do_ic;
#endif
cmd = eap->arg;
@@ -5470,17 +5478,49 @@ do_sub(exarg_T *eap)
save_ma = curbuf->b_p_ma;
curbuf->b_p_ma = FALSE;
sandbox++;
+
}
+ /* save for recursion
+ * can happen for e.g. :s/^/\=execute("s#^##gn") */
+
+ cur_do_all = do_all;
+ cur_do_ask = do_ask;
+ cur_do_count = do_count;
+ cur_do_error = do_error;
+ cur_do_print = do_print;
+ cur_do_list = do_list;
+ cur_do_number = do_number;
+ cur_do_ic = do_ic;
#endif
/* get length of substitution part */
sublen = vim_regsub_multi(®match,
sub_firstlnum - regmatch.startpos[0].lnum,
sub, sub_firstline, FALSE, p_magic, TRUE);
#ifdef FEAT_EVAL
+ /* damn recursion! */
+ if (cur_do_all != do_all)
+ do_all = cur_do_all;
+ if (cur_do_ask != do_ask)
+ do_ask = cur_do_ask;
+ if (cur_do_count != do_count)
+ do_count = cur_do_count;
+ if (cur_do_error != do_error)
+ do_error = cur_do_error;
+ if (cur_do_print != do_print)
+ do_print = cur_do_print;
+ if (cur_do_list != do_list)
+ do_list = cur_do_list;
+ if (cur_do_number != do_number)
+ do_number = cur_do_number;
+ if (cur_do_ic != do_ic)
+ do_ic = cur_do_ic;
+
if (do_count)
{
curbuf->b_p_ma = save_ma;
- sandbox--;
+ /* might have been changed recursively */
+ if (sandbox)
+ sandbox--;
goto skip;
}
#endif