Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Convert integer string representation to an integer.
0004  * If an integer doesn't fit into specified type, -E is returned.
0005  *
0006  * Integer starts with optional sign.
0007  * kstrtou*() functions do not accept sign "-".
0008  *
0009  * Radix 0 means autodetection: leading "0x" implies radix 16,
0010  * leading "0" implies radix 8, otherwise radix is 10.
0011  * Autodetection hints work after optional sign, but not before.
0012  *
0013  * If -E is returned, result is not touched.
0014  */
0015 #include <linux/ctype.h>
0016 #include <linux/errno.h>
0017 #include <linux/export.h>
0018 #include <linux/kstrtox.h>
0019 #include <linux/math64.h>
0020 #include <linux/types.h>
0021 #include <linux/uaccess.h>
0022 
0023 #include "kstrtox.h"
0024 
0025 noinline
0026 const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
0027 {
0028     if (*base == 0) {
0029         if (s[0] == '0') {
0030             if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
0031                 *base = 16;
0032             else
0033                 *base = 8;
0034         } else
0035             *base = 10;
0036     }
0037     if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
0038         s += 2;
0039     return s;
0040 }
0041 
0042 /*
0043  * Convert non-negative integer string representation in explicitly given radix
0044  * to an integer. A maximum of max_chars characters will be converted.
0045  *
0046  * Return number of characters consumed maybe or-ed with overflow bit.
0047  * If overflow occurs, result integer (incorrect) is still returned.
0048  *
0049  * Don't you dare use this function.
0050  */
0051 noinline
0052 unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p,
0053                   size_t max_chars)
0054 {
0055     unsigned long long res;
0056     unsigned int rv;
0057 
0058     res = 0;
0059     rv = 0;
0060     while (max_chars--) {
0061         unsigned int c = *s;
0062         unsigned int lc = c | 0x20; /* don't tolower() this line */
0063         unsigned int val;
0064 
0065         if ('0' <= c && c <= '9')
0066             val = c - '0';
0067         else if ('a' <= lc && lc <= 'f')
0068             val = lc - 'a' + 10;
0069         else
0070             break;
0071 
0072         if (val >= base)
0073             break;
0074         /*
0075          * Check for overflow only if we are within range of
0076          * it in the max base we support (16)
0077          */
0078         if (unlikely(res & (~0ull << 60))) {
0079             if (res > div_u64(ULLONG_MAX - val, base))
0080                 rv |= KSTRTOX_OVERFLOW;
0081         }
0082         res = res * base + val;
0083         rv++;
0084         s++;
0085     }
0086     *p = res;
0087     return rv;
0088 }
0089 
0090 noinline
0091 unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
0092 {
0093     return _parse_integer_limit(s, base, p, INT_MAX);
0094 }
0095 
0096 static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
0097 {
0098     unsigned long long _res;
0099     unsigned int rv;
0100 
0101     s = _parse_integer_fixup_radix(s, &base);
0102     rv = _parse_integer(s, base, &_res);
0103     if (rv & KSTRTOX_OVERFLOW)
0104         return -ERANGE;
0105     if (rv == 0)
0106         return -EINVAL;
0107     s += rv;
0108     if (*s == '\n')
0109         s++;
0110     if (*s)
0111         return -EINVAL;
0112     *res = _res;
0113     return 0;
0114 }
0115 
0116 /**
0117  * kstrtoull - convert a string to an unsigned long long
0118  * @s: The start of the string. The string must be null-terminated, and may also
0119  *  include a single newline before its terminating null. The first character
0120  *  may also be a plus sign, but not a minus sign.
0121  * @base: The number base to use. The maximum supported base is 16. If base is
0122  *  given as 0, then the base of the string is automatically detected with the
0123  *  conventional semantics - If it begins with 0x the number will be parsed as a
0124  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
0125  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
0126  * @res: Where to write the result of the conversion on success.
0127  *
0128  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
0129  * Preferred over simple_strtoull(). Return code must be checked.
0130  */
0131 noinline
0132 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
0133 {
0134     if (s[0] == '+')
0135         s++;
0136     return _kstrtoull(s, base, res);
0137 }
0138 EXPORT_SYMBOL(kstrtoull);
0139 
0140 /**
0141  * kstrtoll - convert a string to a long long
0142  * @s: The start of the string. The string must be null-terminated, and may also
0143  *  include a single newline before its terminating null. The first character
0144  *  may also be a plus sign or a minus sign.
0145  * @base: The number base to use. The maximum supported base is 16. If base is
0146  *  given as 0, then the base of the string is automatically detected with the
0147  *  conventional semantics - If it begins with 0x the number will be parsed as a
0148  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
0149  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
0150  * @res: Where to write the result of the conversion on success.
0151  *
0152  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
0153  * Preferred over simple_strtoll(). Return code must be checked.
0154  */
0155 noinline
0156 int kstrtoll(const char *s, unsigned int base, long long *res)
0157 {
0158     unsigned long long tmp;
0159     int rv;
0160 
0161     if (s[0] == '-') {
0162         rv = _kstrtoull(s + 1, base, &tmp);
0163         if (rv < 0)
0164             return rv;
0165         if ((long long)-tmp > 0)
0166             return -ERANGE;
0167         *res = -tmp;
0168     } else {
0169         rv = kstrtoull(s, base, &tmp);
0170         if (rv < 0)
0171             return rv;
0172         if ((long long)tmp < 0)
0173             return -ERANGE;
0174         *res = tmp;
0175     }
0176     return 0;
0177 }
0178 EXPORT_SYMBOL(kstrtoll);
0179 
0180 /* Internal, do not use. */
0181 int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
0182 {
0183     unsigned long long tmp;
0184     int rv;
0185 
0186     rv = kstrtoull(s, base, &tmp);
0187     if (rv < 0)
0188         return rv;
0189     if (tmp != (unsigned long)tmp)
0190         return -ERANGE;
0191     *res = tmp;
0192     return 0;
0193 }
0194 EXPORT_SYMBOL(_kstrtoul);
0195 
0196 /* Internal, do not use. */
0197 int _kstrtol(const char *s, unsigned int base, long *res)
0198 {
0199     long long tmp;
0200     int rv;
0201 
0202     rv = kstrtoll(s, base, &tmp);
0203     if (rv < 0)
0204         return rv;
0205     if (tmp != (long)tmp)
0206         return -ERANGE;
0207     *res = tmp;
0208     return 0;
0209 }
0210 EXPORT_SYMBOL(_kstrtol);
0211 
0212 /**
0213  * kstrtouint - convert a string to an unsigned int
0214  * @s: The start of the string. The string must be null-terminated, and may also
0215  *  include a single newline before its terminating null. The first character
0216  *  may also be a plus sign, but not a minus sign.
0217  * @base: The number base to use. The maximum supported base is 16. If base is
0218  *  given as 0, then the base of the string is automatically detected with the
0219  *  conventional semantics - If it begins with 0x the number will be parsed as a
0220  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
0221  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
0222  * @res: Where to write the result of the conversion on success.
0223  *
0224  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
0225  * Preferred over simple_strtoul(). Return code must be checked.
0226  */
0227 noinline
0228 int kstrtouint(const char *s, unsigned int base, unsigned int *res)
0229 {
0230     unsigned long long tmp;
0231     int rv;
0232 
0233     rv = kstrtoull(s, base, &tmp);
0234     if (rv < 0)
0235         return rv;
0236     if (tmp != (unsigned int)tmp)
0237         return -ERANGE;
0238     *res = tmp;
0239     return 0;
0240 }
0241 EXPORT_SYMBOL(kstrtouint);
0242 
0243 /**
0244  * kstrtoint - convert a string to an int
0245  * @s: The start of the string. The string must be null-terminated, and may also
0246  *  include a single newline before its terminating null. The first character
0247  *  may also be a plus sign or a minus sign.
0248  * @base: The number base to use. The maximum supported base is 16. If base is
0249  *  given as 0, then the base of the string is automatically detected with the
0250  *  conventional semantics - If it begins with 0x the number will be parsed as a
0251  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
0252  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
0253  * @res: Where to write the result of the conversion on success.
0254  *
0255  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
0256  * Preferred over simple_strtol(). Return code must be checked.
0257  */
0258 noinline
0259 int kstrtoint(const char *s, unsigned int base, int *res)
0260 {
0261     long long tmp;
0262     int rv;
0263 
0264     rv = kstrtoll(s, base, &tmp);
0265     if (rv < 0)
0266         return rv;
0267     if (tmp != (int)tmp)
0268         return -ERANGE;
0269     *res = tmp;
0270     return 0;
0271 }
0272 EXPORT_SYMBOL(kstrtoint);
0273 
0274 noinline
0275 int kstrtou16(const char *s, unsigned int base, u16 *res)
0276 {
0277     unsigned long long tmp;
0278     int rv;
0279 
0280     rv = kstrtoull(s, base, &tmp);
0281     if (rv < 0)
0282         return rv;
0283     if (tmp != (u16)tmp)
0284         return -ERANGE;
0285     *res = tmp;
0286     return 0;
0287 }
0288 EXPORT_SYMBOL(kstrtou16);
0289 
0290 noinline
0291 int kstrtos16(const char *s, unsigned int base, s16 *res)
0292 {
0293     long long tmp;
0294     int rv;
0295 
0296     rv = kstrtoll(s, base, &tmp);
0297     if (rv < 0)
0298         return rv;
0299     if (tmp != (s16)tmp)
0300         return -ERANGE;
0301     *res = tmp;
0302     return 0;
0303 }
0304 EXPORT_SYMBOL(kstrtos16);
0305 
0306 noinline
0307 int kstrtou8(const char *s, unsigned int base, u8 *res)
0308 {
0309     unsigned long long tmp;
0310     int rv;
0311 
0312     rv = kstrtoull(s, base, &tmp);
0313     if (rv < 0)
0314         return rv;
0315     if (tmp != (u8)tmp)
0316         return -ERANGE;
0317     *res = tmp;
0318     return 0;
0319 }
0320 EXPORT_SYMBOL(kstrtou8);
0321 
0322 noinline
0323 int kstrtos8(const char *s, unsigned int base, s8 *res)
0324 {
0325     long long tmp;
0326     int rv;
0327 
0328     rv = kstrtoll(s, base, &tmp);
0329     if (rv < 0)
0330         return rv;
0331     if (tmp != (s8)tmp)
0332         return -ERANGE;
0333     *res = tmp;
0334     return 0;
0335 }
0336 EXPORT_SYMBOL(kstrtos8);
0337 
0338 /**
0339  * kstrtobool - convert common user inputs into boolean values
0340  * @s: input string
0341  * @res: result
0342  *
0343  * This routine returns 0 iff the first character is one of 'YyTt1NnFf0', or
0344  * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL.  Value
0345  * pointed to by res is updated upon finding a match.
0346  */
0347 noinline
0348 int kstrtobool(const char *s, bool *res)
0349 {
0350     if (!s)
0351         return -EINVAL;
0352 
0353     switch (s[0]) {
0354     case 'y':
0355     case 'Y':
0356     case 't':
0357     case 'T':
0358     case '1':
0359         *res = true;
0360         return 0;
0361     case 'n':
0362     case 'N':
0363     case 'f':
0364     case 'F':
0365     case '0':
0366         *res = false;
0367         return 0;
0368     case 'o':
0369     case 'O':
0370         switch (s[1]) {
0371         case 'n':
0372         case 'N':
0373             *res = true;
0374             return 0;
0375         case 'f':
0376         case 'F':
0377             *res = false;
0378             return 0;
0379         default:
0380             break;
0381         }
0382         break;
0383     default:
0384         break;
0385     }
0386 
0387     return -EINVAL;
0388 }
0389 EXPORT_SYMBOL(kstrtobool);
0390 
0391 /*
0392  * Since "base" would be a nonsense argument, this open-codes the
0393  * _from_user helper instead of using the helper macro below.
0394  */
0395 int kstrtobool_from_user(const char __user *s, size_t count, bool *res)
0396 {
0397     /* Longest string needed to differentiate, newline, terminator */
0398     char buf[4];
0399 
0400     count = min(count, sizeof(buf) - 1);
0401     if (copy_from_user(buf, s, count))
0402         return -EFAULT;
0403     buf[count] = '\0';
0404     return kstrtobool(buf, res);
0405 }
0406 EXPORT_SYMBOL(kstrtobool_from_user);
0407 
0408 #define kstrto_from_user(f, g, type)                    \
0409 int f(const char __user *s, size_t count, unsigned int base, type *res) \
0410 {                                   \
0411     /* sign, base 2 representation, newline, terminator */      \
0412     char buf[1 + sizeof(type) * 8 + 1 + 1];             \
0413                                     \
0414     count = min(count, sizeof(buf) - 1);                \
0415     if (copy_from_user(buf, s, count))              \
0416         return -EFAULT;                     \
0417     buf[count] = '\0';                      \
0418     return g(buf, base, res);                   \
0419 }                                   \
0420 EXPORT_SYMBOL(f)
0421 
0422 kstrto_from_user(kstrtoull_from_user,   kstrtoull,  unsigned long long);
0423 kstrto_from_user(kstrtoll_from_user,    kstrtoll,   long long);
0424 kstrto_from_user(kstrtoul_from_user,    kstrtoul,   unsigned long);
0425 kstrto_from_user(kstrtol_from_user, kstrtol,    long);
0426 kstrto_from_user(kstrtouint_from_user,  kstrtouint, unsigned int);
0427 kstrto_from_user(kstrtoint_from_user,   kstrtoint,  int);
0428 kstrto_from_user(kstrtou16_from_user,   kstrtou16,  u16);
0429 kstrto_from_user(kstrtos16_from_user,   kstrtos16,  s16);
0430 kstrto_from_user(kstrtou8_from_user,    kstrtou8,   u8);
0431 kstrto_from_user(kstrtos8_from_user,    kstrtos8,   s8);