From 85602659537e2ff2b93f47294a1a1add6dbaeee6 Mon Sep 17 00:00:00 2001 From: Darkvater Date: Tue, 28 Mar 2006 21:51:14 +0000 Subject: (svn r4142) - Fix [FS#74]: Incorrectly loaded settings from the config file when the signed uint32 variable would be negative. --- macros.h | 6 ++++++ settings.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/macros.h b/macros.h index 8f1064a0d..4f9fa192d 100644 --- a/macros.h +++ b/macros.h @@ -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); } -- cgit v1.2.3-54-g00ecf