From 534b610a76f0eb18517dceb6efe24b47600921b2 Mon Sep 17 00:00:00 2001
From: SteelT <steeltitanium1@gmail.com>
Date: Mon, 3 Oct 2022 16:04:38 -0400
Subject: [PATCH] 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
---
 src/lua_consolelib.c | 76 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 61 insertions(+), 15 deletions(-)

diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c
index c8e914e6de..8160511990 100644
--- a/src/lua_consolelib.c
+++ b/src/lua_consolelib.c
@@ -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;
-- 
GitLab