diff --git a/lapi.c b/lapi.c index f00bd53f..dbd291d7 100644 --- a/lapi.c +++ b/lapi.c @@ -1022,10 +1022,15 @@ LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) { */ +#define MAXRESULTS 250 + + #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)), \ - "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, diff --git a/lcode.c b/lcode.c index c1fce37f..0799306e 100644 --- a/lcode.c +++ b/lcode.c @@ -724,6 +724,8 @@ static void const2exp (TValue *v, expdesc *e) { */ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { 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? */ SETARG_C(*pc, nresults + 1); else { diff --git a/manual/manual.of b/manual/manual.of index 1069f644..c7f6904a 100644 --- a/manual/manual.of +++ b/manual/manual.of @@ -3028,14 +3028,20 @@ When the function returns, all arguments and the function value are popped and the call results are pushed onto the stack. The number of results is adjusted to @id{nresults}, -unless @id{nresults} is @defid{LUA_MULTRET}. -In this case, all results from the function are pushed; +unless @id{nresults} is @defid{LUA_MULTRET}, +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, but it does not ensure any extra space in the stack. The function results are pushed onto the stack in direct order (the first result is pushed first), 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 (with a @id{longjmp}).