LCOV - code coverage report
Current view: top level - lib - kstrtox.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 56 103 54.4 %
Date: 2015-04-12 14:34:49 Functions: 6 23 26.1 %

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

Generated by: LCOV version 1.11