Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Commit

Permalink
Fixed reentrancy bug found by Florian Weimer (patch by Sam Roberts)
Browse files Browse the repository at this point in the history
The patch marks the lxp userdata as busy during calls to XML_Parse().
  • Loading branch information
Andre Carregal committed Dec 11, 2008
1 parent be33b6e commit 4490830
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions src/lxplib.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lxplib.c,v 1.16 2007-06-05 20:03:12 carregal Exp $
** $Id: lxplib.c,v 1.17 2008-12-11 19:05:13 carregal Exp $
** LuaExpat: Lua bind for Expat library
** See Copyright Notice in license.html
*/
Expand Down Expand Up @@ -33,6 +33,7 @@ enum XPState {
struct lxp_userdata {
lua_State *L;
XML_Parser parser; /* associated expat parser */
int busy; /* true while parsing, used to avoid calling XML_Parse() recursively */
int tableref; /* table with callbacks for this parser */
enum XPState state;
luaL_Buffer *b; /* to concatenate sequences of cdata pieces */
Expand All @@ -55,9 +56,8 @@ static int reporterror (lxp_userdata *xpu) {

static lxp_userdata *createlxp (lua_State *L) {
lxp_userdata *xpu = (lxp_userdata *)lua_newuserdata(L, sizeof(lxp_userdata));
memset(xpu, 0, sizeof(*xpu));
xpu->tableref = LUA_REFNIL; /* in case of errors... */
xpu->parser = NULL;
xpu->L = NULL;
xpu->state = XPSpre;
luaL_getmetatable(L, ParserType);
lua_setmetatable(L, -2);
Expand Down Expand Up @@ -435,7 +435,9 @@ static int parse_aux (lua_State *L, lxp_userdata *xpu, const char *s,
xpu->b = &b;
lua_settop(L, 2);
lua_getref(L, xpu->tableref); /* to be used by handlers */
xpu->busy = 1;
status = XML_Parse(xpu->parser, s, (int)len, s == NULL);
xpu->busy = 0;
if (xpu->state == XPSstring) dischargestring(xpu);
if (xpu->state == XPSerror) { /* callback error? */
lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref); /* get original msg. */
Expand All @@ -456,6 +458,7 @@ static int lxp_parse (lua_State *L) {
lxp_userdata *xpu = checkparser(L, 1);
size_t len;
const char *s = luaL_optlstring(L, 2, NULL, &len);
luaL_argcheck(L, !xpu->busy, 1, "expat parser is busy");
if (xpu->state == XPSfinished && s != NULL) {
lua_pushnil(L);
lua_pushliteral(L, "cannot parse - document is finished");
Expand All @@ -469,6 +472,7 @@ static int lxp_close (lua_State *L) {
int status = 1;
lxp_userdata *xpu = (lxp_userdata *)luaL_checkudata(L, 1, ParserType);
luaL_argcheck(L, xpu, 1, "expat parser expected");
luaL_argcheck(L, !xpu->busy, 1, "expat parser is busy");
if (xpu->state != XPSfinished)
status = parse_aux(L, xpu, NULL, 0);
lxpclose(L, xpu);
Expand Down

0 comments on commit 4490830

Please sign in to comment.