aboutsummaryrefslogtreecommitdiff
path: root/lauxlib.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2026-07-24 11:38:45 -0300
committerRoberto I <roberto@inf.puc-rio.br>2026-07-24 11:38:45 -0300
commitf4f4968fd3947519fdca385b6f9757e55ae60441 (patch)
tree30f2eb3120ea1184e25c0d710a332210710ff391 /lauxlib.c
parente282da498cbf0bd5ea474b38bd61f6a1453d035d (diff)
downloadlua-f4f4968fd3947519fdca385b6f9757e55ae60441.tar.gz
lua-f4f4968fd3947519fdca385b6f9757e55ae60441.tar.bz2
lua-f4f4968fd3947519fdca385b6f9757e55ae60441.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 923105ed..f9a45384 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -501,12 +501,25 @@ static const luaL_Reg boxmt[] = { /* box metamethods */
501}; 501};
502 502
503 503
504/*
505** Get/create metatable (MT) for boxes
506*/
507static void getBoxMT (lua_State *L) {
508 const char *BOXMT = "_UBOX*"; /* key for the metatable */
509 if (luaL_getmetatable(L, BOXMT) == LUA_TNIL) { /* MT not created yet? */
510 luaL_newlibtable(L, boxmt); /* create it */
511 luaL_setfuncs(L, boxmt, 0); /* initialize it */
512 lua_copy(L, -1, -2); /* change stack from nil,MT to MT,MT */
513 lua_setfield(L, LUA_REGISTRYINDEX, BOXMT); /* store MT in the registry */
514 }
515}
516
517
504static void newbox (lua_State *L) { 518static void newbox (lua_State *L) {
505 UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); 519 UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0);
506 box->box = NULL; 520 box->box = NULL;
507 box->bsize = 0; 521 box->bsize = 0;
508 if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ 522 getBoxMT(L);
509 luaL_setfuncs(L, boxmt, 0); /* set its metamethods */
510 lua_setmetatable(L, -2); 523 lua_setmetatable(L, -2);
511} 524}
512 525