From bc4bbcef651ba2870d6c68db16dc7d6ce6f68636 Mon Sep 17 00:00:00 2001 From: Roberto I Date: Wed, 17 Jun 2026 11:20:10 -0300 Subject: [PATCH] Bug: 'luaL_newmetatable' used in a wrong way The call to 'luaL_newmetatable' in 'newbox' can leave an incomplete metatable in the registry, if 'luaL_setfuncs' raises a memory error. --- lauxlib.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lauxlib.c b/lauxlib.c index af44418a..8620c8b3 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -513,12 +513,25 @@ static const luaL_Reg boxmt[] = { /* box metamethods */ }; +/* +** Get/create metatable (MT) for boxes +*/ +static void getBoxMT (lua_State *L) { + const char *BOXMT = "_UBOX*"; /* key for the metatable */ + if (luaL_getmetatable(L, BOXMT) == LUA_TNIL) { /* MT not created yet? */ + luaL_newlibtable(L, boxmt); /* create it */ + luaL_setfuncs(L, boxmt, 0); /* initialize it */ + lua_copy(L, -1, -2); /* change stack from nil,MT to MT,MT */ + lua_setfield(L, LUA_REGISTRYINDEX, BOXMT); /* store MT in the registry */ + } +} + + static void newbox (lua_State *L) { UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); box->box = NULL; box->bsize = 0; - if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ - luaL_setfuncs(L, boxmt, 0); /* set its metamethods */ + getBoxMT(L); lua_setmetatable(L, -2); }