# HG changeset patch # User rubidium # Date 2010-05-20 15:14:10 # Node ID 4e305be6015a3469111f0a933264ce3612f36635 # Parent 399a475edd5fa49bf80cb6ae0e489c853e7516e8 (svn r19865) -Fix [FS#3830]: crash when changing locale settings from console due to strcpy-ing a string into a pointer diff --git a/src/settings.cpp b/src/settings.cpp --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1713,15 +1713,22 @@ uint GetCompanySettingIndex(const char * * 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 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 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -86,7 +86,7 @@ typedef SettingDesc SettingDescGlobVarLi 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;