diff options
author | Max Kellermann <max@duempel.org> | 2008-10-23 09:54:10 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2008-10-23 09:54:10 +0200 |
commit | e172874cc65f39e79ae895d35382d2fa3061d3dd (patch) | |
tree | f423adfba4b6060a3a4bc4828727c0266543bf82 /src/command.c | |
parent | 95ae1d9e9ef259ea8edd3887b9531fb39e1f633e (diff) | |
download | mpd-e172874cc65f39e79ae895d35382d2fa3061d3dd.tar.gz mpd-e172874cc65f39e79ae895d35382d2fa3061d3dd.tar.xz mpd-e172874cc65f39e79ae895d35382d2fa3061d3dd.zip |
command: check over/underflows in check_int()
The "long" result of strtol() was implicitly casted down to a 32 bit
integer. Add some range checking instead.
Diffstat (limited to 'src/command.c')
-rw-r--r-- | src/command.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/command.c b/src/command.c index 853c7d798..2f567e25b 100644 --- a/src/command.c +++ b/src/command.c @@ -129,12 +129,13 @@ check_uint32(struct client *client, uint32_t *dst, } static bool mpd_fprintf__ -check_int(struct client *client, int *dst, +check_int(struct client *client, int *value_r, const char *s, const char *fmt, ...) { char *test; + long value; - *dst = strtol(s, &test, 10); + value = strtol(s, &test, 10); if (*test != '\0') { va_list args; va_start(args, fmt); @@ -142,6 +143,16 @@ check_int(struct client *client, int *dst, va_end(args); return false; } + +#if LONG_MAX > INT_MAX + if (value < INT_MIN || value > INT_MAX) { + command_error(client, ACK_ERROR_ARG, + "Number too large: %s", s); + return false; + } +#endif + + *value_r = (int)value; return true; } |