fix(color): prevent crash, show error if Lua script uses a deleted LVGL object (#6229)

This commit is contained in:
philmoz
2025-05-12 09:10:37 +10:00
committed by GitHub
parent 04a7e340d7
commit d22628d1d6
5 changed files with 92 additions and 66 deletions
+68 -49
View File
@@ -112,15 +112,19 @@ static bool pcallFuncWithString(lua_State *L, int funcRef, int nretval, const ch
//-----------------------------------------------------------------------------
LvglWidgetObjectBase *LvglWidgetObjectBase::checkLvgl(lua_State *L, int index)
LvglWidgetObjectBase *LvglWidgetObjectBase::checkLvgl(lua_State *L, int index, bool required)
{
LvglWidgetObjectBase **p;
p = (LvglWidgetObjectBase **)luaL_testudata(L, index, LVGL_METATABLE);
if (p) return *p;
if (p && *p) return *p;
p = (LvglWidgetObjectBase **)luaL_testudata(L, index, LVGL_SIMPLEMETATABLE);
if (p) return *p;
if (p && *p) return *p;
if (required) {
luaL_error(L, "Invalid lvgl object (it has been probably been cleared).");
}
return nullptr;
}
@@ -170,16 +174,18 @@ void LvglWidgetObjectBase::getParams(lua_State *L, int index)
void LvglWidgetObjectBase::pcallSimpleFunc(lua_State *L, int funcRef)
{
if (funcRef != LUA_REFNIL) {
auto save = luaScriptManager;
luaScriptManager = lvglManager;
PROTECT_LUA()
{
auto save = luaScriptManager;
luaScriptManager = lvglManager;
if (!pcallFunc(L, funcRef, 0)) {
lvglManager->luaShowError();
}
luaScriptManager = save;
} else {
lvglManager->luaShowError();
}
UNPROTECT_LUA();
luaScriptManager = save;
}
}
@@ -191,18 +197,24 @@ bool LvglWidgetObjectBase::pcallUpdateBool(lua_State *L, int getFuncRef,
auto save = luaScriptManager;
luaScriptManager = lvglManager;
int t = lua_gettop(L);
if (pcallFunc(L, getFuncRef, 1)) {
bool val = false;
if (lua_isboolean(L, -1))
val = lua_toboolean(L, -1);
else
val = luaL_optinteger(L, -1, 0) != 0;
update(val);
lua_settop(L, t);
PROTECT_LUA()
{
if (pcallFunc(L, getFuncRef, 1)) {
bool val = false;
if (lua_isboolean(L, -1))
val = lua_toboolean(L, -1);
else
val = luaL_optinteger(L, -1, 0) != 0;
update(val);
} else {
res = false;
}
} else {
res = false;
lvglManager->luaShowError();
}
lvglManager = save;
UNPROTECT_LUA();
lua_settop(L, t);
luaScriptManager = save;
}
return res;
}
@@ -215,14 +227,20 @@ bool LvglWidgetObjectBase::pcallUpdate1Int(lua_State *L, int getFuncRef,
auto save = luaScriptManager;
luaScriptManager = lvglManager;
int t = lua_gettop(L);
if (pcallFunc(L, getFuncRef, 1)) {
int val = luaL_checkunsigned(L, -1);
update(val);
lua_settop(L, t);
PROTECT_LUA()
{
if (pcallFunc(L, getFuncRef, 1)) {
int val = luaL_checkunsigned(L, -1);
update(val);
} else {
res = false;
}
} else {
res = false;
lvglManager->luaShowError();
}
lvglManager = save;
UNPROTECT_LUA();
lua_settop(L, t);
luaScriptManager = save;
}
return res;
}
@@ -235,15 +253,21 @@ bool LvglWidgetObjectBase::pcallUpdate2Int(lua_State *L, int getFuncRef,
auto save = luaScriptManager;
luaScriptManager = lvglManager;
int t = lua_gettop(L);
if (pcallFunc(L, getFuncRef, 2)) {
int v1 = luaL_checkunsigned(L, -2);
int v2 = luaL_checkunsigned(L, -1);
update(v1, v2);
lua_settop(L, t);
PROTECT_LUA()
{
if (pcallFunc(L, getFuncRef, 2)) {
int v1 = luaL_checkunsigned(L, -2);
int v2 = luaL_checkunsigned(L, -1);
update(v1, v2);
} else {
res = false;
}
} else {
res = false;
lvglManager->luaShowError();
}
lvglManager = save;
UNPROTECT_LUA();
lua_settop(L, t);
luaScriptManager = save;
}
return res;
}
@@ -265,14 +289,12 @@ int LvglWidgetObjectBase::pcallGetIntVal(lua_State *L, int getFuncRef)
} else {
lvglManager->luaShowError();
}
}
else
{
} else {
lvglManager->luaShowError();
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
luaScriptManager = save;
}
return val;
}
@@ -294,14 +316,12 @@ int LvglWidgetObjectBase::pcallGetOptIntVal(lua_State *L, int getFuncRef, int de
} else {
lvglManager->luaShowError();
}
}
else
{
} else {
lvglManager->luaShowError();
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
luaScriptManager = save;
}
return val;
}
@@ -317,14 +337,12 @@ void LvglWidgetObjectBase::pcallSetIntVal(lua_State *L, int setFuncRef, int val)
if (!pcallFuncWithInt(L, setFuncRef, 0, val)) {
lvglManager->luaShowError();
}
}
else
{
} else {
lvglManager->luaShowError();
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
luaScriptManager = save;
}
}
@@ -342,14 +360,12 @@ const char* LvglWidgetObjectBase::pcallGetStringVal(lua_State *L, int getFuncRef
} else {
lvglManager->luaShowError();
}
}
else
{
} else {
lvglManager->luaShowError();
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
luaScriptManager = save;
}
return val;
}
@@ -365,14 +381,12 @@ void LvglWidgetObjectBase::pcallSetStringVal(lua_State *L, int setFuncRef, const
if (!pcallFuncWithString(L, setFuncRef, 0, val)) {
lvglManager->luaShowError();
}
}
else
{
} else {
lvglManager->luaShowError();
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
luaScriptManager = save;
}
}
@@ -471,6 +485,11 @@ void LvglWidgetObjectBase::clearChildRefs(lua_State *L)
void LvglWidgetObjectBase::clearRefs(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef);
auto p = (LvglWidgetObjectBase **)luaL_testudata(L, -1, metatable);
if (p) *p = nullptr;
lua_pop(L, 1);
clearRef(L, luaRef);
clearRef(L, color.function);
clearRef(L, opacity.function);