15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*************************************************************************** 25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * _ _ ____ _ 35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Project ___| | | | _ \| | 45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * / __| | | | |_) | | 55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * | (__| |_| | _ <| |___ 65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * \___|\___/|_| \_\_____| 75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2011, 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 125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * are also available at http://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 23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h" 24e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "strtoofft.h" 265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * NOTE: 295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we 315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * could use in case strtoll() doesn't exist... See 325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html 335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef NEED_CURL_STRTOLL 365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* Range tests can be used for alphanum decoding if characters are consecutive, 385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen like in ASCII. Else an array is scanned. Determine this condition now. */ 395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25 415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define NO_RANGE_TEST 435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic const char valchars[] = 455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic int get_char(char c, int base); 495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/** 515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Emulated version of the strtoll function. This extracts a long long 525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * value from the given input string and returns it. 535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsencurl_off_t 555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsencurlx_strtoll(const char *nptr, char **endptr, int base) 565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char *end; 585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int is_negative = 0; 595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int overflow; 605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int i; 615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen curl_off_t value = 0; 625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen curl_off_t newval; 635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Skip leading whitespace. */ 655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end = (char *)nptr; 665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen while(ISSPACE(end[0])) { 675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Handle the sign, if any. */ 715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(end[0] == '-') { 725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen is_negative = 1; 735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(end[0] == '+') { 765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(end[0] == '\0') { 795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* We had nothing but perhaps some whitespace -- there was no number. */ 805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(endptr) { 815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *endptr = end; 825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return 0; 845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Handle special beginnings, if present and allowed. */ 875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(end[0] == '0' && end[1] == 'x') { 885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(base == 16 || base == 0) { 895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end += 2; 905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen base = 16; 915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(end[0] == '0') { 945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(base == 8 || base == 0) { 955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen end++; 965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen base = 8; 975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Matching strtol, if the base is 0 and it doesn't look like 1015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * the number is octal or hex, we assume it's base 10. 1025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(base == 0) { 1045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen base = 10; 1055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Loop handling digits. */ 1085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = 0; 1095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen overflow = 0; 110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = get_char(end[0], base); 111e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET i != -1; 112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET end++, i = get_char(end[0], base)) { 1135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen newval = base * value + i; 1145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(newval < value) { 1155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* We've overflowed. */ 1165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen overflow = 1; 1175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 1185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = newval; 1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!overflow) { 1245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(is_negative) { 1255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Fix the sign. */ 1265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value *= -1; 1275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else { 1305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(is_negative) 1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels value = CURL_OFF_T_MIN; 1325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels value = CURL_OFF_T_MAX; 1345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen SET_ERRNO(ERANGE); 1365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(endptr) 1395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *endptr = end; 1405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return value; 1425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 1435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/** 1455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Returns the value of c in the given base, or -1 if c cannot 1465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * be interpreted properly in that base (i.e., is out of range, 1475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * is a null, etc.). 1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * @param c the character to interpret according to base 1505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * @param base the base in which to interpret c 1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * @return the value of c in base, or -1 if c isn't in range 1535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic int get_char(char c, int base) 1555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifndef NO_RANGE_TEST 1575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int value = -1; 1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(c <= '9' && c >= '0') { 1595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = c - '0'; 1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(c <= 'Z' && c >= 'A') { 1625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = c - 'A' + 10; 1635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(c <= 'z' && c >= 'a') { 1655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = c - 'a' + 10; 1665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#else 1685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen const char * cp; 1695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int value; 1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cp = memchr(valchars, c, 10 + 26 + 26); 1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!cp) 1745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return -1; 1755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = cp - valchars; 1775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(value >= 10 + 26) 1795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value -= 26; /* Lowercase. */ 1805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 1815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(value >= base) { 1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen value = -1; 1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return value; 1875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* Only present if we need strtoll, but don't have it. */ 189