From: terencehill <piuntn@gmail.com>
Date: Thu, 11 Apr 2019 20:23:11 +0000 (+0200)
Subject: Fix array indices out of bounds; abort dump if a weapon / turret has more than MAX_CO... 
X-Git-Tag: xonotic-v0.8.5~1546^2~5
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=2a5eece0284574783afd4de43735ab38a98d328d;p=xonotic%2Fxonotic-data.pk3dir.git

Fix array indices out of bounds; abort dump if a weapon / turret has more than MAX_CONFIG_SETTINGS settings
---

diff --git a/qcsrc/common/turrets/config.qc b/qcsrc/common/turrets/config.qc
index d1a980d76..19b64ff07 100644
--- a/qcsrc/common/turrets/config.qc
+++ b/qcsrc/common/turrets/config.qc
@@ -1,10 +1,23 @@
 #include "config.qh"
+#if defined(CSQC)
+#elif defined(MENUQC)
+#elif defined(SVQC)
+	#include <common/util.qh>
+	#include "all.qh"
+#endif
+
 // ==========================
 //  Turret Config Generator
 // ==========================
 
 #ifdef SVQC
 
+void T_Config_Queue(string setting)
+{
+	if (TUR_CONFIG_COUNT <= MAX_CONFIG_SETTINGS - 1)
+		config_queue[TUR_CONFIG_COUNT++] = setting;
+}
+
 void T_Config_Queue_Swap(float root, float child, entity pass)
 {
 	string oldroot = config_queue[root];
@@ -35,18 +48,24 @@ void Dump_Turret_Settings()
 	FOREACH(Turrets, it != TUR_Null, {
 		// step 1: clear the queue
 		TUR_CONFIG_COUNT = 0;
-		for(int j = 0; j <= MAX_CONFIG_SETTINGS; ++j)
+		for (int j = 0; j < MAX_CONFIG_SETTINGS; ++j)
 			config_queue[j] = string_null;
 
 		// step 2: build new queue
 		it.tr_config(it);
 
+		if (TUR_CONFIG_COUNT > MAX_CONFIG_SETTINGS - 1)
+		{
+			LOG_INFOF("\n^1Dumping aborted^7: hit MAX_CONFIG_SETTINGS (%d) limit\n\n", MAX_CONFIG_SETTINGS);
+			break;
+		}
+
 		// step 3: sort queue
 		heapsort(TUR_CONFIG_COUNT, T_Config_Queue_Swap, T_Config_Queue_Compare, NULL);
 
 		// step 4: write queue
 		TUR_CONFIG_WRITETOFILE(sprintf("// {{{ #%d: %s\n", i, it.turret_name));
-		for(int j = 0; j <= TUR_CONFIG_COUNT; ++j)
+		for (int j = 0; j < TUR_CONFIG_COUNT; ++j)
 			TUR_CONFIG_WRITETOFILE(config_queue[j]);
 		TUR_CONFIG_WRITETOFILE("// }}}\n");
 
@@ -56,13 +75,14 @@ void Dump_Turret_Settings()
 	});
 	#undef TUR_CONFIG_WRITETOFILE
 
+	// extra information
+	if (TUR_CONFIG_COUNT <= MAX_CONFIG_SETTINGS - 1)
+		LOG_INFOF("Totals: %d turrets, %d settings", (Turrets_COUNT - 1), totalsettings);
+
 	// clear queue now that we're finished
 	TUR_CONFIG_COUNT = 0;
-	for(int j = 0; j <= MAX_CONFIG_SETTINGS; ++j)
+	for (int j = 0; j < MAX_CONFIG_SETTINGS; ++j)
 		config_queue[j] = string_null;
-
-	// extra information
-	LOG_INFOF("Totals: %d turrets, %d settings", (Turrets_COUNT - 1), totalsettings);
 }
 
 #endif
diff --git a/qcsrc/common/turrets/config.qh b/qcsrc/common/turrets/config.qh
index 274128381..06e66fa27 100644
--- a/qcsrc/common/turrets/config.qh
+++ b/qcsrc/common/turrets/config.qh
@@ -10,18 +10,20 @@ float tur_config_file;
 float tur_config_alsoprint;
 
 float TUR_CONFIG_COUNT;
-#define TUR_CONFIG_QUEUE(a) config_queue[TUR_CONFIG_COUNT++] = a;
+void T_Config_Queue(string setting);
 
 #define TUR_CONFIG_WRITE_CVARS(turname, name, T) TUR_CONFIG_WRITE_PROPS_##T(turname, name)
 
-#define TUR_CONFIG_WRITE_PROPS_string(turname, name) \
-	{ TUR_CONFIG_QUEUE( \
+#define TUR_CONFIG_WRITE_PROPS_string(turname, name) {\
+	T_Config_Queue( \
 		sprintf("set g_turrets_unit_%s_%s \"%s\"\n", #turname, #name, \
-		cvar_string(sprintf("g_turrets_unit_%s_%s", #turname, #name)))) }
+		cvar_string(sprintf("g_turrets_unit_%s_%s", #turname, #name)))); \
+}
 
-#define TUR_CONFIG_WRITE_PROPS_float(turname, name) \
-	{ TUR_CONFIG_QUEUE( \
+#define TUR_CONFIG_WRITE_PROPS_float(turname, name) {\
+	T_Config_Queue( \
 		sprintf("set g_turrets_unit_%s_%s %g\n", #turname, #name, \
-		cvar(sprintf("g_turrets_unit_%s_%s", #turname, #name)))) }
+		cvar(sprintf("g_turrets_unit_%s_%s", #turname, #name)))); \
+}
 
 #endif
diff --git a/qcsrc/common/weapons/config.qc b/qcsrc/common/weapons/config.qc
index f9ff67393..f1cc349ca 100644
--- a/qcsrc/common/weapons/config.qc
+++ b/qcsrc/common/weapons/config.qc
@@ -2,14 +2,20 @@
 #if defined(CSQC)
 #elif defined(MENUQC)
 #elif defined(SVQC)
-    #include <common/util.qh>
-    #include "all.qh"
+	#include <common/util.qh>
+	#include "all.qh"
 #endif
 
 // ==========================
 //  Balance Config Generator
 // ==========================
 
+void W_Config_Queue(string setting)
+{
+	if (WEP_CONFIG_COUNT <= MAX_CONFIG_SETTINGS - 1)
+		config_queue[WEP_CONFIG_COUNT++] = setting;
+}
+
 void W_Config_Queue_Swap(int root, int child, entity pass)
 {
 	string oldroot = config_queue[root];
@@ -32,12 +38,18 @@ void Dump_Weapon_Settings()
 			continue; // never include the attacks
 		// step 1: clear the queue
 		WEP_CONFIG_COUNT = 0;
-		for (int x = 0; x <= MAX_CONFIG_SETTINGS; ++x)
+		for (int x = 0; x < MAX_CONFIG_SETTINGS; ++x)
 			config_queue[x] = string_null;
 
 		// step 2: build new queue
 		it.wr_config(it);
 
+		if (WEP_CONFIG_COUNT > MAX_CONFIG_SETTINGS - 1)
+		{
+			LOG_INFOF("\n^1Dumping aborted^7: hit MAX_CONFIG_SETTINGS (%d) limit\n\n", MAX_CONFIG_SETTINGS);
+			break;
+		}
+
 		// step 3: sort queue
 		heapsort(WEP_CONFIG_COUNT, W_Config_Queue_Swap, W_Config_Queue_Compare, NULL);
 
@@ -48,7 +60,7 @@ void Dump_Weapon_Settings()
 			it.m_name,
 			((it.spawnflags & WEP_FLAG_MUTATORBLOCKED) ? " (MUTATOR WEAPON)" : "")
 		));
-		for (int x = 0; x <= WEP_CONFIG_COUNT; ++x)
+		for (int x = 0; x < WEP_CONFIG_COUNT; ++x)
 			WEP_CONFIG_WRITETOFILE(config_queue[x]);
 		WEP_CONFIG_WRITETOFILE("// }}}\n");
 
@@ -60,11 +72,12 @@ void Dump_Weapon_Settings()
 	});
 	#undef WEP_CONFIG_WRITETOFILE
 
+	// extra information
+	if (WEP_CONFIG_COUNT <= MAX_CONFIG_SETTINGS - 1)
+		LOG_INFOF("Totals: %d weapons, %d settings", totalweapons, totalsettings);
+
 	// clear queue now that we're finished
 	WEP_CONFIG_COUNT = 0;
-	for(int x = 0; x <= MAX_CONFIG_SETTINGS; ++x)
+	for (int x = 0; x < MAX_CONFIG_SETTINGS; ++x)
 		config_queue[x] = string_null;
-
-	// extra information
-	LOG_INFOF("Totals: %d weapons, %d settings", totalweapons, totalsettings);
 }
diff --git a/qcsrc/common/weapons/config.qh b/qcsrc/common/weapons/config.qh
index 26a37a7ce..b84268498 100644
--- a/qcsrc/common/weapons/config.qh
+++ b/qcsrc/common/weapons/config.qh
@@ -10,18 +10,20 @@ int wep_config_file;
 bool wep_config_alsoprint;
 
 int WEP_CONFIG_COUNT;
-#define WEP_CONFIG_QUEUE(a) config_queue[WEP_CONFIG_COUNT++] = a;
+void W_Config_Queue(string setting);
 
 #define WEP_CONFIG_WRITE_CVARS(wepname, name, T) WEP_CONFIG_WRITE_PROPS_##T(wepname, name)
 
-#define WEP_CONFIG_WRITE_PROPS_string(wepname, name) \
-	{ WEP_CONFIG_QUEUE( \
+#define WEP_CONFIG_WRITE_PROPS_string(wepname, name) {\
+	W_Config_Queue( \
 		sprintf("set g_balance_%s_%s \"%s\"\n", #wepname, #name, \
-		cvar_string(sprintf("g_balance_%s_%s", #wepname, #name)))) }
+		cvar_string(sprintf("g_balance_%s_%s", #wepname, #name)))); \
+}
 
-#define WEP_CONFIG_WRITE_PROPS_float(wepname, name) \
-	{ WEP_CONFIG_QUEUE( \
+#define WEP_CONFIG_WRITE_PROPS_float(wepname, name) {\
+	W_Config_Queue( \
 		sprintf("set g_balance_%s_%s %g\n", #wepname, #name, \
-		cvar(sprintf("g_balance_%s_%s", #wepname, #name)))) }
+		cvar(sprintf("g_balance_%s_%s", #wepname, #name)))); \
+}
 
 #endif