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 : 161635 : const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
25 : : {
26 [ + + ]: 161635 : if (*base == 0) {
27 [ + + ]: 133425 : if (s[0] == '0') {
28 [ + + + - ]: 6672 : if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
29 : 414 : *base = 16;
30 : : else
31 : 2922 : *base = 8;
32 : : } else
33 : 130089 : *base = 10;
34 : : }
35 [ + + + + : 171364 : if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
+ + ]
36 : 414 : s += 2;
37 : 161635 : 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 : 161630 : unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
49 : : {
50 : : unsigned long long res;
51 : : unsigned int rv;
52 : :
53 : : res = 0;
54 : : rv = 0;
55 : : while (1) {
56 : 674533 : unsigned int c = *s;
57 : 674533 : unsigned int lc = c | 0x20; /* don't tolower() this line */
58 : : unsigned int val;
59 : :
60 [ + + ]: 674533 : if ('0' <= c && c <= '9')
61 : : val = c - '0';
62 [ + + ]: 164939 : else if ('a' <= lc && lc <= 'f')
63 : 3312 : val = lc - 'a' + 10;
64 : : else
65 : : break;
66 : :
67 [ + + ]: 512906 : 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 [ - + ]: 512903 : if (unlikely(res & (~0ull << 60))) {
74 [ # # ]: 0 : if (res > div_u64(ULLONG_MAX - val, base))
75 : 0 : rv |= KSTRTOX_OVERFLOW;
76 : : }
77 : 512903 : res = res * base + val;
78 : 512903 : rv++;
79 : 512903 : s++;
80 : 512903 : }
81 : 161630 : *p = res;
82 : 161630 : return rv;
83 : : }
84 : :
85 : 142590 : static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
86 : : {
87 : : unsigned long long _res;
88 : : unsigned int rv;
89 : :
90 : 142590 : s = _parse_integer_fixup_radix(s, &base);
91 : 142589 : rv = _parse_integer(s, base, &_res);
92 [ + + ]: 142588 : if (rv & KSTRTOX_OVERFLOW)
93 : : return -ERANGE;
94 [ + + ]: 142587 : if (rv == 0)
95 : : return -EINVAL;
96 : 138201 : s += rv;
97 [ - + ]: 138201 : if (*s == '\n')
98 : 0 : s++;
99 [ + - ]: 138201 : if (*s)
100 : : return -EINVAL;
101 : 138241 : *res = _res;
102 : 138241 : 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 : 0 : int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
122 : : {
123 [ # # # # : 142177 : if (s[0] == '+')
# # - + -
+ - + #
# ]
124 : 0 : s++;
125 : 142177 : 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 : 134055 : int kstrtoll(const char *s, unsigned int base, long long *res)
146 : : {
147 : : unsigned long long tmp;
148 : : int rv;
149 : :
150 [ + + ]: 134055 : if (s[0] == '-') {
151 : 414 : rv = _kstrtoull(s + 1, base, &tmp);
152 [ + - ]: 414 : if (rv < 0)
153 : : return rv;
154 [ + - ]: 414 : if ((long long)-tmp > 0)
155 : : return -ERANGE;
156 : 414 : *res = -tmp;
157 : : } else {
158 : : rv = kstrtoull(s, base, &tmp);
159 [ + + ]: 133636 : if (rv < 0)
160 : : return rv;
161 [ + - ]: 129291 : if ((long long)tmp < 0)
162 : : return -ERANGE;
163 : 129292 : *res = tmp;
164 : : }
165 : : return 0;
166 : : }
167 : : EXPORT_SYMBOL(kstrtoll);
168 : :
169 : : /* Internal, do not use. */
170 : 207 : int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
171 : : {
172 : : unsigned long long tmp;
173 : : int rv;
174 : :
175 : : rv = kstrtoull(s, base, &tmp);
176 [ + - ]: 207 : if (rv < 0)
177 : : return rv;
178 [ + - ]: 207 : if (tmp != (unsigned long)tmp)
179 : : return -ERANGE;
180 : 207 : *res = tmp;
181 : 207 : 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 : : long long tmp;
189 : : 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 : 8329 : int kstrtouint(const char *s, unsigned int base, unsigned int *res)
218 : : {
219 : : unsigned long long tmp;
220 : : int rv;
221 : :
222 : : rv = kstrtoull(s, base, &tmp);
223 [ + - ]: 8329 : if (rv < 0)
224 : : return rv;
225 [ + - ]: 8329 : if (tmp != (unsigned int)tmp)
226 : : return -ERANGE;
227 : 8329 : *res = tmp;
228 : 8329 : 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 : 122458 : int kstrtoint(const char *s, unsigned int base, int *res)
249 : : {
250 : : long long tmp;
251 : : int rv;
252 : :
253 : 122458 : rv = kstrtoll(s, base, &tmp);
254 [ + + ]: 122447 : if (rv < 0)
255 : : return rv;
256 [ + + ]: 118107 : if (tmp != (int)tmp)
257 : : return -ERANGE;
258 : 118101 : *res = tmp;
259 : 118101 : return 0;
260 : : }
261 : : EXPORT_SYMBOL(kstrtoint);
262 : :
263 : 0 : int kstrtou16(const char *s, unsigned int base, u16 *res)
264 : : {
265 : : unsigned long long tmp;
266 : : int rv;
267 : :
268 : : 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 : : long long tmp;
281 : : 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 : : unsigned long long tmp;
296 : : int rv;
297 : :
298 : : 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 : : long long tmp;
311 : : 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 : 621 : int kstrtobool(const char *s, bool *res)
333 : : {
334 [ + - ]: 621 : if (!s)
335 : : return -EINVAL;
336 : :
337 [ + + - - ]: 621 : switch (s[0]) {
338 : : case 'y':
339 : : case 'Y':
340 : : case '1':
341 : 414 : *res = true;
342 : 414 : return 0;
343 : : case 'n':
344 : : case 'N':
345 : : case '0':
346 : 207 : *res = false;
347 : 207 : return 0;
348 : : case 'o':
349 : : case 'O':
350 [ # # # ]: 0 : switch (s[1]) {
351 : : case 'n':
352 : : case 'N':
353 : 0 : *res = true;
354 : 0 : return 0;
355 : : 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 : : 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 [ + - ]: 1674 : 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);
|