aboutsummaryrefslogtreecommitdiff
path: root/lobject.c
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 /lobject.c
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.
Diffstat (limited to 'lobject.c')
-rw-r--r--lobject.c37
1 files changed, 24 insertions, 13 deletions
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