aboutsummaryrefslogtreecommitdiff
path: root/lauxlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lauxlib.c')
-rw-r--r--lauxlib.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/lauxlib.c b/lauxlib.c
index 2610f90e..94835ef9 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -516,6 +516,15 @@ static void newbox (lua_State *L) {
516 516
517 517
518/* 518/*
519** Whenever buffer is accessed, slot 'idx' must either be a box (which
520** cannot be NULL) or it is a placeholder for the buffer.
521*/
522#define checkbufferlevel(B,idx) \
523 lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \
524 : lua_touserdata(B->L, idx) == (void*)B)
525
526
527/*
519** Compute new size for buffer 'B', enough to accommodate extra 'sz' 528** Compute new size for buffer 'B', enough to accommodate extra 'sz'
520** bytes. 529** bytes.
521*/ 530*/
@@ -531,10 +540,11 @@ static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
531 540
532/* 541/*
533** Returns a pointer to a free area with at least 'sz' bytes in buffer 542** Returns a pointer to a free area with at least 'sz' bytes in buffer
534** 'B'. 'boxidx' is the relative position in the stack where the 543** 'B'. 'boxidx' is the relative position in the stack where is the
535** buffer's box is or should be. 544** buffer's box or its placeholder.
536*/ 545*/
537static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { 546static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) {
547 checkbufferlevel(B, boxidx);
538 if (B->size - B->n >= sz) /* enough space? */ 548 if (B->size - B->n >= sz) /* enough space? */
539 return B->b + B->n; 549 return B->b + B->n;
540 else { 550 else {
@@ -545,6 +555,7 @@ static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) {
545 if (buffonstack(B)) /* buffer already has a box? */ 555 if (buffonstack(B)) /* buffer already has a box? */
546 newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ 556 newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */
547 else { /* no box yet */ 557 else { /* no box yet */
558 lua_remove(L, boxidx); /* remove placeholder */
548 newbox(L); /* create a new box */ 559 newbox(L); /* create a new box */
549 lua_insert(L, boxidx); /* move box to its intended position */ 560 lua_insert(L, boxidx); /* move box to its intended position */
550 lua_toclose(L, boxidx); 561 lua_toclose(L, boxidx);
@@ -581,11 +592,11 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
581 592
582LUALIB_API void luaL_pushresult (luaL_Buffer *B) { 593LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
583 lua_State *L = B->L; 594 lua_State *L = B->L;
595 checkbufferlevel(B, -1);
584 lua_pushlstring(L, B->b, B->n); 596 lua_pushlstring(L, B->b, B->n);
585 if (buffonstack(B)) { 597 if (buffonstack(B))
586 lua_closeslot(L, -2); /* close the box */ 598 lua_closeslot(L, -2); /* close the box */
587 lua_remove(L, -2); /* remove box from the stack */ 599 lua_remove(L, -2); /* remove box or placeholder from the stack */
588 }
589} 600}
590 601
591 602
@@ -620,6 +631,7 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
620 B->b = B->init.b; 631 B->b = B->init.b;
621 B->n = 0; 632 B->n = 0;
622 B->size = LUAL_BUFFERSIZE; 633 B->size = LUAL_BUFFERSIZE;
634 lua_pushlightuserdata(L, (void*)B); /* push placeholder */
623} 635}
624 636
625 637