root/lib/kstrtox.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _parse_integer_fixup_radix
  2. _parse_integer
  3. _kstrtoull
  4. kstrtoull
  5. kstrtoll
  6. _kstrtoul
  7. _kstrtol
  8. kstrtouint
  9. kstrtoint
  10. kstrtou16
  11. kstrtos16
  12. kstrtou8
  13. kstrtos8
  14. kstrtobool
  15. kstrtobool_from_user

   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 const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
  25 {
  26         if (*base == 0) {
  27                 if (s[0] == '0') {
  28                         if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
  29                                 *base = 16;
  30                         else
  31                                 *base = 8;
  32                 } else
  33                         *base = 10;
  34         }
  35         if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
  36                 s += 2;
  37         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 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                 unsigned int c = *s;
  57                 unsigned int lc = c | 0x20; /* don't tolower() this line */
  58                 unsigned int val;
  59 
  60                 if ('0' <= c && c <= '9')
  61                         val = c - '0';
  62                 else if ('a' <= lc && lc <= 'f')
  63                         val = lc - 'a' + 10;
  64                 else
  65                         break;
  66 
  67                 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                 if (unlikely(res & (~0ull << 60))) {
  74                         if (res > div_u64(ULLONG_MAX - val, base))
  75                                 rv |= KSTRTOX_OVERFLOW;
  76                 }
  77                 res = res * base + val;
  78                 rv++;
  79                 s++;
  80         }
  81         *p = res;
  82         return rv;
  83 }
  84 
  85 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         s = _parse_integer_fixup_radix(s, &base);
  91         rv = _parse_integer(s, base, &_res);
  92         if (rv & KSTRTOX_OVERFLOW)
  93                 return -ERANGE;
  94         if (rv == 0)
  95                 return -EINVAL;
  96         s += rv;
  97         if (*s == '\n')
  98                 s++;
  99         if (*s)
 100                 return -EINVAL;
 101         *res = _res;
 102         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 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
 122 {
 123         if (s[0] == '+')
 124                 s++;
 125         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 int kstrtoll(const char *s, unsigned int base, long long *res)
 146 {
 147         unsigned long long tmp;
 148         int rv;
 149 
 150         if (s[0] == '-') {
 151                 rv = _kstrtoull(s + 1, base, &tmp);
 152                 if (rv < 0)
 153                         return rv;
 154                 if ((long long)-tmp > 0)
 155                         return -ERANGE;
 156                 *res = -tmp;
 157         } else {
 158                 rv = kstrtoull(s, base, &tmp);
 159                 if (rv < 0)
 160                         return rv;
 161                 if ((long long)tmp < 0)
 162                         return -ERANGE;
 163                 *res = tmp;
 164         }
 165         return 0;
 166 }
 167 EXPORT_SYMBOL(kstrtoll);
 168 
 169 /* Internal, do not use. */
 170 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         if (rv < 0)
 177                 return rv;
 178         if (tmp != (unsigned long)tmp)
 179                 return -ERANGE;
 180         *res = tmp;
 181         return 0;
 182 }
 183 EXPORT_SYMBOL(_kstrtoul);
 184 
 185 /* Internal, do not use. */
 186 int _kstrtol(const char *s, unsigned int base, long *res)
 187 {
 188         long long tmp;
 189         int rv;
 190 
 191         rv = kstrtoll(s, base, &tmp);
 192         if (rv < 0)
 193                 return rv;
 194         if (tmp != (long)tmp)
 195                 return -ERANGE;
 196         *res = tmp;
 197         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 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         if (rv < 0)
 224                 return rv;
 225         if (tmp != (unsigned int)tmp)
 226                 return -ERANGE;
 227         *res = tmp;
 228         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 int kstrtoint(const char *s, unsigned int base, int *res)
 249 {
 250         long long tmp;
 251         int rv;
 252 
 253         rv = kstrtoll(s, base, &tmp);
 254         if (rv < 0)
 255                 return rv;
 256         if (tmp != (int)tmp)
 257                 return -ERANGE;
 258         *res = tmp;
 259         return 0;
 260 }
 261 EXPORT_SYMBOL(kstrtoint);
 262 
 263 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         if (rv < 0)
 270                 return rv;
 271         if (tmp != (u16)tmp)
 272                 return -ERANGE;
 273         *res = tmp;
 274         return 0;
 275 }
 276 EXPORT_SYMBOL(kstrtou16);
 277 
 278 int kstrtos16(const char *s, unsigned int base, s16 *res)
 279 {
 280         long long tmp;
 281         int rv;
 282 
 283         rv = kstrtoll(s, base, &tmp);
 284         if (rv < 0)
 285                 return rv;
 286         if (tmp != (s16)tmp)
 287                 return -ERANGE;
 288         *res = tmp;
 289         return 0;
 290 }
 291 EXPORT_SYMBOL(kstrtos16);
 292 
 293 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         if (rv < 0)
 300                 return rv;
 301         if (tmp != (u8)tmp)
 302                 return -ERANGE;
 303         *res = tmp;
 304         return 0;
 305 }
 306 EXPORT_SYMBOL(kstrtou8);
 307 
 308 int kstrtos8(const char *s, unsigned int base, s8 *res)
 309 {
 310         long long tmp;
 311         int rv;
 312 
 313         rv = kstrtoll(s, base, &tmp);
 314         if (rv < 0)
 315                 return rv;
 316         if (tmp != (s8)tmp)
 317                 return -ERANGE;
 318         *res = tmp;
 319         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 int kstrtobool(const char *s, bool *res)
 333 {
 334         if (!s)
 335                 return -EINVAL;
 336 
 337         switch (s[0]) {
 338         case 'y':
 339         case 'Y':
 340         case '1':
 341                 *res = true;
 342                 return 0;
 343         case 'n':
 344         case 'N':
 345         case '0':
 346                 *res = false;
 347                 return 0;
 348         case 'o':
 349         case 'O':
 350                 switch (s[1]) {
 351                 case 'n':
 352                 case 'N':
 353                         *res = true;
 354                         return 0;
 355                 case 'f':
 356                 case 'F':
 357                         *res = false;
 358                         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 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         count = min(count, sizeof(buf) - 1);
 380         if (copy_from_user(buf, s, count))
 381                 return -EFAULT;
 382         buf[count] = '\0';
 383         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 kstrto_from_user(kstrtoull_from_user,   kstrtoull,      unsigned long long);
 402 kstrto_from_user(kstrtoll_from_user,    kstrtoll,       long long);
 403 kstrto_from_user(kstrtoul_from_user,    kstrtoul,       unsigned long);
 404 kstrto_from_user(kstrtol_from_user,     kstrtol,        long);
 405 kstrto_from_user(kstrtouint_from_user,  kstrtouint,     unsigned int);
 406 kstrto_from_user(kstrtoint_from_user,   kstrtoint,      int);
 407 kstrto_from_user(kstrtou16_from_user,   kstrtou16,      u16);
 408 kstrto_from_user(kstrtos16_from_user,   kstrtos16,      s16);
 409 kstrto_from_user(kstrtou8_from_user,    kstrtou8,       u8);
 410 kstrto_from_user(kstrtos8_from_user,    kstrtos8,       s8);

/* [<][>][^][v][top][bottom][index][help] */