linux/lib/kstrtox.c
<<
>>
Prefs
   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
  23const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
  24{
  25        if (*base == 0) {
  26                if (s[0] == '0') {
  27                        if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
  28                                *base = 16;
  29                        else
  30                                *base = 8;
  31                } else
  32                        *base = 10;
  33        }
  34        if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
  35                s += 2;
  36        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 */
  47unsigned 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        while (*s) {
  57                unsigned int val;
  58
  59                if ('0' <= *s && *s <= '9')
  60                        val = *s - '0';
  61                else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f')
  62                        val = _tolower(*s) - 'a' + 10;
  63                else
  64                        break;
  65
  66                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                if (unlikely(res & (~0ull << 60))) {
  73                        if (res > div_u64(ULLONG_MAX - val, base))
  74                                overflow = 1;
  75                }
  76                res = res * base + val;
  77                rv++;
  78                s++;
  79        }
  80        *p = res;
  81        if (overflow)
  82                rv |= KSTRTOX_OVERFLOW;
  83        return rv;
  84}
  85
  86static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
  87{
  88        unsigned long long _res;
  89        unsigned int rv;
  90
  91        s = _parse_integer_fixup_radix(s, &base);
  92        rv = _parse_integer(s, base, &_res);
  93        if (rv & KSTRTOX_OVERFLOW)
  94                return -ERANGE;
  95        rv &= ~KSTRTOX_OVERFLOW;
  96        if (rv == 0)
  97                return -EINVAL;
  98        s += rv;
  99        if (*s == '\n')
 100                s++;
 101        if (*s)
 102                return -EINVAL;
 103        *res = _res;
 104        return 0;
 105}
 106
 107/**
 108 * kstrtoull - convert a string to an unsigned long long
 109 * @s: The start of the string. The string must be null-terminated, and may also
 110 *  include a single newline before its terminating null. The first character
 111 *  may also be a plus sign, but not a minus sign.
 112 * @base: The number base to use. The maximum supported base is 16. If base is
 113 *  given as 0, then the base of the string is automatically detected with the
 114 *  conventional semantics - If it begins with 0x the number will be parsed as a
 115 *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
 116 *  parsed as an octal number. Otherwise it will be parsed as a decimal.
 117 * @res: Where to write the result of the conversion on success.
 118 *
 119 * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
 120 * Used as a replacement for the obsolete simple_strtoull. Return code must
 121 * be checked.
 122 */
 123int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
 124{
 125        if (s[0] == '+')
 126                s++;
 127        return _kstrtoull(s, base, res);
 128}
 129EXPORT_SYMBOL(kstrtoull);
 130
 131/**
 132 * kstrtoll - convert a string to a long long
 133 * @s: The start of the string. The string must be null-terminated, and may also
 134 *  include a single newline before its terminating null. The first character
 135 *  may also be a plus sign or a minus sign.
 136 * @base: The number base to use. The maximum supported base is 16. If base is
 137 *  given as 0, then the base of the string is automatically detected with the
 138 *  conventional semantics - If it begins with 0x the number will be parsed as a
 139 *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
 140 *  parsed as an octal number. Otherwise it will be parsed as a decimal.
 141 * @res: Where to write the result of the conversion on success.
 142 *
 143 * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
 144 * Used as a replacement for the obsolete simple_strtoull. Return code must
 145 * be checked.
 146 */
 147int kstrtoll(const char *s, unsigned int base, long long *res)
 148{
 149        unsigned long long tmp;
 150        int rv;
 151
 152        if (s[0] == '-') {
 153                rv = _kstrtoull(s + 1, base, &tmp);
 154                if (rv < 0)
 155                        return rv;
 156                if ((long long)(-tmp) >= 0)
 157                        return -ERANGE;
 158                *res = -tmp;
 159        } else {
 160                rv = kstrtoull(s, base, &tmp);
 161                if (rv < 0)
 162                        return rv;
 163                if ((long long)tmp < 0)
 164                        return -ERANGE;
 165                *res = tmp;
 166        }
 167        return 0;
 168}
 169EXPORT_SYMBOL(kstrtoll);
 170
 171/* Internal, do not use. */
 172int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
 173{
 174        unsigned long long tmp;
 175        int rv;
 176
 177        rv = kstrtoull(s, base, &tmp);
 178        if (rv < 0)
 179                return rv;
 180        if (tmp != (unsigned long long)(unsigned long)tmp)
 181                return -ERANGE;
 182        *res = tmp;
 183        return 0;
 184}
 185EXPORT_SYMBOL(_kstrtoul);
 186
 187/* Internal, do not use. */
 188int _kstrtol(const char *s, unsigned int base, long *res)
 189{
 190        long long tmp;
 191        int rv;
 192
 193        rv = kstrtoll(s, base, &tmp);
 194        if (rv < 0)
 195                return rv;
 196        if (tmp != (long long)(long)tmp)
 197                return -ERANGE;
 198        *res = tmp;
 199        return 0;
 200}
 201EXPORT_SYMBOL(_kstrtol);
 202
 203/**
 204 * kstrtouint - convert a string to an unsigned int
 205 * @s: The start of the string. The string must be null-terminated, and may also
 206 *  include a single newline before its terminating null. The first character
 207 *  may also be a plus sign, but not a minus sign.
 208 * @base: The number base to use. The maximum supported base is 16. If base is
 209 *  given as 0, then the base of the string is automatically detected with the
 210 *  conventional semantics - If it begins with 0x the number will be parsed as a
 211 *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
 212 *  parsed as an octal number. Otherwise it will be parsed as a decimal.
 213 * @res: Where to write the result of the conversion on success.
 214 *
 215 * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
 216 * Used as a replacement for the obsolete simple_strtoull. Return code must
 217 * be checked.
 218 */
 219int kstrtouint(const char *s, unsigned int base, unsigned int *res)
 220{
 221        unsigned long long tmp;
 222        int rv;
 223
 224        rv = kstrtoull(s, base, &tmp);
 225        if (rv < 0)
 226                return rv;
 227        if (tmp != (unsigned long long)(unsigned int)tmp)
 228                return -ERANGE;
 229        *res = tmp;
 230        return 0;
 231}
 232EXPORT_SYMBOL(kstrtouint);
 233
 234/**
 235 * kstrtoint - convert a string to an int
 236 * @s: The start of the string. The string must be null-terminated, and may also
 237 *  include a single newline before its terminating null. The first character
 238 *  may also be a plus sign or a minus sign.
 239 * @base: The number base to use. The maximum supported base is 16. If base is
 240 *  given as 0, then the base of the string is automatically detected with the
 241 *  conventional semantics - If it begins with 0x the number will be parsed as a
 242 *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
 243 *  parsed as an octal number. Otherwise it will be parsed as a decimal.
 244 * @res: Where to write the result of the conversion on success.
 245 *
 246 * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
 247 * Used as a replacement for the obsolete simple_strtoull. Return code must
 248 * be checked.
 249 */
 250int kstrtoint(const char *s, unsigned int base, int *res)
 251{
 252        long long tmp;
 253        int rv;
 254
 255        rv = kstrtoll(s, base, &tmp);
 256        if (rv < 0)
 257                return rv;
 258        if (tmp != (long long)(int)tmp)
 259                return -ERANGE;
 260        *res = tmp;
 261        return 0;
 262}
 263EXPORT_SYMBOL(kstrtoint);
 264
 265int kstrtou16(const char *s, unsigned int base, u16 *res)
 266{
 267        unsigned long long tmp;
 268        int rv;
 269
 270        rv = kstrtoull(s, base, &tmp);
 271        if (rv < 0)
 272                return rv;
 273        if (tmp != (unsigned long long)(u16)tmp)
 274                return -ERANGE;
 275        *res = tmp;
 276        return 0;
 277}
 278EXPORT_SYMBOL(kstrtou16);
 279
 280int kstrtos16(const char *s, unsigned int base, s16 *res)
 281{
 282        long long tmp;
 283        int rv;
 284
 285        rv = kstrtoll(s, base, &tmp);
 286        if (rv < 0)
 287                return rv;
 288        if (tmp != (long long)(s16)tmp)
 289                return -ERANGE;
 290        *res = tmp;
 291        return 0;
 292}
 293EXPORT_SYMBOL(kstrtos16);
 294
 295int kstrtou8(const char *s, unsigned int base, u8 *res)
 296{
 297        unsigned long long tmp;
 298        int rv;
 299
 300        rv = kstrtoull(s, base, &tmp);
 301        if (rv < 0)
 302                return rv;
 303        if (tmp != (unsigned long long)(u8)tmp)
 304                return -ERANGE;
 305        *res = tmp;
 306        return 0;
 307}
 308EXPORT_SYMBOL(kstrtou8);
 309
 310int kstrtos8(const char *s, unsigned int base, s8 *res)
 311{
 312        long long tmp;
 313        int rv;
 314
 315        rv = kstrtoll(s, base, &tmp);
 316        if (rv < 0)
 317                return rv;
 318        if (tmp != (long long)(s8)tmp)
 319                return -ERANGE;
 320        *res = tmp;
 321        return 0;
 322}
 323EXPORT_SYMBOL(kstrtos8);
 324
 325#define kstrto_from_user(f, g, type)                                    \
 326int f(const char __user *s, size_t count, unsigned int base, type *res) \
 327{                                                                       \
 328        /* sign, base 2 representation, newline, terminator */          \
 329        char buf[1 + sizeof(type) * 8 + 1 + 1];                         \
 330                                                                        \
 331        count = min(count, sizeof(buf) - 1);                            \
 332        if (copy_from_user(buf, s, count))                              \
 333                return -EFAULT;                                         \
 334        buf[count] = '\0';                                              \
 335        return g(buf, base, res);                                       \
 336}                                                                       \
 337EXPORT_SYMBOL(f)
 338
 339kstrto_from_user(kstrtoull_from_user,   kstrtoull,      unsigned long long);
 340kstrto_from_user(kstrtoll_from_user,    kstrtoll,       long long);
 341kstrto_from_user(kstrtoul_from_user,    kstrtoul,       unsigned long);
 342kstrto_from_user(kstrtol_from_user,     kstrtol,        long);
 343kstrto_from_user(kstrtouint_from_user,  kstrtouint,     unsigned int);
 344kstrto_from_user(kstrtoint_from_user,   kstrtoint,      int);
 345kstrto_from_user(kstrtou16_from_user,   kstrtou16,      u16);
 346kstrto_from_user(kstrtos16_from_user,   kstrtos16,      s16);
 347kstrto_from_user(kstrtou8_from_user,    kstrtou8,       u8);
 348kstrto_from_user(kstrtos8_from_user,    kstrtos8,       s8);
 349
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.