From 2a5eece0284574783afd4de43735ab38a98d328d Mon Sep 17 00:00:00 2001 From: terencehill Date: Thu, 11 Apr 2019 22:23:11 +0200 Subject: [PATCH] Fix array indices out of bounds; abort dump if a weapon / turret has more than MAX_CONFIG_SETTINGS settings --- qcsrc/common/turrets/config.qc | 32 ++++++++++++++++++++++++++------ qcsrc/common/turrets/config.qh | 16 +++++++++------- qcsrc/common/weapons/config.qc | 29 +++++++++++++++++++++-------- qcsrc/common/weapons/config.qh | 16 +++++++++------- 4 files changed, 65 insertions(+), 28 deletions(-) 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 + #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 - #include "all.qh" + #include + #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 -- 2.39.2