From a546138d158d79d44b2c5b42630be00d306f4e7c Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 18 Jul 2024 14:44:40 -0300 Subject: [PATCH] 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. --- lapi.c | 9 +++++++-- lcode.c | 2 ++ manual/manual.of | 10 ++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) 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}).