lua-cjson
lua-cjson copied to clipboard
strbuf_free causes Bus error or SIGSEGV
When DEFAULT_ENCODE_KEEP_BUFFER is 0, strbuf_free will cause Bus error or SIGSEGV. Please see the code below:
#define DEFAULT_ENCODE_KEEP_BUFFER 0
void strbuf_free(strbuf_t *s)
{
debug_stats(s);
if (s->buf) {
free(s->buf);
s->buf = NULL;
}
if (s->dynamic)
free(s);
}
static int json_destroy_config(lua_State *l)
{
json_config_t *cfg;
cfg = lua_touserdata(l, 1);
if (cfg)
strbuf_free(&cfg->encode_buf);
cfg = NULL;
return 0;
}
static void json_create_config(lua_State *l)
{
json_config_t *cfg;
int i;
cfg = lua_newuserdata(l, sizeof(*cfg));
// memset(cfg, 0, sizeof(*cfg)) should be called here
/* Create GC method to clean up strbuf */
lua_newtable(l);
lua_pushcfunction(l, json_destroy_config);
lua_setfield(l, -2, "__gc");
lua_setmetatable(l, -2);
...
#if DEFAULT_ENCODE_KEEP_BUFFER > 0
strbuf_init(&cfg->encode_buf, 0); // will not be called
#endif
}
In the json_create_config function, DEFAULT_ENCODE_KEEP_BUFFER is 0 and strbuf_init function will not be called.
When cfg = lua_newuserdata() is called, should check whether cfg is NULL. If it is not NULL, should call memset function, otherwise cfg->encode_buf.buf may not be NULL.
When the program exits json_destroy_config function calls strbuf_free function. When strbuf_free checks that cfg->encode_buf.buf is not NULL, and attempts to release memory results in an error.