diff options
author | Darkvater <darkvater@openttd.org> | 2006-03-28 21:51:14 +0000 |
---|---|---|
committer | Darkvater <darkvater@openttd.org> | 2006-03-28 21:51:14 +0000 |
commit | 85602659537e2ff2b93f47294a1a1add6dbaeee6 (patch) | |
tree | 2f3c43d8636a934d32307352bc552d097094e7cd | |
parent | 1e428481b2c7035fdba6936b2ba3f9af347d76e9 (diff) | |
download | openttd-85602659537e2ff2b93f47294a1a1add6dbaeee6.tar.xz |
(svn r4142) - Fix [FS#74]: Incorrectly loaded settings from the config file when the signed uint32 variable would be negative.
-rw-r--r-- | macros.h | 6 | ||||
-rw-r--r-- | settings.c | 32 |
2 files changed, 34 insertions, 4 deletions
@@ -35,6 +35,12 @@ static inline int clamp(int a, int min, int max) return a; } +static inline uint clampu(uint a, uint min, uint max) +{ + if (a <= min) return min; + if (a >= max) return max; + return a; +} static inline int32 BIGMULSS(int32 a, int32 b, int shift) { return (int32)(((int64)(a) * (int64)(b)) >> (shift)); diff --git a/settings.c b/settings.c index bce3601fd..02b4dff28 100644 --- a/settings.c +++ b/settings.c @@ -583,15 +583,39 @@ static const void *string_to_val(const SettingDescBase *desc, const char *str) static void Write_ValidateSetting(void *ptr, const SettingDesc *sd, int32 val) { const SettingDescBase *sdb = &sd->desc; - int32 min; if (sdb->cmd != SDT_BOOLX && sdb->cmd != SDT_NUMX && sdb->cmd != SDT_ONEOFMANY && sdb->cmd != SDT_MANYOFMANY) return; - /* Override the minimum value. No value below sdb->min, except special value 0 */ - min = ((sdb->flags & SGF_0ISDISABLED) && val <= sdb->min) ? 0 : sdb->min; /* We cannot know the maximum value of a bitset variable, so just have faith */ - val = (sdb->cmd == SDT_MANYOFMANY) ? val : clamp(val, min, sdb->max); + if (sdb->cmd != SDT_MANYOFMANY) { + /* We need to take special care of the uint32 type as we receive from the function + * a signed integer. While here also bail out on 64-bit settings as those are not + * supported. Unsigned 8 and 16-bit variables are safe since they fit into a signed + * 32-bit variable + * TODO: Support 64-bit settings/variables */ + switch (GetVarMemType(sd->save.conv)) { + case SLE_VAR_BL: + case SLE_VAR_I8: + case SLE_VAR_U8: + case SLE_VAR_I16: + case SLE_VAR_U16: + case SLE_VAR_I32: { + /* Override the minimum value. No value below sdb->min, except special value 0 */ + int32 min = ((sdb->flags & SGF_0ISDISABLED) && val <= sdb->min) ? 0 : sdb->min; + val = clamp(val, min, sdb->max); + } break; + case SLE_VAR_U32: { + /* Override the minimum value. No value below sdb->min, except special value 0 */ + uint min = ((sdb->flags & SGF_0ISDISABLED) && (uint)val <= (uint)sdb->min) ? 0 : sdb->min; + WriteValue(ptr, SLE_VAR_U32, (int64)clampu(val, min, sdb->max)); + return; + } + case SLE_VAR_I64: + case SLE_VAR_U64: + default: NOT_REACHED(); break; + } + } WriteValue(ptr, sd->save.conv, (int64)val); } |