diff options
author | Daniel Stenberg <daniel@haxx.se> | 2017-08-14 23:33:23 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2017-08-14 23:33:41 +0200 |
commit | ff50fe0348466cae1a9f9f759b362c03f7060c34 (patch) | |
tree | 6a5a6efbe7bd7b00e49982e09a5da8f8341de28c /lib/strtoofft.c | |
parent | b53b4e44241415c0a7ad857c72ec323109d2a7c0 (diff) | |
download | curl-ff50fe0348466cae1a9f9f759b362c03f7060c34.tar.gz |
strtoofft: reduce integer overflow risks globally
... make sure we bail out on overflows.
Reported-by: Brian Carpenter
Closes #1758
Diffstat (limited to 'lib/strtoofft.c')
-rw-r--r-- | lib/strtoofft.c | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/lib/strtoofft.c b/lib/strtoofft.c index c2adc7280..f057bb1d6 100644 --- a/lib/strtoofft.c +++ b/lib/strtoofft.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -20,6 +20,7 @@ * ***************************************************************************/ +#include <errno.h> #include "curl_setup.h" #include "strtoofft.h" @@ -32,6 +33,30 @@ * https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html */ +#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG) +# ifdef HAVE_STRTOLL +# define strtooff strtoll +# else +# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64) +# if defined(_SAL_VERSION) + _Check_return_ _CRTIMP __int64 __cdecl _strtoi64( + _In_z_ const char *_String, + _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix); +# else + _CRTIMP __int64 __cdecl _strtoi64(const char *_String, + char **_EndPtr, int _Radix); +# endif +# define strtooff _strtoi64 +# else + curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base); +# define strtooff curlx_strtoll +# define NEED_CURL_STRTOLL 1 +# endif +# endif +#else +# define strtooff strtol +#endif + #ifdef NEED_CURL_STRTOLL /* Range tests can be used for alphanum decoding if characters are consecutive, @@ -48,11 +73,10 @@ static const char valchars[] = static int get_char(char c, int base); /** - * Emulated version of the strtoll function. This extracts a long long + * Custom version of the strtooff function. This extracts a curl_off_t * value from the given input string and returns it. */ -curl_off_t -curlx_strtoll(const char *nptr, char **endptr, int base) +static curl_off_t strtooff(const char *nptr, char **endptr, int base) { char *end; int is_negative = 0; @@ -186,3 +210,34 @@ static int get_char(char c, int base) return value; } #endif /* Only present if we need strtoll, but don't have it. */ + +/* + * Parse a *positive* up to 64 bit number written in ascii. + */ +CURLofft curlx_strtoofft(const char *str, char **endp, int base, + curl_off_t *num) +{ + char *end; + curl_off_t number; + errno = 0; + *num = 0; /* clear by default */ + while(str && *str && ISSPACE(*str)) + str++; + if('-' == *str) { + if(endp) + *endp = (char *)str; /* didn't actually move */ + return CURL_OFFT_INVAL; /* nothing parsed */ + } + number = strtooff(str, &end, base); + if(endp) + *endp = end; + if(errno == ERANGE) + /* overflow/underflow */ + return CURL_OFFT_FLOW; + else if(str == end) + /* nothing parsed */ + return CURL_OFFT_INVAL; + + *num = number; + return CURL_OFFT_OK; +} |