From 20d42ccaaed9a84783d548d76633a5a38f0091f1 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 20 Sep 2024 15:56:39 -0300 Subject: No errors in 'luaO_pushvfstring' Any call to 'va_start' must have a corresponding call to 'va_end'; so, functions called between them (luaO_pushvfstring in particular) cannot raise errors. --- lobject.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'lobject.c') diff --git a/lobject.c b/lobject.c index 0116e01b..ba10189d 100644 --- a/lobject.c +++ b/lobject.c @@ -480,7 +480,7 @@ void luaO_tostring (lua_State *L, TValue *obj) { #define BUFVFS cast_uint(LUA_IDSIZE + MAXNUMBER2STR + 95) /* -** Buffer used by 'luaO_pushvfstring'. 'err' signals any error while +** Buffer used by 'luaO_pushvfstring'. 'err' signals an error while ** building result (memory error [1] or buffer overflow [2]). */ typedef struct BuffFS { @@ -512,9 +512,14 @@ static void pushbuff (lua_State *L, void *ud) { case 1: luaD_throw(L, LUA_ERRMEM); break; - case 2: - luaG_runerror(L, "buffer overflow"); - break; + case 2: /* length overflow: Add "..." at the end of result */ + if (buff->buffsize - buff->blen < 3) + strcpy(buff->b + buff->blen - 3, "..."); /* 'blen' must be > 3 */ + else { /* there is enough space left for the "..." */ + strcpy(buff->b + buff->blen, "..."); + buff->blen += 3; + } + /* FALLTHROUGH */ default: { /* no errors */ TString *ts = luaS_newlstr(L, buff->b, buff->blen); setsvalue2s(L, L->top.p, ts); @@ -527,8 +532,10 @@ static void pushbuff (lua_State *L, void *ud) { static const char *clearbuff (BuffFS *buff) { lua_State *L = buff->L; const char *res; - pushbuff(L, buff); - res = getstr(tsvalue(s2v(L->top.p - 1))); + if (luaD_rawrunprotected(L, pushbuff, buff) != LUA_OK) /* errors? */ + res = NULL; /* error message is on the top of the stack */ + else + res = getstr(tsvalue(s2v(L->top.p - 1))); if (buff->b != buff->space) /* using dynamic buffer? */ luaM_freearray(L, buff->b, buff->buffsize); /* free it */ return res; @@ -536,12 +543,14 @@ static const char *clearbuff (BuffFS *buff) { static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { + size_t left = buff->buffsize - buff->blen; /* space left in the buffer */ if (buff->err) /* do nothing else after an error */ return; - if (slen > buff->buffsize - buff->blen) { - /* new string doesn't fit into current buffer */ + if (slen > left) { /* new string doesn't fit into current buffer? */ if (slen > ((MAX_SIZE/2) - buff->blen)) { /* overflow? */ - buff->err = 2; + memcpy(buff->b + buff->blen, str, left); /* copy what it can */ + buff->blen = buff->buffsize; + buff->err = 2; /* doesn't add anything else */ return; } else { @@ -552,13 +561,13 @@ static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { : luaM_reallocvector(buff->L, buff->b, buff->buffsize, newsize, char); if (newb == NULL) { /* allocation error? */ - buff->err = 1; + buff->err = 1; /* signal a memory error */ return; } - if (buff->b == buff->space) + if (buff->b == buff->space) /* new buffer (not reallocated)? */ memcpy(newb, buff->b, buff->blen); /* copy previous content */ - buff->b = newb; - buff->buffsize = newsize; + buff->b = newb; /* set new (larger) buffer... */ + buff->buffsize = newsize; /* ...and its new size */ } } memcpy(buff->b + buff->blen, str, slen); /* copy new content */ @@ -651,6 +660,8 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { va_start(argp, fmt); msg = luaO_pushvfstring(L, fmt, argp); va_end(argp); + if (msg == NULL) /* error? */ + luaD_throw(L, LUA_ERRMEM); return msg; } -- cgit v1.2.3-55-g6feb