Skip to content

Commit 20d42cc

Browse files
committed
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.
1 parent 70d6975 commit 20d42cc

File tree

5 files changed

+45
-24
lines changed

5 files changed

+45
-24
lines changed

lapi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,8 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
587587
ret = luaO_pushvfstring(L, fmt, argp);
588588
va_end(argp);
589589
luaC_checkGC(L);
590+
if (ret == NULL) /* error? */
591+
luaD_throw(L, LUA_ERRMEM);
590592
lua_unlock(L);
591593
return ret;
592594
}

lauxlib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
225225
/*
226226
** Again, the use of 'lua_pushvfstring' ensures this function does
227227
** not need reserved stack space when called. (At worst, it generates
228-
** an error with "stack overflow" instead of the given message.)
228+
** a memory error instead of the given message.)
229229
*/
230230
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
231231
va_list argp;

ldebug.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,8 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
847847
va_start(argp, fmt);
848848
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
849849
va_end(argp);
850-
if (isLua(ci)) { /* if Lua function, add source:line information */
850+
if (msg != NULL && isLua(ci)) { /* Lua function? (and no error) */
851+
/* add source:line information */
851852
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
852853
setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
853854
L->top.p--;

lobject.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ void luaO_tostring (lua_State *L, TValue *obj) {
480480
#define BUFVFS cast_uint(LUA_IDSIZE + MAXNUMBER2STR + 95)
481481

482482
/*
483-
** Buffer used by 'luaO_pushvfstring'. 'err' signals any error while
483+
** Buffer used by 'luaO_pushvfstring'. 'err' signals an error while
484484
** building result (memory error [1] or buffer overflow [2]).
485485
*/
486486
typedef struct BuffFS {
@@ -512,9 +512,14 @@ static void pushbuff (lua_State *L, void *ud) {
512512
case 1:
513513
luaD_throw(L, LUA_ERRMEM);
514514
break;
515-
case 2:
516-
luaG_runerror(L, "buffer overflow");
517-
break;
515+
case 2: /* length overflow: Add "..." at the end of result */
516+
if (buff->buffsize - buff->blen < 3)
517+
strcpy(buff->b + buff->blen - 3, "..."); /* 'blen' must be > 3 */
518+
else { /* there is enough space left for the "..." */
519+
strcpy(buff->b + buff->blen, "...");
520+
buff->blen += 3;
521+
}
522+
/* FALLTHROUGH */
518523
default: { /* no errors */
519524
TString *ts = luaS_newlstr(L, buff->b, buff->blen);
520525
setsvalue2s(L, L->top.p, ts);
@@ -527,21 +532,25 @@ static void pushbuff (lua_State *L, void *ud) {
527532
static const char *clearbuff (BuffFS *buff) {
528533
lua_State *L = buff->L;
529534
const char *res;
530-
pushbuff(L, buff);
531-
res = getstr(tsvalue(s2v(L->top.p - 1)));
535+
if (luaD_rawrunprotected(L, pushbuff, buff) != LUA_OK) /* errors? */
536+
res = NULL; /* error message is on the top of the stack */
537+
else
538+
res = getstr(tsvalue(s2v(L->top.p - 1)));
532539
if (buff->b != buff->space) /* using dynamic buffer? */
533540
luaM_freearray(L, buff->b, buff->buffsize); /* free it */
534541
return res;
535542
}
536543

537544

538545
static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
546+
size_t left = buff->buffsize - buff->blen; /* space left in the buffer */
539547
if (buff->err) /* do nothing else after an error */
540548
return;
541-
if (slen > buff->buffsize - buff->blen) {
542-
/* new string doesn't fit into current buffer */
549+
if (slen > left) { /* new string doesn't fit into current buffer? */
543550
if (slen > ((MAX_SIZE/2) - buff->blen)) { /* overflow? */
544-
buff->err = 2;
551+
memcpy(buff->b + buff->blen, str, left); /* copy what it can */
552+
buff->blen = buff->buffsize;
553+
buff->err = 2; /* doesn't add anything else */
545554
return;
546555
}
547556
else {
@@ -552,13 +561,13 @@ static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
552561
: luaM_reallocvector(buff->L, buff->b, buff->buffsize, newsize,
553562
char);
554563
if (newb == NULL) { /* allocation error? */
555-
buff->err = 1;
564+
buff->err = 1; /* signal a memory error */
556565
return;
557566
}
558-
if (buff->b == buff->space)
567+
if (buff->b == buff->space) /* new buffer (not reallocated)? */
559568
memcpy(newb, buff->b, buff->blen); /* copy previous content */
560-
buff->b = newb;
561-
buff->buffsize = newsize;
569+
buff->b = newb; /* set new (larger) buffer... */
570+
buff->buffsize = newsize; /* ...and its new size */
562571
}
563572
}
564573
memcpy(buff->b + buff->blen, str, slen); /* copy new content */
@@ -651,6 +660,8 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
651660
va_start(argp, fmt);
652661
msg = luaO_pushvfstring(L, fmt, argp);
653662
va_end(argp);
663+
if (msg == NULL) /* error? */
664+
luaD_throw(L, LUA_ERRMEM);
654665
return msg;
655666
}
656667

manual/manual.of

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3974,7 +3974,7 @@ Lua will call @id{falloc} before raising the error.
39743974

39753975

39763976
@APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);|
3977-
@apii{0,1,v}
3977+
@apii{0,1,m}
39783978

39793979
Pushes onto the stack a formatted string
39803980
and returns a pointer to this string @see{constchar}.
@@ -3997,9 +3997,6 @@ The conversion specifiers can only be
39973997
@Char{%c} (inserts an @T{int} as a one-byte character), and
39983998
@Char{%U} (inserts an @T{unsigned long} as a @x{UTF-8} byte sequence).
39993999

4000-
This function may raise errors due to memory overflow
4001-
or an invalid conversion specifier.
4002-
40034000
}
40044001

40054002
@APIEntry{void lua_pushglobaltable (lua_State *L);|
@@ -4104,10 +4101,14 @@ onto the stack.
41044101
const char *lua_pushvfstring (lua_State *L,
41054102
const char *fmt,
41064103
va_list argp);|
4107-
@apii{0,1,v}
4104+
@apii{0,1,-}
41084105

4109-
Equivalent to @Lid{lua_pushfstring}, except that it receives a @id{va_list}
4110-
instead of a variable number of arguments.
4106+
Equivalent to @Lid{lua_pushfstring},
4107+
except that it receives a @id{va_list}
4108+
instead of a variable number of arguments,
4109+
and it does not raise errors.
4110+
Instead, in case of errors it pushes the error message
4111+
and returns @id{NULL}.
41114112

41124113
}
41134114

@@ -5636,6 +5637,7 @@ It is defined as the following macro:
56365637
}
56375638
It @N{returns 0} (@Lid{LUA_OK}) if there are no errors,
56385639
or 1 in case of errors.
5640+
(Except for out-of-memory errors, which are raised.)
56395641

56405642
}
56415643

@@ -5800,7 +5802,7 @@ The first line in the file is ignored if it starts with a @T{#}.
58005802

58015803
The string @id{mode} works as in the function @Lid{lua_load}.
58025804

5803-
This function returns the same results as @Lid{lua_load}
5805+
This function returns the same results as @Lid{lua_load},
58045806
or @Lid{LUA_ERRFILE} for file-related errors.
58055807

58065808
As @Lid{lua_load}, this function only loads the chunk;
@@ -9260,7 +9262,7 @@ the script is compiled as a variadic function.
92609262
In interactive mode,
92619263
Lua repeatedly prompts and waits for a line.
92629264
After reading a line,
9263-
Lua first try to interpret the line as an expression.
9265+
Lua first tries to interpret the line as an expression.
92649266
If it succeeds, it prints its value.
92659267
Otherwise, it interprets the line as a chunk.
92669268
If you write an incomplete chunk,
@@ -9424,6 +9426,11 @@ instead, there is a new option @Lid{LUA_GCPARAM} to that end.
94249426
Moreover, there were some changes in the parameters themselves.
94259427
}
94269428

9429+
@item{
9430+
The function @Lid{lua_pushvfstring} now reports errors,
9431+
instead of raising them.
9432+
}
9433+
94279434
}
94289435

94299436
}

0 commit comments

Comments
 (0)