diff options
Diffstat (limited to 'libs/libcurl/src/strtoofft.c')
-rw-r--r-- | libs/libcurl/src/strtoofft.c | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/libs/libcurl/src/strtoofft.c b/libs/libcurl/src/strtoofft.c index 03a97e8c4d..363647737f 100644 --- a/libs/libcurl/src/strtoofft.c +++ b/libs/libcurl/src/strtoofft.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, 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 - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -20,6 +20,7 @@ * ***************************************************************************/ +#include <errno.h> #include "curl_setup.h" #include "strtoofft.h" @@ -29,10 +30,32 @@ * * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we * could use in case strtoll() doesn't exist... See - * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html + * https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html */ -#ifdef NEED_CURL_STRTOLL +#if (SIZEOF_CURL_OFF_T > 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 +# define PRIVATE_STRTOOFF 1 +# endif +# endif +#else +# define strtooff strtol +#endif + +#ifdef PRIVATE_STRTOOFF /* Range tests can be used for alphanum decoding if characters are consecutive, like in ASCII. Else an array is scanned. Determine this condition now. */ @@ -48,11 +71,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; @@ -132,7 +154,7 @@ curlx_strtoll(const char *nptr, char **endptr, int base) else value = CURL_OFF_T_MAX; - SET_ERRNO(ERANGE); + errno = ERANGE; } if(endptr) @@ -165,7 +187,7 @@ static int get_char(char c, int base) value = c - 'a' + 10; } #else - const char * cp; + const char *cp; int value; cp = memchr(valchars, c, 10 + 26 + 26); @@ -186,3 +208,37 @@ 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 */ + + DEBUGASSERT(str); + + while(*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; +} |