Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * Convert integer string representation to an integer.
4 : : * If an integer doesn't fit into specified type, -E is returned.
5 : : *
6 : : * Integer starts with optional sign.
7 : : * kstrtou*() functions do not accept sign "-".
8 : : *
9 : : * Radix 0 means autodetection: leading "0x" implies radix 16,
10 : : * leading "0" implies radix 8, otherwise radix is 10.
11 : : * Autodetection hints work after optional sign, but not before.
12 : : *
13 : : * If -E is returned, result is not touched.
14 : : */
15 : : #include <linux/ctype.h>
16 : : #include <linux/errno.h>
17 : : #include <linux/kernel.h>
18 : : #include <linux/math64.h>
19 : : #include <linux/export.h>
20 : : #include <linux/types.h>
21 : : #include <linux/uaccess.h>
22 : : #include "kstrtox.h"
23 : :
24 : 7921 : const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
25 : : {
26 [ + + ]: 7921 : if (*base == 0) {
27 [ + + ]: 5461 : if (s[0] == '0') {
28 [ - + - - ]: 391 : if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
29 : 0 : *base = 16;
30 : : else
31 : 391 : *base = 8;
32 : : } else
33 : 5070 : *base = 10;
34 : : }
35 [ + + + + : 7921 : if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
- + ]
36 : 0 : s += 2;
37 : 7921 : return s;
38 : : }
39 : :
40 : : /*
41 : : * Convert non-negative integer string representation in explicitly given radix
42 : : * to an integer.
43 : : * Return number of characters consumed maybe or-ed with overflow bit.
44 : : * If overflow occurs, result integer (incorrect) is still returned.
45 : : *
46 : : * Don't you dare use this function.
47 : : */
48 : 7921 : unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
49 : : {
50 : 7921 : unsigned long long res;
51 : 7921 : unsigned int rv;
52 : :
53 : 7921 : res = 0;
54 : 7921 : rv = 0;
55 : 66423 : while (1) {
56 : 37172 : unsigned int c = *s;
57 : 37172 : unsigned int lc = c | 0x20; /* don't tolower() this line */
58 : 37172 : unsigned int val;
59 : :
60 [ + + ]: 37172 : if ('0' <= c && c <= '9')
61 : : val = c - '0';
62 [ + + ]: 8251 : else if ('a' <= lc && lc <= 'f')
63 : 330 : val = lc - 'a' + 10;
64 : : else
65 : : break;
66 : :
67 [ + - ]: 29251 : if (val >= base)
68 : : break;
69 : : /*
70 : : * Check for overflow only if we are within range of
71 : : * it in the max base we support (16)
72 : : */
73 [ - + ]: 29251 : if (unlikely(res & (~0ull << 60))) {
74 [ # # ]: 0 : if (res > div_u64(ULLONG_MAX - val, base))
75 : 0 : rv |= KSTRTOX_OVERFLOW;
76 : : }
77 : 29251 : res = res * base + val;
78 : 29251 : rv++;
79 : 29251 : s++;
80 : : }
81 : 7921 : *p = res;
82 : 7921 : return rv;
83 : : }
84 : :
85 : 4951 : static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
86 : : {
87 : 4951 : unsigned long long _res;
88 : 4951 : unsigned int rv;
89 : :
90 : 4951 : s = _parse_integer_fixup_radix(s, &base);
91 : 4951 : rv = _parse_integer(s, base, &_res);
92 [ + - ]: 4951 : if (rv & KSTRTOX_OVERFLOW)
93 : : return -ERANGE;
94 [ + - ]: 4951 : if (rv == 0)
95 : : return -EINVAL;
96 : 4951 : s += rv;
97 [ + + ]: 4951 : if (*s == '\n')
98 : 30 : s++;
99 [ + - ]: 4951 : if (*s)
100 : : return -EINVAL;
101 : 4951 : *res = _res;
102 : 4951 : return 0;
103 : : }
104 : :
105 : : /**
106 : : * kstrtoull - convert a string to an unsigned long long
107 : : * @s: The start of the string. The string must be null-terminated, and may also
108 : : * include a single newline before its terminating null. The first character
109 : : * may also be a plus sign, but not a minus sign.
110 : : * @base: The number base to use. The maximum supported base is 16. If base is
111 : : * given as 0, then the base of the string is automatically detected with the
112 : : * conventional semantics - If it begins with 0x the number will be parsed as a
113 : : * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
114 : : * parsed as an octal number. Otherwise it will be parsed as a decimal.
115 : : * @res: Where to write the result of the conversion on success.
116 : : *
117 : : * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
118 : : * Used as a replacement for the obsolete simple_strtoull. Return code must
119 : : * be checked.
120 : : */
121 : 4891 : int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
122 : : {
123 [ - - - + ]: 60 : if (s[0] == '+')
124 : 0 : s++;
125 : 4891 : return _kstrtoull(s, base, res);
126 : : }
127 : : EXPORT_SYMBOL(kstrtoull);
128 : :
129 : : /**
130 : : * kstrtoll - convert a string to a long long
131 : : * @s: The start of the string. The string must be null-terminated, and may also
132 : : * include a single newline before its terminating null. The first character
133 : : * may also be a plus sign or a minus sign.
134 : : * @base: The number base to use. The maximum supported base is 16. If base is
135 : : * given as 0, then the base of the string is automatically detected with the
136 : : * conventional semantics - If it begins with 0x the number will be parsed as a
137 : : * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
138 : : * parsed as an octal number. Otherwise it will be parsed as a decimal.
139 : : * @res: Where to write the result of the conversion on success.
140 : : *
141 : : * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
142 : : * Used as a replacement for the obsolete simple_strtoull. Return code must
143 : : * be checked.
144 : : */
145 : 4681 : int kstrtoll(const char *s, unsigned int base, long long *res)
146 : : {
147 : 4681 : unsigned long long tmp;
148 : 4681 : int rv;
149 : :
150 [ + + ]: 4681 : if (s[0] == '-') {
151 : 60 : rv = _kstrtoull(s + 1, base, &tmp);
152 [ + - ]: 60 : if (rv < 0)
153 : : return rv;
154 [ + - ]: 60 : if ((long long)-tmp > 0)
155 : : return -ERANGE;
156 : 60 : *res = -tmp;
157 : : } else {
158 [ - + ]: 4621 : rv = kstrtoull(s, base, &tmp);
159 [ + - ]: 4621 : if (rv < 0)
160 : : return rv;
161 [ + - ]: 4621 : if ((long long)tmp < 0)
162 : : return -ERANGE;
163 : 4621 : *res = tmp;
164 : : }
165 : : return 0;
166 : : }
167 : : EXPORT_SYMBOL(kstrtoll);
168 : :
169 : : /* Internal, do not use. */
170 : 0 : int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
171 : : {
172 : 0 : unsigned long long tmp;
173 : 0 : int rv;
174 : :
175 [ # # ]: 0 : rv = kstrtoull(s, base, &tmp);
176 [ # # ]: 0 : if (rv < 0)
177 : : return rv;
178 : 0 : if (tmp != (unsigned long)tmp)
179 : : return -ERANGE;
180 : 0 : *res = tmp;
181 : 0 : return 0;
182 : : }
183 : : EXPORT_SYMBOL(_kstrtoul);
184 : :
185 : : /* Internal, do not use. */
186 : 0 : int _kstrtol(const char *s, unsigned int base, long *res)
187 : : {
188 : 0 : long long tmp;
189 : 0 : int rv;
190 : :
191 : 0 : rv = kstrtoll(s, base, &tmp);
192 [ # # ]: 0 : if (rv < 0)
193 : : return rv;
194 : 0 : if (tmp != (long)tmp)
195 : : return -ERANGE;
196 : 0 : *res = tmp;
197 : 0 : return 0;
198 : : }
199 : : EXPORT_SYMBOL(_kstrtol);
200 : :
201 : : /**
202 : : * kstrtouint - convert a string to an unsigned int
203 : : * @s: The start of the string. The string must be null-terminated, and may also
204 : : * include a single newline before its terminating null. The first character
205 : : * may also be a plus sign, but not a minus sign.
206 : : * @base: The number base to use. The maximum supported base is 16. If base is
207 : : * given as 0, then the base of the string is automatically detected with the
208 : : * conventional semantics - If it begins with 0x the number will be parsed as a
209 : : * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
210 : : * parsed as an octal number. Otherwise it will be parsed as a decimal.
211 : : * @res: Where to write the result of the conversion on success.
212 : : *
213 : : * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
214 : : * Used as a replacement for the obsolete simple_strtoull. Return code must
215 : : * be checked.
216 : : */
217 : 210 : int kstrtouint(const char *s, unsigned int base, unsigned int *res)
218 : : {
219 : 210 : unsigned long long tmp;
220 : 210 : int rv;
221 : :
222 [ - + ]: 210 : rv = kstrtoull(s, base, &tmp);
223 [ + - ]: 210 : if (rv < 0)
224 : : return rv;
225 [ + - ]: 210 : if (tmp != (unsigned int)tmp)
226 : : return -ERANGE;
227 : 210 : *res = tmp;
228 : 210 : return 0;
229 : : }
230 : : EXPORT_SYMBOL(kstrtouint);
231 : :
232 : : /**
233 : : * kstrtoint - convert a string to an int
234 : : * @s: The start of the string. The string must be null-terminated, and may also
235 : : * include a single newline before its terminating null. The first character
236 : : * may also be a plus sign or a minus sign.
237 : : * @base: The number base to use. The maximum supported base is 16. If base is
238 : : * given as 0, then the base of the string is automatically detected with the
239 : : * conventional semantics - If it begins with 0x the number will be parsed as a
240 : : * hexadecimal (case insensitive), if it otherwise begins with 0, it will be
241 : : * parsed as an octal number. Otherwise it will be parsed as a decimal.
242 : : * @res: Where to write the result of the conversion on success.
243 : : *
244 : : * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
245 : : * Used as a replacement for the obsolete simple_strtoull. Return code must
246 : : * be checked.
247 : : */
248 : 4681 : int kstrtoint(const char *s, unsigned int base, int *res)
249 : : {
250 : 4681 : long long tmp;
251 : 4681 : int rv;
252 : :
253 : 4681 : rv = kstrtoll(s, base, &tmp);
254 [ - - + - ]: 4681 : if (rv < 0)
255 : : return rv;
256 [ - - + - ]: 4681 : if (tmp != (int)tmp)
257 : : return -ERANGE;
258 : 4681 : *res = tmp;
259 : 4681 : return 0;
260 : : }
261 : : EXPORT_SYMBOL(kstrtoint);
262 : :
263 : 0 : int kstrtou16(const char *s, unsigned int base, u16 *res)
264 : : {
265 : 0 : unsigned long long tmp;
266 : 0 : int rv;
267 : :
268 [ # # ]: 0 : rv = kstrtoull(s, base, &tmp);
269 [ # # ]: 0 : if (rv < 0)
270 : : return rv;
271 [ # # ]: 0 : if (tmp != (u16)tmp)
272 : : return -ERANGE;
273 : 0 : *res = tmp;
274 : 0 : return 0;
275 : : }
276 : : EXPORT_SYMBOL(kstrtou16);
277 : :
278 : 0 : int kstrtos16(const char *s, unsigned int base, s16 *res)
279 : : {
280 : 0 : long long tmp;
281 : 0 : int rv;
282 : :
283 : 0 : rv = kstrtoll(s, base, &tmp);
284 [ # # # # ]: 0 : if (rv < 0)
285 : : return rv;
286 [ # # # # ]: 0 : if (tmp != (s16)tmp)
287 : : return -ERANGE;
288 : 0 : *res = tmp;
289 : 0 : return 0;
290 : : }
291 : : EXPORT_SYMBOL(kstrtos16);
292 : :
293 : 0 : int kstrtou8(const char *s, unsigned int base, u8 *res)
294 : : {
295 : 0 : unsigned long long tmp;
296 : 0 : int rv;
297 : :
298 [ # # ]: 0 : rv = kstrtoull(s, base, &tmp);
299 [ # # ]: 0 : if (rv < 0)
300 : : return rv;
301 [ # # ]: 0 : if (tmp != (u8)tmp)
302 : : return -ERANGE;
303 : 0 : *res = tmp;
304 : 0 : return 0;
305 : : }
306 : : EXPORT_SYMBOL(kstrtou8);
307 : :
308 : 0 : int kstrtos8(const char *s, unsigned int base, s8 *res)
309 : : {
310 : 0 : long long tmp;
311 : 0 : int rv;
312 : :
313 : 0 : rv = kstrtoll(s, base, &tmp);
314 [ # # # # ]: 0 : if (rv < 0)
315 : : return rv;
316 [ # # # # ]: 0 : if (tmp != (s8)tmp)
317 : : return -ERANGE;
318 : 0 : *res = tmp;
319 : 0 : return 0;
320 : : }
321 : : EXPORT_SYMBOL(kstrtos8);
322 : :
323 : : /**
324 : : * kstrtobool - convert common user inputs into boolean values
325 : : * @s: input string
326 : : * @res: result
327 : : *
328 : : * This routine returns 0 iff the first character is one of 'Yy1Nn0', or
329 : : * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value
330 : : * pointed to by res is updated upon finding a match.
331 : : */
332 : 0 : int kstrtobool(const char *s, bool *res)
333 : : {
334 [ # # ]: 0 : if (!s)
335 : : return -EINVAL;
336 : :
337 [ # # # # ]: 0 : switch (s[0]) {
338 : 0 : case 'y':
339 : : case 'Y':
340 : : case '1':
341 : 0 : *res = true;
342 : 0 : return 0;
343 : 0 : case 'n':
344 : : case 'N':
345 : : case '0':
346 : 0 : *res = false;
347 : 0 : return 0;
348 : 0 : case 'o':
349 : : case 'O':
350 [ # # # ]: 0 : switch (s[1]) {
351 : 0 : case 'n':
352 : : case 'N':
353 : 0 : *res = true;
354 : 0 : return 0;
355 : 0 : case 'f':
356 : : case 'F':
357 : 0 : *res = false;
358 : 0 : return 0;
359 : : default:
360 : : break;
361 : : }
362 : : default:
363 : : break;
364 : : }
365 : :
366 : : return -EINVAL;
367 : : }
368 : : EXPORT_SYMBOL(kstrtobool);
369 : :
370 : : /*
371 : : * Since "base" would be a nonsense argument, this open-codes the
372 : : * _from_user helper instead of using the helper macro below.
373 : : */
374 : 0 : int kstrtobool_from_user(const char __user *s, size_t count, bool *res)
375 : : {
376 : : /* Longest string needed to differentiate, newline, terminator */
377 : 0 : char buf[4];
378 : :
379 : 0 : count = min(count, sizeof(buf) - 1);
380 [ # # ]: 0 : if (copy_from_user(buf, s, count))
381 : : return -EFAULT;
382 : 0 : buf[count] = '\0';
383 : 0 : return kstrtobool(buf, res);
384 : : }
385 : : EXPORT_SYMBOL(kstrtobool_from_user);
386 : :
387 : : #define kstrto_from_user(f, g, type) \
388 : : int f(const char __user *s, size_t count, unsigned int base, type *res) \
389 : : { \
390 : : /* sign, base 2 representation, newline, terminator */ \
391 : : char buf[1 + sizeof(type) * 8 + 1 + 1]; \
392 : : \
393 : : count = min(count, sizeof(buf) - 1); \
394 : : if (copy_from_user(buf, s, count)) \
395 : : return -EFAULT; \
396 : : buf[count] = '\0'; \
397 : : return g(buf, base, res); \
398 : : } \
399 : : EXPORT_SYMBOL(f)
400 : :
401 [ # # # # ]: 0 : kstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long);
402 [ # # ]: 0 : kstrto_from_user(kstrtoll_from_user, kstrtoll, long long);
403 [ # # # # ]: 0 : kstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long);
404 [ # # ]: 0 : kstrto_from_user(kstrtol_from_user, kstrtol, long);
405 [ # # ]: 0 : kstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int);
406 [ # # ]: 0 : kstrto_from_user(kstrtoint_from_user, kstrtoint, int);
407 [ # # ]: 0 : kstrto_from_user(kstrtou16_from_user, kstrtou16, u16);
408 [ # # ]: 0 : kstrto_from_user(kstrtos16_from_user, kstrtos16, s16);
409 [ # # ]: 0 : kstrto_from_user(kstrtou8_from_user, kstrtou8, u8);
410 [ # # ]: 0 : kstrto_from_user(kstrtos8_from_user, kstrtos8, s8);
|