Skip to content

Commit 3052804

Browse files
committed
'lua_upvalueid' returns NULL on invalid upvalue index
1 parent 9a89fb1 commit 3052804

File tree

4 files changed

+33
-15
lines changed

4 files changed

+33
-15
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ testes/time.txt
1010
testes/time-debug.txt
1111

1212
testes/libs/all
13+
14+
temp
15+
lua

lapi.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,13 +1383,16 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
13831383

13841384

13851385
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1386+
static const UpVal *const nullup = NULL;
13861387
LClosure *f;
13871388
TValue *fi = index2value(L, fidx);
13881389
api_check(L, ttisLclosure(fi), "Lua function expected");
13891390
f = clLvalue(fi);
1390-
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
13911391
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;
13931396
}
13941397

13951398

@@ -1401,11 +1404,14 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
14011404
}
14021405
case LUA_VCCL: { /* C closure */
14031406
CClosure *f = clCvalue(fi);
1404-
api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
1405-
return &f->upvalue[n - 1];
1406-
}
1407+
if (1 <= n && n <= f->nupvalues)
1408+
return &f->upvalue[n - 1];
1409+
/* else */
1410+
} /* FALLTHROUGH */
1411+
case LUA_VLCF:
1412+
return NULL; /* light C functions have no upvalues */
14071413
default: {
1408-
api_check(L, 0, "closure expected");
1414+
api_check(L, 0, "function expected");
14091415
return NULL;
14101416
}
14111417
}
@@ -1417,6 +1423,7 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
14171423
LClosure *f1;
14181424
UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
14191425
UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1426+
api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index");
14201427
*up1 = *up2;
14211428
luaC_objbarrier(L, f1, *up1);
14221429
}

ldblib.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -281,25 +281,33 @@ static int db_setupvalue (lua_State *L) {
281281
** Check whether a given upvalue from a given closure exists and
282282
** returns its index
283283
*/
284-
static int checkupval (lua_State *L, int argf, int argnup) {
284+
static void *checkupval (lua_State *L, int argf, int argnup, int *pnup) {
285+
void *id;
285286
int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */
286287
luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */
287-
luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
288-
"invalid upvalue index");
289-
return nup;
288+
id = lua_upvalueid(L, argf, nup);
289+
if (pnup) {
290+
luaL_argcheck(L, id != NULL, argnup, "invalid upvalue index");
291+
*pnup = nup;
292+
}
293+
return id;
290294
}
291295

292296

293297
static int db_upvalueid (lua_State *L) {
294-
int n = checkupval(L, 1, 2);
295-
lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
298+
void *id = checkupval(L, 1, 2, NULL);
299+
if (id != NULL)
300+
lua_pushlightuserdata(L, id);
301+
else
302+
luaL_pushfail(L);
296303
return 1;
297304
}
298305

299306

300307
static int db_upvaluejoin (lua_State *L) {
301-
int n1 = checkupval(L, 1, 2);
302-
int n2 = checkupval(L, 3, 4);
308+
int n1, n2;
309+
checkupval(L, 1, 2, &n1);
310+
checkupval(L, 3, 4, &n2);
303311
luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
304312
luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
305313
lua_upvaluejoin(L, 1, n1, 3, n2);

testes/closure.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ end
242242

243243
assert(debug.upvalueid(foo1, 1))
244244
assert(debug.upvalueid(foo1, 2))
245-
assert(not pcall(debug.upvalueid, foo1, 3))
245+
assert(not debug.upvalueid(foo1, 3))
246246
assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2))
247247
assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1))
248248
assert(debug.upvalueid(foo3, 1))

0 commit comments

Comments
 (0)