15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*************************************************************************** 25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * _ _ ____ _ 35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Project ___| | | | _ \| | 45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * / __| | | | |_) | | 55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * | (__| |_| | _ <| |___ 65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * \___|\___/|_| \_\_____| 75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 8486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. 95ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is licensed as described in the file COPYING, which 115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * you should have received as part of this distribution. The terms 128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * You may opt to use, copy, modify, merge, publish, distribute and/or sell 155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * copies of the Software, and permit persons to whom the Software is 165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * furnished to do so, under the terms of the COPYING file. 175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * KIND, either express or implied. 205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen ***************************************************************************/ 225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 23486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#include <errno.h> 24e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h" 25e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "strtoofft.h" 275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * NOTE: 305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we 325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * could use in case strtoll() doesn't exist... See 3382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html 345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 36486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG) 37486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# ifdef HAVE_STRTOLL 38486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# define strtooff strtoll 39486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# else 40486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64) 41486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# if defined(_SAL_VERSION) 42486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo _Check_return_ _CRTIMP __int64 __cdecl _strtoi64( 43486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo _In_z_ const char *_String, 44486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix); 45486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# else 46486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo _CRTIMP __int64 __cdecl _strtoi64(const char *_String, 47486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo char **_EndPtr, int _Radix); 48486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# endif 49486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# define strtooff _strtoi64 50486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# else 51486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# define PRIVATE_STRTOOFF 1 52486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# endif 53486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# endif 54486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#else 55486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo# define strtooff strtol 56486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#endif 57486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo 58486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo#ifdef PRIVATE_STRTOOFF 595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* Range tests can be used for alphanum decoding if characters are consecutive, 615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen like in ASCII. Else an array is scanned. Determine this condition now. */ 625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25 645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define NO_RANGE_TEST 665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic const char valchars[] = 685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic int get_char(char c, int base); 725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/** 74486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * Custom version of the strtooff function. This extracts a curl_off_t 755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * value from the given input string and returns it. 765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 77486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymostatic curl_off_t strtooff(const char *nptr, char **endptr, int base) 785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char *end; 805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int is_negative = 0; 815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int overflow; 825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int i; 835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen curl_off_t value = 0; 845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen curl_off_t newval; 855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Skip leading whitespace. */ 875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end = (char *)nptr; 885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen while(ISSPACE(end[0])) { 895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Handle the sign, if any. */ 935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(end[0] == '-') { 945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen is_negative = 1; 955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(end[0] == '+') { 985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(end[0] == '\0') { 1015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* We had nothing but perhaps some whitespace -- there was no number. */ 1025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(endptr) { 1035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *endptr = end; 1045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return 0; 1065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Handle special beginnings, if present and allowed. */ 1095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(end[0] == '0' && end[1] == 'x') { 1105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(base == 16 || base == 0) { 1115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end += 2; 1125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen base = 16; 1135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(end[0] == '0') { 1165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(base == 8 || base == 0) { 1175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 1185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen base = 8; 1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Matching strtol, if the base is 0 and it doesn't look like 1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * the number is octal or hex, we assume it's base 10. 1245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(base == 0) { 1265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen base = 10; 1275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Loop handling digits. */ 1305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = 0; 1315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen overflow = 0; 132e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = get_char(end[0], base); 133e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET i != -1; 134e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET end++, i = get_char(end[0], base)) { 1355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen newval = base * value + i; 1365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(newval < value) { 1375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* We've overflowed. */ 1385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen overflow = 1; 1395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 1405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 1425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = newval; 1435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!overflow) { 1465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(is_negative) { 1475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Fix the sign. */ 1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value *= -1; 1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else { 1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(is_negative) 1539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels value = CURL_OFF_T_MIN; 1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 1559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels value = CURL_OFF_T_MAX; 1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 15782be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes errno = ERANGE; 1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(endptr) 1615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *endptr = end; 1625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return value; 1645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 1655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/** 1675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Returns the value of c in the given base, or -1 if c cannot 1685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * be interpreted properly in that base (i.e., is out of range, 1695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * is a null, etc.). 1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 1715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * @param c the character to interpret according to base 1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * @param base the base in which to interpret c 1735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 1745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * @return the value of c in base, or -1 if c isn't in range 1755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic int get_char(char c, int base) 1775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 1785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifndef NO_RANGE_TEST 1795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int value = -1; 1805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(c <= '9' && c >= '0') { 1815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = c - '0'; 1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(c <= 'Z' && c >= 'A') { 1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = c - 'A' + 10; 1855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(c <= 'z' && c >= 'a') { 1875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = c - 'a' + 10; 1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#else 190cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes const char *cp; 1915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int value; 1925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cp = memchr(valchars, c, 10 + 26 + 26); 1945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!cp) 1965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return -1; 1975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = cp - valchars; 1995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(value >= 10 + 26) 2015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value -= 26; /* Lowercase. */ 2025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 2035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(value >= base) { 2055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = -1; 2065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return value; 2095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 2105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* Only present if we need strtoll, but don't have it. */ 211486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo 212486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo/* 213486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo * Parse a *positive* up to 64 bit number written in ascii. 214486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo */ 215486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex DeymoCURLofft curlx_strtoofft(const char *str, char **endp, int base, 216486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo curl_off_t *num) 217486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo{ 218486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo char *end; 219486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo curl_off_t number; 220486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo errno = 0; 221486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo *num = 0; /* clear by default */ 222486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo 223486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo DEBUGASSERT(str); 224486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo 225486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo while(*str && ISSPACE(*str)) 226486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo str++; 227486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo if('-' == *str) { 228486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo if(endp) 229486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo *endp = (char *)str; /* didn't actually move */ 230486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo return CURL_OFFT_INVAL; /* nothing parsed */ 231486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo } 232486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo number = strtooff(str, &end, base); 233486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo if(endp) 234486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo *endp = end; 235486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo if(errno == ERANGE) 236486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo /* overflow/underflow */ 237486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo return CURL_OFFT_FLOW; 238486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo else if(str == end) 239486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo /* nothing parsed */ 240486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo return CURL_OFFT_INVAL; 241486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo 242486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo *num = number; 243486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo return CURL_OFFT_OK; 244486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo} 245