aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-09-20 15:56:39 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-09-20 15:56:39 -0300
commit20d42ccaaed9a84783d548d76633a5a38f0091f1 (patch)
tree4d0aae4dfac41956ac35a69ece27d042acd8f4f8
parent70d6975018c1f2b8ce34058a4d54a28a3fafca66 (diff)
downloadlua-20d42ccaaed9a84783d548d76633a5a38f0091f1.tar.gz
lua-20d42ccaaed9a84783d548d76633a5a38f0091f1.tar.bz2
lua-20d42ccaaed9a84783d548d76633a5a38f0091f1.zip
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.
-rw-r--r--lapi.c2
-rw-r--r--lauxlib.c2
-rw-r--r--ldebug.c3
-rw-r--r--lobject.c37
-rw-r--r--manual/manual.of25
5 files changed, 45 insertions, 24 deletions
diff --git a/lapi.c b/lapi.c
index 7980ead0..fffd7d26 100644
--- a/lapi.c
+++ b/lapi.c
@@ -587,6 +587,8 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
587 ret = luaO_pushvfstring(L, fmt, argp); 587 ret = luaO_pushvfstring(L, fmt, argp);
588 va_end(argp); 588 va_end(argp);
589 luaC_checkGC(L); 589 luaC_checkGC(L);
590 if (ret == NULL) /* error? */
591 luaD_throw(L, LUA_ERRMEM);
590 lua_unlock(L); 592 lua_unlock(L);
591 return ret; 593 return ret;
592} 594}
diff --git a/lauxlib.c b/lauxlib.c
index defd4d57..a36655f2 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -225,7 +225,7 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
225/* 225/*
226** Again, the use of 'lua_pushvfstring' ensures this function does 226** Again, the use of 'lua_pushvfstring' ensures this function does
227** not need reserved stack space when called. (At worst, it generates 227** 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.)
229*/ 229*/
230LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { 230LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
231 va_list argp; 231 va_list argp;
diff --git a/ldebug.c b/ldebug.c
index 9e341f11..d1b47c56 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -847,7 +847,8 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
847 va_start(argp, fmt); 847 va_start(argp, fmt);
848 msg = luaO_pushvfstring(L, fmt, argp); /* format message */ 848 msg = luaO_pushvfstring(L, fmt, argp); /* format message */
849 va_end(argp); 849 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 */
851 luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci)); 852 luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
852 setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */ 853 setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
853 L->top.p--; 854 L->top.p--;
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) {
480#define BUFVFS cast_uint(LUA_IDSIZE + MAXNUMBER2STR + 95) 480#define BUFVFS cast_uint(LUA_IDSIZE + MAXNUMBER2STR + 95)
481 481
482/* 482/*
483** Buffer used by 'luaO_pushvfstring'. 'err' signals any error while 483** Buffer used by 'luaO_pushvfstring'. 'err' signals an error while
484** building result (memory error [1] or buffer overflow [2]). 484** building result (memory error [1] or buffer overflow [2]).
485*/ 485*/
486typedef struct BuffFS { 486typedef struct BuffFS {
@@ -512,9 +512,14 @@ static void pushbuff (lua_State *L, void *ud) {
512 case 1: 512 case 1:
513 luaD_throw(L, LUA_ERRMEM); 513 luaD_throw(L, LUA_ERRMEM);
514 break; 514 break;
515 case 2: 515 case 2: /* length overflow: Add "..." at the end of result */
516 luaG_runerror(L, "buffer overflow"); 516 if (buff->buffsize - buff->blen < 3)
517 break; 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 */
518 default: { /* no errors */ 523 default: { /* no errors */
519 TString *ts = luaS_newlstr(L, buff->b, buff->blen); 524 TString *ts = luaS_newlstr(L, buff->b, buff->blen);
520 setsvalue2s(L, L->top.p, ts); 525 setsvalue2s(L, L->top.p, ts);
@@ -527,8 +532,10 @@ static void pushbuff (lua_State *L, void *ud) {
527static const char *clearbuff (BuffFS *buff) { 532static const char *clearbuff (BuffFS *buff) {
528 lua_State *L = buff->L; 533 lua_State *L = buff->L;
529 const char *res; 534 const char *res;
530 pushbuff(L, buff); 535 if (luaD_rawrunprotected(L, pushbuff, buff) != LUA_OK) /* errors? */
531 res = getstr(tsvalue(s2v(L->top.p - 1))); 536 res = NULL; /* error message is on the top of the stack */
537 else
538 res = getstr(tsvalue(s2v(L->top.p - 1)));
532 if (buff->b != buff->space) /* using dynamic buffer? */ 539 if (buff->b != buff->space) /* using dynamic buffer? */
533 luaM_freearray(L, buff->b, buff->buffsize); /* free it */ 540 luaM_freearray(L, buff->b, buff->buffsize); /* free it */
534 return res; 541 return res;
@@ -536,12 +543,14 @@ static const char *clearbuff (BuffFS *buff) {
536 543
537 544
538static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { 545static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
546 size_t left = buff->buffsize - buff->blen; /* space left in the buffer */
539 if (buff->err) /* do nothing else after an error */ 547 if (buff->err) /* do nothing else after an error */
540 return; 548 return;
541 if (slen > buff->buffsize - buff->blen) { 549 if (slen > left) { /* new string doesn't fit into current buffer? */
542 /* new string doesn't fit into current buffer */
543 if (slen > ((MAX_SIZE/2) - buff->blen)) { /* overflow? */ 550 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 */
545 return; 554 return;
546 } 555 }
547 else { 556 else {
@@ -552,13 +561,13 @@ static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
552 : luaM_reallocvector(buff->L, buff->b, buff->buffsize, newsize, 561 : luaM_reallocvector(buff->L, buff->b, buff->buffsize, newsize,
553 char); 562 char);
554 if (newb == NULL) { /* allocation error? */ 563 if (newb == NULL) { /* allocation error? */
555 buff->err = 1; 564 buff->err = 1; /* signal a memory error */
556 return; 565 return;
557 } 566 }
558 if (buff->b == buff->space) 567 if (buff->b == buff->space) /* new buffer (not reallocated)? */
559 memcpy(newb, buff->b, buff->blen); /* copy previous content */ 568 memcpy(newb, buff->b, buff->blen); /* copy previous content */
560 buff->b = newb; 569 buff->b = newb; /* set new (larger) buffer... */
561 buff->buffsize = newsize; 570 buff->buffsize = newsize; /* ...and its new size */
562 } 571 }
563 } 572 }
564 memcpy(buff->b + buff->blen, str, slen); /* copy new content */ 573 memcpy(buff->b + buff->blen, str, slen); /* copy new content */
@@ -651,6 +660,8 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
651 va_start(argp, fmt); 660 va_start(argp, fmt);
652 msg = luaO_pushvfstring(L, fmt, argp); 661 msg = luaO_pushvfstring(L, fmt, argp);
653 va_end(argp); 662 va_end(argp);
663 if (msg == NULL) /* error? */
664 luaD_throw(L, LUA_ERRMEM);
654 return msg; 665 return msg;
655} 666}
656 667
diff --git a/manual/manual.of b/manual/manual.of
index f0a2ed94..1ac537f7 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -3974,7 +3974,7 @@ Lua will call @id{falloc} before raising the error.
3974 3974
3975 3975
3976@APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);| 3976@APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);|
3977@apii{0,1,v} 3977@apii{0,1,m}
3978 3978
3979Pushes onto the stack a formatted string 3979Pushes onto the stack a formatted string
3980and returns a pointer to this string @see{constchar}. 3980and returns a pointer to this string @see{constchar}.
@@ -3997,9 +3997,6 @@ The conversion specifiers can only be
3997@Char{%c} (inserts an @T{int} as a one-byte character), and 3997@Char{%c} (inserts an @T{int} as a one-byte character), and
3998@Char{%U} (inserts an @T{unsigned long} as a @x{UTF-8} byte sequence). 3998@Char{%U} (inserts an @T{unsigned long} as a @x{UTF-8} byte sequence).
3999 3999
4000This function may raise errors due to memory overflow
4001or an invalid conversion specifier.
4002
4003} 4000}
4004 4001
4005@APIEntry{void lua_pushglobaltable (lua_State *L);| 4002@APIEntry{void lua_pushglobaltable (lua_State *L);|
@@ -4104,10 +4101,14 @@ onto the stack.
4104const char *lua_pushvfstring (lua_State *L, 4101const char *lua_pushvfstring (lua_State *L,
4105 const char *fmt, 4102 const char *fmt,
4106 va_list argp);| 4103 va_list argp);|
4107@apii{0,1,v} 4104@apii{0,1,-}
4108 4105
4109Equivalent to @Lid{lua_pushfstring}, except that it receives a @id{va_list} 4106Equivalent to @Lid{lua_pushfstring},
4110instead of a variable number of arguments. 4107except that it receives a @id{va_list}
4108instead of a variable number of arguments,
4109and it does not raise errors.
4110Instead, in case of errors it pushes the error message
4111and returns @id{NULL}.
4111 4112
4112} 4113}
4113 4114
@@ -5636,6 +5637,7 @@ It is defined as the following macro:
5636} 5637}
5637It @N{returns 0} (@Lid{LUA_OK}) if there are no errors, 5638It @N{returns 0} (@Lid{LUA_OK}) if there are no errors,
5638or 1 in case of errors. 5639or 1 in case of errors.
5640(Except for out-of-memory errors, which are raised.)
5639 5641
5640} 5642}
5641 5643
@@ -5800,7 +5802,7 @@ The first line in the file is ignored if it starts with a @T{#}.
5800 5802
5801The string @id{mode} works as in the function @Lid{lua_load}. 5803The string @id{mode} works as in the function @Lid{lua_load}.
5802 5804
5803This function returns the same results as @Lid{lua_load} 5805This function returns the same results as @Lid{lua_load},
5804or @Lid{LUA_ERRFILE} for file-related errors. 5806or @Lid{LUA_ERRFILE} for file-related errors.
5805 5807
5806As @Lid{lua_load}, this function only loads the chunk; 5808As @Lid{lua_load}, this function only loads the chunk;
@@ -9260,7 +9262,7 @@ the script is compiled as a variadic function.
9260In interactive mode, 9262In interactive mode,
9261Lua repeatedly prompts and waits for a line. 9263Lua repeatedly prompts and waits for a line.
9262After reading a line, 9264After reading a line,
9263Lua first try to interpret the line as an expression. 9265Lua first tries to interpret the line as an expression.
9264If it succeeds, it prints its value. 9266If it succeeds, it prints its value.
9265Otherwise, it interprets the line as a chunk. 9267Otherwise, it interprets the line as a chunk.
9266If you write an incomplete chunk, 9268If you write an incomplete chunk,
@@ -9424,6 +9426,11 @@ instead, there is a new option @Lid{LUA_GCPARAM} to that end.
9424Moreover, there were some changes in the parameters themselves. 9426Moreover, there were some changes in the parameters themselves.
9425} 9427}
9426 9428
9429@item{
9430The function @Lid{lua_pushvfstring} now reports errors,
9431instead of raising them.
9432}
9433
9427} 9434}
9428 9435
9429} 9436}