diff options
author | dequis <dx@dxzone.com.ar> | 2017-06-17 14:30:37 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2017-06-17 15:34:36 -0300 |
commit | 7354a74c654f1717d08a37c2b118141655974bc0 (patch) | |
tree | bcabcf818ec09a8b4083a4baf4fa04b7b50156cb /src/core/misc.c | |
parent | 9d3cfe1069b5cfaf0efb972e36695b781ecf93de (diff) | |
download | irssi-7354a74c654f1717d08a37c2b118141655974bc0.zip |
parse_time_interval: Allow negative time in settings
This splits sign parsing out of parse_time_interval_uint() so that the
negative sign is applied outside of the unsigned context where the
number parsing is done, and after all the checks that it's lower than
(1 << 31)
This fixes issues with settings like `server_reconnect_time`,
`server_connect_timeout` and `lag_max_before_disconnect`, which accepted
-1 as a valid value.
Diffstat (limited to 'src/core/misc.c')
-rw-r--r-- | src/core/misc.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/core/misc.c b/src/core/misc.c index 0f038cbb..ce49925b 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -781,24 +781,35 @@ int parse_uint(const char *nptr, char **endptr, int base, guint *number) return TRUE; } +static int parse_number_sign(const char *input, char **endptr, int *sign) +{ + int sign_ = 1; + + while (i_isspace(*input)) + input++; + + if (*input == '-') { + sign_ = -sign_; + input++; + } + + *sign = sign_; + *endptr = (char *) input; + return TRUE; +} + static int parse_time_interval_uint(const char *time, guint *msecs) { const char *desc; guint number; - int sign, len, ret, digits; + int len, ret, digits; *msecs = 0; /* max. return value is around 24 days */ - number = 0; sign = 1; ret = TRUE; digits = FALSE; + number = 0; ret = TRUE; digits = FALSE; while (i_isspace(*time)) time++; - if (*time == '-') { - sign = -sign; - time++; - while (i_isspace(*time)) - time++; - } for (;;) { if (i_isdigit(*time)) { char *endptr; @@ -828,7 +839,6 @@ static int parse_time_interval_uint(const char *time, guint *msecs) if (*time != '\0') return FALSE; *msecs += number * 1000; /* assume seconds */ - *msecs *= sign; return TRUE; } @@ -866,7 +876,6 @@ static int parse_time_interval_uint(const char *time, guint *msecs) digits = FALSE; } - *msecs *= sign; return ret; } @@ -960,15 +969,18 @@ int parse_size(const char *size, int *bytes) int parse_time_interval(const char *time, int *msecs) { guint msecs_; - int ret; + char *number; + int ret, sign; + + parse_number_sign(time, &number, &sign); - ret = parse_time_interval_uint(time, &msecs_); + ret = parse_time_interval_uint(number, &msecs_); if (msecs_ > (1U << 31)) { return FALSE; } - *msecs = msecs_; + *msecs = msecs_ * sign; return ret; } |