1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
From: Bram Moolenaar <Bram@vim.org>
Date: Tue, 10 Jul 2018 19:39:18 +0200
Subject: patch 8.1.0177: defining function in sandbox is inconsistent
Problem: Defining function in sandbox is inconsistent, cannot use :function
but can define a lambda.
Solution: Allow defining a function in the sandbox, but also use the sandbox
when executing it. (closes #3182)
(cherry picked from commit 93343725b5fa1cf580a24302455980faacae8ee2)
Signed-off-by: James McCoy <jamessan@debian.org>
---
src/ex_cmds.h | 2 +-
src/userfunc.c | 29 ++++++++++++++++++++++-------
src/version.c | 2 ++
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index cb2fadc..daf2fbe 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -581,7 +581,7 @@ EX(CMD_for, "for", ex_while,
EXTRA|NOTRLCOM|SBOXOK|CMDWIN,
ADDR_LINES),
EX(CMD_function, "function", ex_function,
- EXTRA|BANG|CMDWIN,
+ EXTRA|BANG|SBOXOK|CMDWIN,
ADDR_LINES),
EX(CMD_global, "global", ex_global,
RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN,
diff --git a/src/userfunc.c b/src/userfunc.c
index 372c9bb..3782c9f 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -14,13 +14,14 @@
#include "vim.h"
#if defined(FEAT_EVAL) || defined(PROTO)
-/* function flags */
-#define FC_ABORT 0x01 /* abort function on error */
-#define FC_RANGE 0x02 /* function accepts range */
-#define FC_DICT 0x04 /* Dict function, uses "self" */
-#define FC_CLOSURE 0x08 /* closure, uses outer scope variables */
-#define FC_DELETED 0x10 /* :delfunction used while uf_refcount > 0 */
-#define FC_REMOVED 0x20 /* function redefined while uf_refcount > 0 */
+// flags used in uf_flags
+#define FC_ABORT 0x01 // abort function on error
+#define FC_RANGE 0x02 // function accepts range
+#define FC_DICT 0x04 // Dict function, uses "self"
+#define FC_CLOSURE 0x08 // closure, uses outer scope variables
+#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0
+#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0
+#define FC_SANDBOX 0x40 // function defined in the sandbox
/* From user function to hashitem and back. */
#define UF2HIKEY(fp) ((fp)->uf_name)
@@ -300,6 +301,8 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
if (prof_def_func())
func_do_profile(fp);
#endif
+ if (sandbox)
+ flags |= FC_SANDBOX;
fp->uf_varargs = TRUE;
fp->uf_flags = flags;
fp->uf_calls = 0;
@@ -643,6 +646,7 @@ call_user_func(
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
scid_T save_current_SID;
+ int using_sandbox = FALSE;
funccall_T *fc;
int save_did_emsg;
static int depth = 0;
@@ -808,6 +812,13 @@ call_user_func(
save_sourcing_name = sourcing_name;
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 1;
+
+ if (fp->uf_flags & FC_SANDBOX)
+ {
+ using_sandbox = TRUE;
+ ++sandbox;
+ }
+
/* need space for function name + ("function " + 3) or "[number]" */
len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
+ STRLEN(fp->uf_name) + 20;
@@ -968,6 +979,8 @@ call_user_func(
if (do_profiling == PROF_YES)
script_prof_restore(&wait_start);
#endif
+ if (using_sandbox)
+ --sandbox;
if (p_verbose >= 12 && sourcing_name != NULL)
{
@@ -2331,6 +2344,8 @@ ex_function(exarg_T *eap)
func_do_profile(fp);
#endif
fp->uf_varargs = varargs;
+ if (sandbox)
+ flags |= FC_SANDBOX;
fp->uf_flags = flags;
fp->uf_calls = 0;
fp->uf_script_ID = current_SID;
diff --git a/src/version.c b/src/version.c
index 0aba135..43a0f66 100644
--- a/src/version.c
+++ b/src/version.c
@@ -1195,6 +1195,8 @@ static int included_patches[] =
*/
static char *(extra_patches[]) =
{ /* Add your patch description below this line */
+/**/
+ "8.1.0177",
/**/
"8.1.0067",
/**/
|