Plug up some holes with lib_cvRegisterVar

* Error if a consvar is set to an empty string
* Error if a consvar is not given a defaultvalue
This commit is contained in:
SteelT 2022-10-03 16:04:38 -04:00
parent e08ebac5c8
commit 534b610a76

View file

@ -313,36 +313,57 @@ static int lib_cvRegisterVar(lua_State *L)
#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))
lua_pushnil(L);
while (lua_next(L, 1)) {
while (lua_next(L, 1))
{
// stack: cvar table, cvar userdata, key/index, value
// 1 2 3 4
i = 0;
k = NULL;
if (lua_isnumber(L, 3))
{
i = lua_tointeger(L, 3);
}
else if (lua_isstring(L, 3))
{
k = lua_tostring(L, 3);
}
if (i == 1 || (k && fasticmp(k, "name"))) {
if (i == 1 || (k && fasticmp(k, "name")))
{
if (!lua_isstring(L, 4))
{
TYPEERROR("name", LUA_TSTRING)
}
cvar->name = Z_StrDup(lua_tostring(L, 4));
} else if (i == 2 || (k && fasticmp(k, "defaultvalue"))) {
}
else if (i == 2 || (k && fasticmp(k, "defaultvalue")))
{
if (!lua_isstring(L, 4))
{
TYPEERROR("defaultvalue", LUA_TSTRING)
}
cvar->defaultvalue = Z_StrDup(lua_tostring(L, 4));
} else if (i == 3 || (k && fasticmp(k, "flags"))) {
}
else if (i == 3 || (k && fasticmp(k, "flags")))
{
if (!lua_isnumber(L, 4))
{
TYPEERROR("flags", LUA_TNUMBER)
}
cvar->flags = (INT32)lua_tointeger(L, 4);
} else if (i == 4 || (k && fasticmp(k, "PossibleValue"))) {
if (lua_islightuserdata(L, 4)) {
}
else if (i == 4 || (k && fasticmp(k, "PossibleValue")))
{
if (lua_islightuserdata(L, 4))
{
CV_PossibleValue_t *pv = lua_touserdata(L, 4);
if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural)
cvar->PossibleValue = pv;
else
FIELDERROR("PossibleValue", "CV_PossibleValue_t expected, got unrecognised pointer")
} else if (lua_istable(L, 4)) {
}
else if (lua_istable(L, 4))
{
// Accepts tables in the form of {MIN=0, MAX=9999} or {Red=0, Green=1, Blue=2}
// and converts them to CV_PossibleValue_t {{0,"MIN"},{9999,"MAX"}} or {{0,"Red"},{1,"Green"},{2,"Blue"}}
//
@ -353,7 +374,8 @@ static int lib_cvRegisterVar(lua_State *L)
CV_PossibleValue_t *cvpv;
lua_pushnil(L);
while (lua_next(L, 4)) {
while (lua_next(L, 4))
{
count++;
lua_pop(L, 1);
}
@ -367,7 +389,8 @@ static int lib_cvRegisterVar(lua_State *L)
i = 0;
lua_pushnil(L);
while (lua_next(L, 4)) {
while (lua_next(L, 4))
{
// stack: [...] PossibleValue table, index, value
// 4 5 6
if (lua_type(L, 5) != LUA_TSTRING
@ -381,11 +404,18 @@ static int lib_cvRegisterVar(lua_State *L)
cvpv[i].value = 0;
cvpv[i].strvalue = NULL;
cvar->PossibleValue = cvpv;
} else
}
else
{
FIELDERROR("PossibleValue", va("%s or CV_PossibleValue_t expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
} else if (cvar->flags & CV_CALL && (i == 5 || (k && fasticmp(k, "func")))) {
}
}
else if (cvar->flags & CV_CALL && (i == 5 || (k && fasticmp(k, "func"))))
{
if (!lua_isfunction(L, 4))
{
TYPEERROR("func", LUA_TFUNCTION)
}
lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange");
I_Assert(lua_istable(L, 5));
lua_pushlightuserdata(L, cvar);
@ -400,18 +430,34 @@ static int lib_cvRegisterVar(lua_State *L)
#undef FIELDERROR
#undef TYPEERROR
if (!cvar->name)
return luaL_error(L, M_GetText("Variable has no name!\n"));
if (!cvar->name || cvar->name[0] == '\0')
{
return luaL_error(L, M_GetText("Variable has no name!"));
}
if (!cvar->defaultvalue)
{
return luaL_error(L, M_GetText("Variable has no defaultvalue!"));
}
if ((cvar->flags & CV_NOINIT) && !(cvar->flags & CV_CALL))
return luaL_error(L, M_GetText("Variable %s has CV_NOINIT without CV_CALL\n"), cvar->name);
{
return luaL_error(L, M_GetText("Variable %s has CV_NOINIT without CV_CALL"), cvar->name);
}
if ((cvar->flags & CV_CALL) && !cvar->func)
return luaL_error(L, M_GetText("Variable %s has CV_CALL without a function\n"), cvar->name);
{
return luaL_error(L, M_GetText("Variable %s has CV_CALL without a function"), cvar->name);
}
// actually time to register it to the console now! Finally!
cvar->flags |= CV_MODIFIED;
CV_RegisterVar(cvar);
if (cvar->flags & CV_MODIFIED)
{
return luaL_error(L, "failed to register cvar (probable conflict with internal variable/command names)");
}
// return cvar userdata
return 1;