aboutsummaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-01-04 13:09:47 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-01-04 13:09:47 -0200
commit4ace93ca6502dd1da38d5c06fa099d229e791ba8 (patch)
tree34f95ef56aecb56ae1db5e8b843b6e9bd2cbae51 /lfunc.c
parentc6f7181e910b6b2ff1346b5486a31be87b1da5af (diff)
downloadlua-4ace93ca6502dd1da38d5c06fa099d229e791ba8.tar.gz
lua-4ace93ca6502dd1da38d5c06fa099d229e791ba8.tar.bz2
lua-4ace93ca6502dd1da38d5c06fa099d229e791ba8.zip
No more to-be-closed functions
To-be-closed variables must contain objects with '__toclose' metamethods (or nil). Functions were removed for several reasons: * Functions interact badly with sandboxes. If a sandbox raises an error to interrupt a script, a to-be-closed function still can hijack control and continue running arbitrary sandboxed code. * Functions interact badly with coroutines. If a coroutine yields and is never resumed again, its to-be-closed functions will never run. To-be-closed objects, on the other hand, will still be closed, provided they have appropriate finalizers. * If you really need a function, it is easy to create a dummy object to run that function in its '__toclose' metamethod. This comit also adds closing of variables in case of panic.
Diffstat (limited to 'lfunc.c')
-rw-r--r--lfunc.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/lfunc.c b/lfunc.c
index bdf3cd25..362b798c 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -100,28 +100,23 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
100 100
101static void callclose (lua_State *L, void *ud) { 101static void callclose (lua_State *L, void *ud) {
102 UNUSED(ud); 102 UNUSED(ud);
103 luaD_callnoyield(L, L->top - 2, 0); 103 luaD_callnoyield(L, L->top - 3, 0);
104} 104}
105 105
106 106
107/* 107/*
108** Prepare closing method plus its argument for object 'obj' with 108** Prepare closing method plus its arguments for object 'obj' with
109** error message 'err'. (This function assumes EXTRA_STACK.) 109** error message 'err'. (This function assumes EXTRA_STACK.)
110*/ 110*/
111static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) { 111static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) {
112 StkId top = L->top; 112 StkId top = L->top;
113 if (ttisfunction(obj)) { /* object to-be-closed is a function? */ 113 const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
114 setobj2s(L, top, obj); /* push function */ 114 if (ttisnil(tm)) /* no metamethod? */
115 setobj2s(L, top + 1, err); /* push error msg. as argument */ 115 return 0; /* nothing to call */
116 } 116 setobj2s(L, top, tm); /* will call metamethod... */
117 else { /* try '__close' metamethod */ 117 setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */
118 const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); 118 setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */
119 if (ttisnil(tm)) /* no metamethod? */ 119 L->top = top + 3; /* add function and arguments */
120 return 0; /* nothing to call */
121 setobj2s(L, top, tm); /* will call metamethod... */
122 setobj2s(L, top + 1, obj); /* with 'self' as the argument */
123 }
124 L->top = top + 2; /* add function and argument */
125 return 1; 120 return 1;
126} 121}
127 122
@@ -156,6 +151,7 @@ static int callclosemth (lua_State *L, TValue *uv, StkId level, int status) {
156 if (newstatus != LUA_OK) /* another error when closing? */ 151 if (newstatus != LUA_OK) /* another error when closing? */
157 status = newstatus; /* this will be the new error */ 152 status = newstatus; /* this will be the new error */
158 } 153 }
154 /* else no metamethod; ignore this case and keep original error */
159 } 155 }
160 return status; 156 return status;
161} 157}