changeset 15231:82d0bcb2cf7d draft

(svn r19865) -Fix [FS#3830]: crash when changing locale settings from console due to strcpy-ing a string into a pointer
author rubidium <rubidium@openttd.org>
date Thu, 20 May 2010 15:14:10 +0000
parents 8f2ef31b6876
children 30f4ce8e6ad0
files src/settings.cpp src/settings_internal.h
diffstat 2 files changed, 13 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -1713,15 +1713,22 @@
  * 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 @@
 
 	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);
--- a/src/settings_internal.h
+++ b/src/settings_internal.h
@@ -86,7 +86,7 @@
 
 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;