VirtualBox

source: vbox/trunk/src/libs/curl-8.7.1/lib/strtoofft.c@ 106542

最後變更 在這個檔案從106542是 104083,由 vboxsync 提交於 11 月 前

curl-8.7.1: Applied and adjusted our curl changes to 8.4.0. bugref:10639

  • 屬性 svn:eol-style 設為 native
檔案大小: 5.7 KB
 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25#include <errno.h>
26#include "curl_setup.h"
27
28#include "strtoofft.h"
29
30/*
31 * NOTE:
32 *
33 * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
34 * could use in case strtoll() doesn't exist... See
35 * https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
36 */
37
38#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG)
39# ifdef HAVE_STRTOLL
40# define strtooff strtoll
41# else
42# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
43# if defined(_SAL_VERSION)
44 _Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
45 _In_z_ const char *_String,
46 _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
47# else
48 _CRTIMP __int64 __cdecl _strtoi64(const char *_String,
49 char **_EndPtr, int _Radix);
50# endif
51# define strtooff _strtoi64
52# else
53# define PRIVATE_STRTOOFF 1
54# endif
55# endif
56#else
57# define strtooff strtol
58#endif
59
60#ifdef PRIVATE_STRTOOFF
61
62/* Range tests can be used for alphanum decoding if characters are consecutive,
63 like in ASCII. Else an array is scanned. Determine this condition now. */
64
65#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25
66
67#define NO_RANGE_TEST
68
69static const char valchars[] =
70 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
71#endif
72
73static int get_char(char c, int base);
74
75/**
76 * Custom version of the strtooff function. This extracts a curl_off_t
77 * value from the given input string and returns it.
78 */
79static curl_off_t strtooff(const char *nptr, char **endptr, int base)
80{
81 char *end;
82 bool is_negative = FALSE;
83 bool overflow = FALSE;
84 int i;
85 curl_off_t value = 0;
86
87 /* Skip leading whitespace. */
88 end = (char *)nptr;
89 while(ISBLANK(end[0])) {
90 end++;
91 }
92
93 /* Handle the sign, if any. */
94 if(end[0] == '-') {
95 is_negative = TRUE;
96 end++;
97 }
98 else if(end[0] == '+') {
99 end++;
100 }
101 else if(end[0] == '\0') {
102 /* We had nothing but perhaps some whitespace -- there was no number. */
103 if(endptr) {
104 *endptr = end;
105 }
106 return 0;
107 }
108
109 /* Handle special beginnings, if present and allowed. */
110 if(end[0] == '0' && end[1] == 'x') {
111 if(base == 16 || base == 0) {
112 end += 2;
113 base = 16;
114 }
115 }
116 else if(end[0] == '0') {
117 if(base == 8 || base == 0) {
118 end++;
119 base = 8;
120 }
121 }
122
123 /* Matching strtol, if the base is 0 and it doesn't look like
124 * the number is octal or hex, we assume it's base 10.
125 */
126 if(base == 0) {
127 base = 10;
128 }
129
130 /* Loop handling digits. */
131 for(i = get_char(end[0], base);
132 i != -1;
133 end++, i = get_char(end[0], base)) {
134
135 if(value > (CURL_OFF_T_MAX - i) / base) {
136 overflow = TRUE;
137 break;
138 }
139 value = base * value + i;
140 }
141
142 if(!overflow) {
143 if(is_negative) {
144 /* Fix the sign. */
145 value *= -1;
146 }
147 }
148 else {
149 if(is_negative)
150 value = CURL_OFF_T_MIN;
151 else
152 value = CURL_OFF_T_MAX;
153
154 errno = ERANGE;
155 }
156
157 if(endptr)
158 *endptr = end;
159
160 return value;
161}
162
163/**
164 * Returns the value of c in the given base, or -1 if c cannot
165 * be interpreted properly in that base (i.e., is out of range,
166 * is a null, etc.).
167 *
168 * @param c the character to interpret according to base
169 * @param base the base in which to interpret c
170 *
171 * @return the value of c in base, or -1 if c isn't in range
172 */
173static int get_char(char c, int base)
174{
175#ifndef NO_RANGE_TEST
176 int value = -1;
177 if(c <= '9' && c >= '0') {
178 value = c - '0';
179 }
180 else if(c <= 'Z' && c >= 'A') {
181 value = c - 'A' + 10;
182 }
183 else if(c <= 'z' && c >= 'a') {
184 value = c - 'a' + 10;
185 }
186#else
187 const char *cp;
188 int value;
189
190 cp = memchr(valchars, c, 10 + 26 + 26);
191
192 if(!cp)
193 return -1;
194
195 value = cp - valchars;
196
197 if(value >= 10 + 26)
198 value -= 26; /* Lowercase. */
199#endif
200
201 if(value >= base) {
202 value = -1;
203 }
204
205 return value;
206}
207#endif /* Only present if we need strtoll, but don't have it. */
208
209/*
210 * Parse a *positive* up to 64 bit number written in ascii.
211 */
212CURLofft curlx_strtoofft(const char *str, char **endp, int base,
213 curl_off_t *num)
214{
215 char *end = NULL;
216 curl_off_t number;
217 errno = 0;
218 *num = 0; /* clear by default */
219 DEBUGASSERT(base); /* starting now, avoid base zero */
220
221 while(*str && ISBLANK(*str))
222 str++;
223 if(('-' == *str) || (ISSPACE(*str))) {
224 if(endp)
225 *endp = (char *)str; /* didn't actually move */
226 return CURL_OFFT_INVAL; /* nothing parsed */
227 }
228 number = strtooff(str, &end, base);
229 if(endp)
230 *endp = end;
231 if(errno == ERANGE)
232 /* overflow/underflow */
233 return CURL_OFFT_FLOW;
234 else if(str == end)
235 /* nothing parsed */
236 return CURL_OFFT_INVAL;
237
238 *num = number;
239 return CURL_OFFT_OK;
240}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette