aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-10-12 14:51:28 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-10-12 14:51:28 -0300
commit30528049f1d11ea2854a6431e8e8524f83206559 (patch)
treef50e46758cb5673df7e6e456b1e94812a2c5050d
parent9a89fb1c9dfeda4640780111f9e9437f08cfad88 (diff)
downloadlua-30528049f1d11ea2854a6431e8e8524f83206559.tar.gz
lua-30528049f1d11ea2854a6431e8e8524f83206559.tar.bz2
lua-30528049f1d11ea2854a6431e8e8524f83206559.zip
'lua_upvalueid' returns NULL on invalid upvalue index
-rw-r--r--.gitignore3
-rw-r--r--lapi.c19
-rw-r--r--ldblib.c24
-rw-r--r--testes/closure.lua2
4 files changed, 33 insertions, 15 deletions
diff --git a/.gitignore b/.gitignore
index 735661ea..ae2899e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,6 @@ testes/time.txt
10testes/time-debug.txt 10testes/time-debug.txt
11 11
12testes/libs/all 12testes/libs/all
13
14temp
15lua
diff --git a/lapi.c b/lapi.c
index 9048245f..c824da27 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1383,13 +1383,16 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1383 1383
1384 1384
1385static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { 1385static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1386 static const UpVal *const nullup = NULL;
1386 LClosure *f; 1387 LClosure *f;
1387 TValue *fi = index2value(L, fidx); 1388 TValue *fi = index2value(L, fidx);
1388 api_check(L, ttisLclosure(fi), "Lua function expected"); 1389 api_check(L, ttisLclosure(fi), "Lua function expected");
1389 f = clLvalue(fi); 1390 f = clLvalue(fi);
1390 api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
1391 if (pf) *pf = f; 1391 if (pf) *pf = f;
1392 return &f->upvals[n - 1]; /* get its upvalue pointer */ 1392 if (1 <= n && n <= f->p->sizeupvalues)
1393 return &f->upvals[n - 1]; /* get its upvalue pointer */
1394 else
1395 return (UpVal**)&nullup;
1393} 1396}
1394 1397
1395 1398
@@ -1401,11 +1404,14 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1401 } 1404 }
1402 case LUA_VCCL: { /* C closure */ 1405 case LUA_VCCL: { /* C closure */
1403 CClosure *f = clCvalue(fi); 1406 CClosure *f = clCvalue(fi);
1404 api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); 1407 if (1 <= n && n <= f->nupvalues)
1405 return &f->upvalue[n - 1]; 1408 return &f->upvalue[n - 1];
1406 } 1409 /* else */
1410 } /* FALLTHROUGH */
1411 case LUA_VLCF:
1412 return NULL; /* light C functions have no upvalues */
1407 default: { 1413 default: {
1408 api_check(L, 0, "closure expected"); 1414 api_check(L, 0, "function expected");
1409 return NULL; 1415 return NULL;
1410 } 1416 }
1411 } 1417 }
@@ -1417,6 +1423,7 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1417 LClosure *f1; 1423 LClosure *f1;
1418 UpVal **up1 = getupvalref(L, fidx1, n1, &f1); 1424 UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1419 UpVal **up2 = getupvalref(L, fidx2, n2, NULL); 1425 UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1426 api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index");
1420 *up1 = *up2; 1427 *up1 = *up2;
1421 luaC_objbarrier(L, f1, *up1); 1428 luaC_objbarrier(L, f1, *up1);
1422} 1429}
diff --git a/ldblib.c b/ldblib.c
index 26058b50..5a326ade 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -281,25 +281,33 @@ static int db_setupvalue (lua_State *L) {
281** Check whether a given upvalue from a given closure exists and 281** Check whether a given upvalue from a given closure exists and
282** returns its index 282** returns its index
283*/ 283*/
284static int checkupval (lua_State *L, int argf, int argnup) { 284static void *checkupval (lua_State *L, int argf, int argnup, int *pnup) {
285 void *id;
285 int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ 286 int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */
286 luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ 287 luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */
287 luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup, 288 id = lua_upvalueid(L, argf, nup);
288 "invalid upvalue index"); 289 if (pnup) {
289 return nup; 290 luaL_argcheck(L, id != NULL, argnup, "invalid upvalue index");
291 *pnup = nup;
292 }
293 return id;
290} 294}
291 295
292 296
293static int db_upvalueid (lua_State *L) { 297static int db_upvalueid (lua_State *L) {
294 int n = checkupval(L, 1, 2); 298 void *id = checkupval(L, 1, 2, NULL);
295 lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); 299 if (id != NULL)
300 lua_pushlightuserdata(L, id);
301 else
302 luaL_pushfail(L);
296 return 1; 303 return 1;
297} 304}
298 305
299 306
300static int db_upvaluejoin (lua_State *L) { 307static int db_upvaluejoin (lua_State *L) {
301 int n1 = checkupval(L, 1, 2); 308 int n1, n2;
302 int n2 = checkupval(L, 3, 4); 309 checkupval(L, 1, 2, &n1);
310 checkupval(L, 3, 4, &n2);
303 luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); 311 luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
304 luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); 312 luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
305 lua_upvaluejoin(L, 1, n1, 3, n2); 313 lua_upvaluejoin(L, 1, n1, 3, n2);
diff --git a/testes/closure.lua b/testes/closure.lua
index cdeaebaa..c2453677 100644
--- a/testes/closure.lua
+++ b/testes/closure.lua
@@ -242,7 +242,7 @@ end
242 242
243assert(debug.upvalueid(foo1, 1)) 243assert(debug.upvalueid(foo1, 1))
244assert(debug.upvalueid(foo1, 2)) 244assert(debug.upvalueid(foo1, 2))
245assert(not pcall(debug.upvalueid, foo1, 3)) 245assert(not debug.upvalueid(foo1, 3))
246assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2)) 246assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2))
247assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1)) 247assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1))
248assert(debug.upvalueid(foo3, 1)) 248assert(debug.upvalueid(foo3, 1))