LCOV - code coverage report
Current view: top level - lib - kstrtox.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 26 128 20.3 %
Date: 2023-08-24 13:40:31 Functions: 3 26 11.5 %

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

Generated by: LCOV version 1.14