aboutsummaryrefslogtreecommitdiff
path: root/lauxlib.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2026-06-17 11:20:10 -0300
committerRoberto I <roberto@inf.puc-rio.br>2026-06-17 11:20:10 -0300
commitbc4bbcef651ba2870d6c68db16dc7d6ce6f68636 (patch)
tree36e85d893a478aaf03b9490537bfb3cd522fb630 /lauxlib.c
parent40b76de2d77e66b70a9d4bf989c3f5340919973f (diff)
downloadlua-bc4bbcef651ba2870d6c68db16dc7d6ce6f68636.tar.gz
lua-bc4bbcef651ba2870d6c68db16dc7d6ce6f68636.tar.bz2
lua-bc4bbcef651ba2870d6c68db16dc7d6ce6f68636.zip
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.
Diffstat (limited to 'lauxlib.c')
-rw-r--r--lauxlib.c17
1 files 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 */
513}; 513};
514 514
515 515
516/*
517** Get/create metatable (MT) for boxes
518*/
519static void getBoxMT (lua_State *L) {
520 const char *BOXMT = "_UBOX*"; /* key for the metatable */
521 if (luaL_getmetatable(L, BOXMT) == LUA_TNIL) { /* MT not created yet? */
522 luaL_newlibtable(L, boxmt); /* create it */
523 luaL_setfuncs(L, boxmt, 0); /* initialize it */
524 lua_copy(L, -1, -2); /* change stack from nil,MT to MT,MT */
525 lua_setfield(L, LUA_REGISTRYINDEX, BOXMT); /* store MT in the registry */
526 }
527}
528
529
516static void newbox (lua_State *L) { 530static void newbox (lua_State *L) {
517 UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); 531 UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0);
518 box->box = NULL; 532 box->box = NULL;
519 box->bsize = 0; 533 box->bsize = 0;
520 if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ 534 getBoxMT(L);
521 luaL_setfuncs(L, boxmt, 0); /* set its metamethods */
522 lua_setmetatable(L, -2); 535 lua_setmetatable(L, -2);
523} 536}
524 537