[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [BUG] Re: A luaL_Buffer question
- From: Sean Conner <sean@...>
- Date: Fri, 3 Nov 2017 02:55:19 -0400
It was thus said that the Great Dirk Laurie once stated:
> 2017-11-03 7:50 GMT+02:00 Dirk Laurie <dirk.laurie@gmail.com>:
> > 2017-11-02 17:42 GMT+02:00 Viacheslav Usov <via.usov@gmail.com>:
> >>
> >> Here is my test of your code:
> >>
> >> lua_State *L = luaL_newstate();
> >>
> >> luaL_openlibs(L);
> >> luaopen_buffer(L);
> >> lua_setglobal(L, "b");
> >> luaL_dostring(L,
> >> "local x = b.new()"
> >> "b.append(x, string.rep('x', 100000))"
> >> "b.append(x, string.rep('x', 100000))"
> >> "print(b.flush(x))"
> >> );
> >>
> >> When I run the above, it crashes within the second call to luaL_addvalue(),
> >> due to a heap corruption. If I remove the second b.append... line, then it
> >> crashes within luaL_pushresult(), for the same reason.
> >
> > I will be more impressed if you can crash my code by using it as a
> > module of C routines to be called from Lua.
>
> OK, I can spare you the effort. If I run your code line by line in the
> interpreter (without 'local'), it is fine. If I put it inside do ...
> end,
> it crashes spectacularly. You are right.
>
> The reason it is in the API must be that it is needed to code the
> standard library, which prides itself on being totally written in the
> API.
I got the following when I compiled your code and ran it:
[spc]lucy:/tmp/foo>lua-53
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
> b = require "buffer"
> x = b.new()
> b.append(x, string.rep('x', 100000))
> b.append(x, string.rep('x', 100000))
*** glibc detected *** double free or corruption (!prev): 0x098a1ed0 ***
Aborted (core dumped)
[spc]lucy:/tmp/foo>
When I modified the code thusly:
static int buffer_new (lua_State *L) {
luaL_Buffer **buf = lua_newuserdata(L,sizeof(luaL_Buffer *));
*buf = malloc(sizeof(luaL_Buffer));
luaL_buffinit(L,*buf);
luaL_setmetatable(L,"Buffer");
return 1;
}
static int buffer_flush (lua_State *L) {
luaL_Buffer **buf = luaL_checkudata(L,1,"Buffer");
luaL_pushresult(*buf);
free(*buf);
*buf = NULL;
return 1;
}
static int buffer_append (lua_State *L) {
luaL_addvalue(*(luaL_Buffer **)luaL_checkudata(L,1,"Buffer"));
return 0;
}
I got (after the first call to b.append()):
xxxxx
*** glibc detected *** malloc(): memory corruption: 0x08e98da8 ***
Aborted (core dumped)
Meanwhile, this works:
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
static int bar(lua_State *L)
{
lua_pushinteger(L,5 * lua_tointeger(L,1) + 2);
return 1;
}
static int baz(lua_State *L)
{
luaL_Buffer buf;
char *p;
int l;
int x;
luaL_buffinit(L,&buf);
luaL_addstring(&buf,"result: ");
lua_getglobal(L,"foo");
lua_call(L,0,1);
x = lua_tointeger(L,-1);
p = luaL_prepbuffsize(&buf,10000);
l = snprintf(p,10000,"%d",x * 2);
luaL_addsize(&buf,l);
luaL_pushresult(&buf);
return 1;
}
int main(void)
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L,bar);
lua_setglobal(L,"bar");
luaL_loadstring(L,"function foo() return bar(3) * 4 + 5 end");
lua_call(L,0,0);
lua_getglobal(L,"print");
lua_pushcfunction(L,baz);
lua_call(L,0,1);
lua_call(L,1,0);
lua_close(L);
return 0;
}
-spc (Which is how I think the luaL_Buffer API is supposed to be used ... )