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.
This commit is contained in:
2
lapi.c
2
lapi.c
@@ -587,6 +587,8 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
|
|||||||
ret = luaO_pushvfstring(L, fmt, argp);
|
ret = luaO_pushvfstring(L, fmt, argp);
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
|
if (ret == NULL) /* error? */
|
||||||
|
luaD_throw(L, LUA_ERRMEM);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
|
|||||||
/*
|
/*
|
||||||
** Again, the use of 'lua_pushvfstring' ensures this function does
|
** Again, the use of 'lua_pushvfstring' ensures this function does
|
||||||
** not need reserved stack space when called. (At worst, it generates
|
** not need reserved stack space when called. (At worst, it generates
|
||||||
** an error with "stack overflow" instead of the given message.)
|
** a memory error instead of the given message.)
|
||||||
*/
|
*/
|
||||||
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
|
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
|
||||||
va_list argp;
|
va_list argp;
|
||||||
|
|||||||
3
ldebug.c
3
ldebug.c
@@ -847,7 +847,8 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
|||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (isLua(ci)) { /* if Lua function, add source:line information */
|
if (msg != NULL && isLua(ci)) { /* Lua function? (and no error) */
|
||||||
|
/* add source:line information */
|
||||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
||||||
setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
|
setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
|
||||||
L->top.p--;
|
L->top.p--;
|
||||||
|
|||||||
35
lobject.c
35
lobject.c
@@ -480,7 +480,7 @@ void luaO_tostring (lua_State *L, TValue *obj) {
|
|||||||
#define BUFVFS cast_uint(LUA_IDSIZE + MAXNUMBER2STR + 95)
|
#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]).
|
** building result (memory error [1] or buffer overflow [2]).
|
||||||
*/
|
*/
|
||||||
typedef struct BuffFS {
|
typedef struct BuffFS {
|
||||||
@@ -512,9 +512,14 @@ static void pushbuff (lua_State *L, void *ud) {
|
|||||||
case 1:
|
case 1:
|
||||||
luaD_throw(L, LUA_ERRMEM);
|
luaD_throw(L, LUA_ERRMEM);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2: /* length overflow: Add "..." at the end of result */
|
||||||
luaG_runerror(L, "buffer overflow");
|
if (buff->buffsize - buff->blen < 3)
|
||||||
break;
|
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 */
|
default: { /* no errors */
|
||||||
TString *ts = luaS_newlstr(L, buff->b, buff->blen);
|
TString *ts = luaS_newlstr(L, buff->b, buff->blen);
|
||||||
setsvalue2s(L, L->top.p, ts);
|
setsvalue2s(L, L->top.p, ts);
|
||||||
@@ -527,7 +532,9 @@ static void pushbuff (lua_State *L, void *ud) {
|
|||||||
static const char *clearbuff (BuffFS *buff) {
|
static const char *clearbuff (BuffFS *buff) {
|
||||||
lua_State *L = buff->L;
|
lua_State *L = buff->L;
|
||||||
const char *res;
|
const char *res;
|
||||||
pushbuff(L, buff);
|
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)));
|
res = getstr(tsvalue(s2v(L->top.p - 1)));
|
||||||
if (buff->b != buff->space) /* using dynamic buffer? */
|
if (buff->b != buff->space) /* using dynamic buffer? */
|
||||||
luaM_freearray(L, buff->b, buff->buffsize); /* free it */
|
luaM_freearray(L, buff->b, buff->buffsize); /* free it */
|
||||||
@@ -536,12 +543,14 @@ static const char *clearbuff (BuffFS *buff) {
|
|||||||
|
|
||||||
|
|
||||||
static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
|
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 */
|
if (buff->err) /* do nothing else after an error */
|
||||||
return;
|
return;
|
||||||
if (slen > buff->buffsize - buff->blen) {
|
if (slen > left) { /* new string doesn't fit into current buffer? */
|
||||||
/* new string doesn't fit into current buffer */
|
|
||||||
if (slen > ((MAX_SIZE/2) - buff->blen)) { /* overflow? */
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
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,
|
: luaM_reallocvector(buff->L, buff->b, buff->buffsize, newsize,
|
||||||
char);
|
char);
|
||||||
if (newb == NULL) { /* allocation error? */
|
if (newb == NULL) { /* allocation error? */
|
||||||
buff->err = 1;
|
buff->err = 1; /* signal a memory error */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (buff->b == buff->space)
|
if (buff->b == buff->space) /* new buffer (not reallocated)? */
|
||||||
memcpy(newb, buff->b, buff->blen); /* copy previous content */
|
memcpy(newb, buff->b, buff->blen); /* copy previous content */
|
||||||
buff->b = newb;
|
buff->b = newb; /* set new (larger) buffer... */
|
||||||
buff->buffsize = newsize;
|
buff->buffsize = newsize; /* ...and its new size */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(buff->b + buff->blen, str, slen); /* copy new content */
|
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);
|
va_start(argp, fmt);
|
||||||
msg = luaO_pushvfstring(L, fmt, argp);
|
msg = luaO_pushvfstring(L, fmt, argp);
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
if (msg == NULL) /* error? */
|
||||||
|
luaD_throw(L, LUA_ERRMEM);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3974,7 +3974,7 @@ Lua will call @id{falloc} before raising the error.
|
|||||||
|
|
||||||
|
|
||||||
@APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);|
|
@APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);|
|
||||||
@apii{0,1,v}
|
@apii{0,1,m}
|
||||||
|
|
||||||
Pushes onto the stack a formatted string
|
Pushes onto the stack a formatted string
|
||||||
and returns a pointer to this string @see{constchar}.
|
and returns a pointer to this string @see{constchar}.
|
||||||
@@ -3997,9 +3997,6 @@ The conversion specifiers can only be
|
|||||||
@Char{%c} (inserts an @T{int} as a one-byte character), and
|
@Char{%c} (inserts an @T{int} as a one-byte character), and
|
||||||
@Char{%U} (inserts an @T{unsigned long} as a @x{UTF-8} byte sequence).
|
@Char{%U} (inserts an @T{unsigned long} as a @x{UTF-8} byte sequence).
|
||||||
|
|
||||||
This function may raise errors due to memory overflow
|
|
||||||
or an invalid conversion specifier.
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@APIEntry{void lua_pushglobaltable (lua_State *L);|
|
@APIEntry{void lua_pushglobaltable (lua_State *L);|
|
||||||
@@ -4104,10 +4101,14 @@ onto the stack.
|
|||||||
const char *lua_pushvfstring (lua_State *L,
|
const char *lua_pushvfstring (lua_State *L,
|
||||||
const char *fmt,
|
const char *fmt,
|
||||||
va_list argp);|
|
va_list argp);|
|
||||||
@apii{0,1,v}
|
@apii{0,1,-}
|
||||||
|
|
||||||
Equivalent to @Lid{lua_pushfstring}, except that it receives a @id{va_list}
|
Equivalent to @Lid{lua_pushfstring},
|
||||||
instead of a variable number of arguments.
|
except that it receives a @id{va_list}
|
||||||
|
instead of a variable number of arguments,
|
||||||
|
and it does not raise errors.
|
||||||
|
Instead, in case of errors it pushes the error message
|
||||||
|
and returns @id{NULL}.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5636,6 +5637,7 @@ It is defined as the following macro:
|
|||||||
}
|
}
|
||||||
It @N{returns 0} (@Lid{LUA_OK}) if there are no errors,
|
It @N{returns 0} (@Lid{LUA_OK}) if there are no errors,
|
||||||
or 1 in case of errors.
|
or 1 in case of errors.
|
||||||
|
(Except for out-of-memory errors, which are raised.)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5800,7 +5802,7 @@ The first line in the file is ignored if it starts with a @T{#}.
|
|||||||
|
|
||||||
The string @id{mode} works as in the function @Lid{lua_load}.
|
The string @id{mode} works as in the function @Lid{lua_load}.
|
||||||
|
|
||||||
This function returns the same results as @Lid{lua_load}
|
This function returns the same results as @Lid{lua_load},
|
||||||
or @Lid{LUA_ERRFILE} for file-related errors.
|
or @Lid{LUA_ERRFILE} for file-related errors.
|
||||||
|
|
||||||
As @Lid{lua_load}, this function only loads the chunk;
|
As @Lid{lua_load}, this function only loads the chunk;
|
||||||
@@ -9260,7 +9262,7 @@ the script is compiled as a variadic function.
|
|||||||
In interactive mode,
|
In interactive mode,
|
||||||
Lua repeatedly prompts and waits for a line.
|
Lua repeatedly prompts and waits for a line.
|
||||||
After reading a line,
|
After reading a line,
|
||||||
Lua first try to interpret the line as an expression.
|
Lua first tries to interpret the line as an expression.
|
||||||
If it succeeds, it prints its value.
|
If it succeeds, it prints its value.
|
||||||
Otherwise, it interprets the line as a chunk.
|
Otherwise, it interprets the line as a chunk.
|
||||||
If you write an incomplete chunk,
|
If you write an incomplete chunk,
|
||||||
@@ -9424,6 +9426,11 @@ instead, there is a new option @Lid{LUA_GCPARAM} to that end.
|
|||||||
Moreover, there were some changes in the parameters themselves.
|
Moreover, there were some changes in the parameters themselves.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@item{
|
||||||
|
The function @Lid{lua_pushvfstring} now reports errors,
|
||||||
|
instead of raising them.
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user