Explicit limit for number of results in a call

The parameter 'nresults' in 'lua_call' and similar functions has a
limit of 250. It already had an undocumented (and unchecked) limit of
SHRT_MAX, but it is seldom larger than 2.
This commit is contained in:
Roberto Ierusalimschy 2024-07-18 14:44:40 -03:00
parent cd4de92762
commit a546138d15
3 changed files with 17 additions and 4 deletions

9
lapi.c
View File

@ -1022,10 +1022,15 @@ LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
*/ */
#define MAXRESULTS 250
#define checkresults(L,na,nr) \ #define checkresults(L,na,nr) \
api_check(L, (nr) == LUA_MULTRET \ (api_check(L, (nr) == LUA_MULTRET \
|| (L->ci->top.p - L->top.p >= (nr) - (na)), \ || (L->ci->top.p - L->top.p >= (nr) - (na)), \
"results from function overflow current stack size") "results from function overflow current stack size"), \
api_check(L, LUA_MULTRET <= (nr) && (nr) <= MAXRESULTS, \
"invalid number of results"))
LUA_API void lua_callk (lua_State *L, int nargs, int nresults, LUA_API void lua_callk (lua_State *L, int nargs, int nresults,

View File

@ -724,6 +724,8 @@ static void const2exp (TValue *v, expdesc *e) {
*/ */
void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
Instruction *pc = &getinstruction(fs, e); Instruction *pc = &getinstruction(fs, e);
if (nresults + 1 > MAXARG_C)
luaX_syntaxerror(fs->ls, "too many multiple results");
if (e->k == VCALL) /* expression is an open function call? */ if (e->k == VCALL) /* expression is an open function call? */
SETARG_C(*pc, nresults + 1); SETARG_C(*pc, nresults + 1);
else { else {

View File

@ -3028,14 +3028,20 @@ When the function returns,
all arguments and the function value are popped all arguments and the function value are popped
and the call results are pushed onto the stack. and the call results are pushed onto the stack.
The number of results is adjusted to @id{nresults}, The number of results is adjusted to @id{nresults},
unless @id{nresults} is @defid{LUA_MULTRET}. unless @id{nresults} is @defid{LUA_MULTRET},
In this case, all results from the function are pushed; which makes all results from the function to be pushed.
In the first case, an explicit number of results,
the caller must ensure that the stack has space for the
returned values.
In the second case, all results,
Lua takes care that the returned values fit into the stack space, Lua takes care that the returned values fit into the stack space,
but it does not ensure any extra space in the stack. but it does not ensure any extra space in the stack.
The function results are pushed onto the stack in direct order The function results are pushed onto the stack in direct order
(the first result is pushed first), (the first result is pushed first),
so that after the call the last result is on the top of the stack. so that after the call the last result is on the top of the stack.
The maximum value for @id{nresults} is 250.
Any error while calling and running the function is propagated upwards Any error while calling and running the function is propagated upwards
(with a @id{longjmp}). (with a @id{longjmp}).