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(&regmatch,
                                    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

Raspunde prin e-mail lui