diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-26 14:16:17 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-26 14:16:17 -0200 |
commit | 7696c6474fe51ed59fee324e78c1233af74febdd (patch) | |
tree | d5e674cf214a14df38ca39b02177f5cea75b581c /lauxlib.c | |
parent | 7e63d3da0240325db4011f5d2f2e8abfb5d60288 (diff) | |
download | lua-7696c6474fe51ed59fee324e78c1233af74febdd.tar.gz lua-7696c6474fe51ed59fee324e78c1233af74febdd.tar.bz2 lua-7696c6474fe51ed59fee324e78c1233af74febdd.zip |
Auxiliary buffer cannot close box with 'lua_remove'
To remove a to-be-closed variable from the stack in the C API a
function must use 'lua_settop' or 'lua_pop'. Previous implementation of
'luaL_pushresult' was not closing the box. (This commit also added
tests to check that box is being closed "as soon as possible".)
Diffstat (limited to 'lauxlib.c')
-rw-r--r-- | lauxlib.c | 12 |
1 files changed, 7 insertions, 5 deletions
@@ -524,8 +524,8 @@ static size_t newbuffsize (luaL_Buffer *B, size_t sz) { | |||
524 | 524 | ||
525 | /* | 525 | /* |
526 | ** Returns a pointer to a free area with at least 'sz' bytes in buffer | 526 | ** Returns a pointer to a free area with at least 'sz' bytes in buffer |
527 | ** 'B'. 'boxidx' is the position in the stack where the buffer's box is | 527 | ** 'B'. 'boxidx' is the relative position in the stack where the |
528 | ** or should be. | 528 | ** buffer's box is or should be. |
529 | */ | 529 | */ |
530 | static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { | 530 | static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { |
531 | if (B->size - B->n >= sz) /* enough space? */ | 531 | if (B->size - B->n >= sz) /* enough space? */ |
@@ -538,8 +538,10 @@ static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { | |||
538 | if (buffonstack(B)) /* buffer already has a box? */ | 538 | if (buffonstack(B)) /* buffer already has a box? */ |
539 | newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ | 539 | newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ |
540 | else { /* no box yet */ | 540 | else { /* no box yet */ |
541 | lua_pushnil(L); /* reserve slot for final result */ | ||
541 | newbox(L); /* create a new box */ | 542 | newbox(L); /* create a new box */ |
542 | lua_insert(L, boxidx); /* move box to its intended position */ | 543 | /* move box (and slot) to its intended position */ |
544 | lua_rotate(L, boxidx - 1, 2); | ||
543 | lua_toclose(L, boxidx); | 545 | lua_toclose(L, boxidx); |
544 | newbuff = (char *)resizebox(L, boxidx, newsize); | 546 | newbuff = (char *)resizebox(L, boxidx, newsize); |
545 | memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ | 547 | memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ |
@@ -576,8 +578,8 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B) { | |||
576 | lua_State *L = B->L; | 578 | lua_State *L = B->L; |
577 | lua_pushlstring(L, B->b, B->n); | 579 | lua_pushlstring(L, B->b, B->n); |
578 | if (buffonstack(B)) { | 580 | if (buffonstack(B)) { |
579 | resizebox(L, -2, 0); /* delete old buffer */ | 581 | lua_copy(L, -1, -3); /* move string to reserved slot */ |
580 | lua_remove(L, -2); /* remove its header from the stack */ | 582 | lua_pop(L, 2); /* pop string and box (closing the box) */ |
581 | } | 583 | } |
582 | } | 584 | } |
583 | 585 | ||