commit 6e285e539274920830eeec5cd2dde5eeca5863e4
parent b8cdea01908f8d436e9d5a73d640645ea52d5f65
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 23 Oct 2019 10:30:35 -0300
More pious implementation of 'string.dump'
In 'str__dump', the call to 'lua_dump' assumes the function is on the
top of the stack, but the manual allows 'luaL_buffinit' to push stuff
on the stack (although the current implementation does not). So, the
call to 'luaL_buffinit' must come after the call to 'lua_dump'.
Diffstat:
M | lstrlib.c | | | 32 | ++++++++++++++++++++++++-------- |
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/lstrlib.c b/lstrlib.c
@@ -206,22 +206,38 @@ static int str_char (lua_State *L) {
}
-static int writer (lua_State *L, const void *b, size_t size, void *B) {
- (void)L;
- luaL_addlstring((luaL_Buffer *) B, (const char *)b, size);
+/*
+** Buffer to store the result of 'string.dump'. It must be initialized
+** after the call to 'lua_dump', to ensure that the function is on the
+** top of the stack when 'lua_dump' is called. ('luaL_buffinit' might
+** push stuff.)
+*/
+struct str_Writer {
+ int init; /* true iff buffer has been initialized */
+ luaL_Buffer B;
+};
+
+
+static int writer (lua_State *L, const void *b, size_t size, void *ud) {
+ struct str_Writer *state = (struct str_Writer *)ud;
+ if (!state->init) {
+ state->init = 1;
+ luaL_buffinit(L, &state->B);
+ }
+ luaL_addlstring(&state->B, (const char *)b, size);
return 0;
}
static int str_dump (lua_State *L) {
- luaL_Buffer b;
+ struct str_Writer state;
int strip = lua_toboolean(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION);
- lua_settop(L, 1);
- luaL_buffinit(L,&b);
- if (lua_dump(L, writer, &b, strip) != 0)
+ lua_settop(L, 1); /* ensure function is on the top of the stack */
+ state.init = 0;
+ if (lua_dump(L, writer, &state, strip) != 0)
return luaL_error(L, "unable to dump given function");
- luaL_pushresult(&b);
+ luaL_pushresult(&state.B);
return 1;
}