diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-09-20 15:56:39 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-09-20 15:56:39 -0300 |
commit | 20d42ccaaed9a84783d548d76633a5a38f0091f1 (patch) | |
tree | 4d0aae4dfac41956ac35a69ece27d042acd8f4f8 /lobject.c | |
parent | 70d6975018c1f2b8ce34058a4d54a28a3fafca66 (diff) | |
download | lua-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.c | 37 |
1 files changed, 24 insertions, 13 deletions
@@ -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 | */ |
486 | typedef struct BuffFS { | 486 | typedef 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) { | |||
527 | static const char *clearbuff (BuffFS *buff) { | 532 | static 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 | ||
538 | static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { | 545 | static 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 | ||