summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-05-20 15:14:10 +0000
committerrubidium <rubidium@openttd.org>2010-05-20 15:14:10 +0000
commitdd743bcea1e00b5b1314860bc3f1bda91419d5f1 (patch)
tree3aeed40f13a15f06c0743e44023b72a58daf1d0f
parentf1c1812e475d01233b59cf129b787d4bedf63996 (diff)
downloadopenttd-dd743bcea1e00b5b1314860bc3f1bda91419d5f1.tar.xz
(svn r19865) -Fix [FS#3830]: crash when changing locale settings from console due to strcpy-ing a string into a pointer
-rw-r--r--src/settings.cpp17
-rw-r--r--src/settings_internal.h2
2 files changed, 13 insertions, 6 deletions
diff --git a/src/settings.cpp b/src/settings.cpp
index fffe35a9a..71bdf9e2b 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -1713,15 +1713,22 @@ uint GetCompanySettingIndex(const char *name)
* Set a setting value with a string.
* @param index the settings index.
* @param value the value to write
- * @note CANNOT BE SAVED IN THE SAVEGAME.
+ * @param force_newgame force the newgame settings
+ * @note Strings WILL NOT be synced over the network
*/
-bool SetSettingValue(uint index, const char *value)
+bool SetSettingValue(uint index, const char *value, bool force_newgame)
{
const SettingDesc *sd = &_settings[index];
assert(sd->save.conv & SLF_NETWORK_NO);
- char *var = (char*)GetVariableAddress(NULL, &sd->save);
- ttd_strlcpy(var, value, sd->save.length);
+ if (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ) {
+ char **var = (char**)GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->save);
+ free(*var);
+ *var = strcmp(value, "(null)") == 0 ? NULL : strdup(value);
+ } else {
+ char *var = (char*)GetVariableAddress(NULL, &sd->save);
+ ttd_strlcpy(var, value, sd->save.length);
+ }
if (sd->desc.proc != NULL) sd->desc.proc(0);
return true;
@@ -1778,7 +1785,7 @@ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame)
bool success;
if (sd->desc.cmd == SDT_STRING) {
- success = SetSettingValue(index, value);
+ success = SetSettingValue(index, value, force_newgame);
} else {
uint32 val;
extern bool GetArgumentInteger(uint32 *value, const char *arg);
diff --git a/src/settings_internal.h b/src/settings_internal.h
index f97627aac..8d57a10a8 100644
--- a/src/settings_internal.h
+++ b/src/settings_internal.h
@@ -86,7 +86,7 @@ typedef SettingDesc SettingDescGlobVarList;
const SettingDesc *GetSettingFromName(const char *name, uint *i);
bool SetSettingValue(uint index, int32 value, bool force_newgame = false);
-bool SetSettingValue(uint index, const char *value);
+bool SetSettingValue(uint index, const char *value, bool force_newgame = false);
void SetCompanySetting(uint index, int32 value);
extern VehicleDefaultSettings _old_vds;