kstrtox.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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/module.h>
  19. #include <linux/types.h>
  20. #include <asm/uaccess.h>
  21. #include "kstrtox.h"
  22. const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
  23. {
  24. if (*base == 0) {
  25. if (s[0] == '0') {
  26. if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
  27. *base = 16;
  28. else
  29. *base = 8;
  30. } else
  31. *base = 10;
  32. }
  33. if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
  34. s += 2;
  35. return s;
  36. }
  37. /*
  38. * Convert non-negative integer string representation in explicitly given radix
  39. * to an integer.
  40. * Return number of characters consumed maybe or-ed with overflow bit.
  41. * If overflow occurs, result integer (incorrect) is still returned.
  42. *
  43. * Don't you dare use this function.
  44. */
  45. unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *res)
  46. {
  47. unsigned int rv;
  48. int overflow;
  49. *res = 0;
  50. rv = 0;
  51. overflow = 0;
  52. while (*s) {
  53. unsigned int val;
  54. if ('0' <= *s && *s <= '9')
  55. val = *s - '0';
  56. else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f')
  57. val = _tolower(*s) - 'a' + 10;
  58. else
  59. break;
  60. if (val >= base)
  61. break;
  62. if (*res > div_u64(ULLONG_MAX - val, base))
  63. overflow = 1;
  64. *res = *res * base + val;
  65. rv++;
  66. s++;
  67. }
  68. if (overflow)
  69. rv |= KSTRTOX_OVERFLOW;
  70. return rv;
  71. }
  72. static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
  73. {
  74. unsigned long long _res;
  75. unsigned int rv;
  76. s = _parse_integer_fixup_radix(s, &base);
  77. rv = _parse_integer(s, base, &_res);
  78. if (rv & KSTRTOX_OVERFLOW)
  79. return -ERANGE;
  80. rv &= ~KSTRTOX_OVERFLOW;
  81. if (rv == 0)
  82. return -EINVAL;
  83. s += rv;
  84. if (*s == '\n')
  85. s++;
  86. if (*s)
  87. return -EINVAL;
  88. *res = _res;
  89. return 0;
  90. }
  91. int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
  92. {
  93. if (s[0] == '+')
  94. s++;
  95. return _kstrtoull(s, base, res);
  96. }
  97. EXPORT_SYMBOL(kstrtoull);
  98. int kstrtoll(const char *s, unsigned int base, long long *res)
  99. {
  100. unsigned long long tmp;
  101. int rv;
  102. if (s[0] == '-') {
  103. rv = _kstrtoull(s + 1, base, &tmp);
  104. if (rv < 0)
  105. return rv;
  106. if ((long long)(-tmp) >= 0)
  107. return -ERANGE;
  108. *res = -tmp;
  109. } else {
  110. rv = kstrtoull(s, base, &tmp);
  111. if (rv < 0)
  112. return rv;
  113. if ((long long)tmp < 0)
  114. return -ERANGE;
  115. *res = tmp;
  116. }
  117. return 0;
  118. }
  119. EXPORT_SYMBOL(kstrtoll);
  120. /* Internal, do not use. */
  121. int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
  122. {
  123. unsigned long long tmp;
  124. int rv;
  125. rv = kstrtoull(s, base, &tmp);
  126. if (rv < 0)
  127. return rv;
  128. if (tmp != (unsigned long long)(unsigned long)tmp)
  129. return -ERANGE;
  130. *res = tmp;
  131. return 0;
  132. }
  133. EXPORT_SYMBOL(_kstrtoul);
  134. /* Internal, do not use. */
  135. int _kstrtol(const char *s, unsigned int base, long *res)
  136. {
  137. long long tmp;
  138. int rv;
  139. rv = kstrtoll(s, base, &tmp);
  140. if (rv < 0)
  141. return rv;
  142. if (tmp != (long long)(long)tmp)
  143. return -ERANGE;
  144. *res = tmp;
  145. return 0;
  146. }
  147. EXPORT_SYMBOL(_kstrtol);
  148. int kstrtouint(const char *s, unsigned int base, unsigned int *res)
  149. {
  150. unsigned long long tmp;
  151. int rv;
  152. rv = kstrtoull(s, base, &tmp);
  153. if (rv < 0)
  154. return rv;
  155. if (tmp != (unsigned long long)(unsigned int)tmp)
  156. return -ERANGE;
  157. *res = tmp;
  158. return 0;
  159. }
  160. EXPORT_SYMBOL(kstrtouint);
  161. int kstrtoint(const char *s, unsigned int base, int *res)
  162. {
  163. long long tmp;
  164. int rv;
  165. rv = kstrtoll(s, base, &tmp);
  166. if (rv < 0)
  167. return rv;
  168. if (tmp != (long long)(int)tmp)
  169. return -ERANGE;
  170. *res = tmp;
  171. return 0;
  172. }
  173. EXPORT_SYMBOL(kstrtoint);
  174. int kstrtou16(const char *s, unsigned int base, u16 *res)
  175. {
  176. unsigned long long tmp;
  177. int rv;
  178. rv = kstrtoull(s, base, &tmp);
  179. if (rv < 0)
  180. return rv;
  181. if (tmp != (unsigned long long)(u16)tmp)
  182. return -ERANGE;
  183. *res = tmp;
  184. return 0;
  185. }
  186. EXPORT_SYMBOL(kstrtou16);
  187. int kstrtos16(const char *s, unsigned int base, s16 *res)
  188. {
  189. long long tmp;
  190. int rv;
  191. rv = kstrtoll(s, base, &tmp);
  192. if (rv < 0)
  193. return rv;
  194. if (tmp != (long long)(s16)tmp)
  195. return -ERANGE;
  196. *res = tmp;
  197. return 0;
  198. }
  199. EXPORT_SYMBOL(kstrtos16);
  200. int kstrtou8(const char *s, unsigned int base, u8 *res)
  201. {
  202. unsigned long long tmp;
  203. int rv;
  204. rv = kstrtoull(s, base, &tmp);
  205. if (rv < 0)
  206. return rv;
  207. if (tmp != (unsigned long long)(u8)tmp)
  208. return -ERANGE;
  209. *res = tmp;
  210. return 0;
  211. }
  212. EXPORT_SYMBOL(kstrtou8);
  213. int kstrtos8(const char *s, unsigned int base, s8 *res)
  214. {
  215. long long tmp;
  216. int rv;
  217. rv = kstrtoll(s, base, &tmp);
  218. if (rv < 0)
  219. return rv;
  220. if (tmp != (long long)(s8)tmp)
  221. return -ERANGE;
  222. *res = tmp;
  223. return 0;
  224. }
  225. EXPORT_SYMBOL(kstrtos8);
  226. #define kstrto_from_user(f, g, type) \
  227. int f(const char __user *s, size_t count, unsigned int base, type *res) \
  228. { \
  229. /* sign, base 2 representation, newline, terminator */ \
  230. char buf[1 + sizeof(type) * 8 + 1 + 1]; \
  231. \
  232. count = min(count, sizeof(buf) - 1); \
  233. if (copy_from_user(buf, s, count)) \
  234. return -EFAULT; \
  235. buf[count] = '\0'; \
  236. return g(buf, base, res); \
  237. } \
  238. EXPORT_SYMBOL(f)
  239. kstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long);
  240. kstrto_from_user(kstrtoll_from_user, kstrtoll, long long);
  241. kstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long);
  242. kstrto_from_user(kstrtol_from_user, kstrtol, long);
  243. kstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int);
  244. kstrto_from_user(kstrtoint_from_user, kstrtoint, int);
  245. kstrto_from_user(kstrtou16_from_user, kstrtou16, u16);
  246. kstrto_from_user(kstrtos16_from_user, kstrtos16, s16);
  247. kstrto_from_user(kstrtou8_from_user, kstrtou8, u8);
  248. kstrto_from_user(kstrtos8_from_user, kstrtos8, s8);