diff options
Diffstat (limited to 'libbb/safe_strtol.c')
-rw-r--r-- | libbb/safe_strtol.c | 102 |
1 files changed, 77 insertions, 25 deletions
diff --git a/libbb/safe_strtol.c b/libbb/safe_strtol.c index 027fc1e62..a7f012fbc 100644 --- a/libbb/safe_strtol.c +++ b/libbb/safe_strtol.c | |||
@@ -7,21 +7,10 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <stdlib.h> | ||
11 | #include <errno.h> | ||
12 | #include <assert.h> | 10 | #include <assert.h> |
13 | #include "libbb.h" | 11 | #include "libbb.h" |
14 | 12 | ||
15 | int safe_strtoi(char *arg, int* value) | 13 | int safe_strtod(const char *arg, double* value) |
16 | { | ||
17 | int error; | ||
18 | long lvalue = *value; | ||
19 | error = safe_strtol(arg, &lvalue); | ||
20 | *value = (int) lvalue; | ||
21 | return error; | ||
22 | } | ||
23 | |||
24 | int safe_strtod(char *arg, double* value) | ||
25 | { | 14 | { |
26 | char *endptr; | 15 | char *endptr; |
27 | int errno_save = errno; | 16 | int errno_save = errno; |
@@ -29,69 +18,132 @@ int safe_strtod(char *arg, double* value) | |||
29 | assert(arg!=NULL); | 18 | assert(arg!=NULL); |
30 | errno = 0; | 19 | errno = 0; |
31 | *value = strtod(arg, &endptr); | 20 | *value = strtod(arg, &endptr); |
32 | if (errno != 0 || *endptr!='\0' || endptr==arg) { | 21 | if (errno != 0 || *endptr != '\0' || endptr == arg) { |
33 | return 1; | 22 | return 1; |
34 | } | 23 | } |
35 | errno = errno_save; | 24 | errno = errno_save; |
36 | return 0; | 25 | return 0; |
37 | } | 26 | } |
38 | 27 | ||
39 | int safe_strtol(char *arg, long* value) | 28 | int safe_strtoull(const char *arg, unsigned long long* value) |
40 | { | 29 | { |
41 | char *endptr; | 30 | char *endptr; |
42 | int errno_save = errno; | 31 | int errno_save = errno; |
43 | 32 | ||
44 | assert(arg!=NULL); | 33 | assert(arg!=NULL); |
34 | if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */ | ||
35 | return 1; | ||
45 | errno = 0; | 36 | errno = 0; |
46 | *value = strtol(arg, &endptr, 0); | 37 | *value = strtoull(arg, &endptr, 0); |
47 | if (errno != 0 || *endptr!='\0' || endptr==arg) { | 38 | if (errno != 0 || *endptr != '\0' || endptr == arg) { |
48 | return 1; | 39 | return 1; |
49 | } | 40 | } |
50 | errno = errno_save; | 41 | errno = errno_save; |
51 | return 0; | 42 | return 0; |
52 | } | 43 | } |
53 | 44 | ||
54 | int safe_strtoul(char *arg, unsigned long* value) | 45 | int safe_strtoll(const char *arg, long long* value) |
55 | { | 46 | { |
56 | char *endptr; | 47 | char *endptr; |
57 | int errno_save = errno; | 48 | int errno_save = errno; |
58 | 49 | ||
59 | assert(arg!=NULL); | 50 | assert(arg!=NULL); |
60 | errno = 0; | 51 | errno = 0; |
61 | *value = strtoul(arg, &endptr, 0); | 52 | *value = strtoll(arg, &endptr, 0); |
62 | if (errno != 0 || *endptr!='\0' || endptr==arg) { | 53 | if (errno != 0 || *endptr != '\0' || endptr == arg) { |
63 | return 1; | 54 | return 1; |
64 | } | 55 | } |
65 | errno = errno_save; | 56 | errno = errno_save; |
66 | return 0; | 57 | return 0; |
67 | } | 58 | } |
68 | 59 | ||
69 | int safe_strtoll(char *arg, long long* value) | 60 | int safe_strtoul(const char *arg, unsigned long* value) |
70 | { | 61 | { |
71 | char *endptr; | 62 | char *endptr; |
72 | int errno_save = errno; | 63 | int errno_save = errno; |
73 | 64 | ||
74 | assert(arg!=NULL); | 65 | assert(arg!=NULL); |
66 | if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */ | ||
67 | return 1; | ||
75 | errno = 0; | 68 | errno = 0; |
76 | *value = strtoll(arg, &endptr, 0); | 69 | *value = strtoul(arg, &endptr, 0); |
77 | if (errno != 0 || *endptr!='\0' || endptr==arg) { | 70 | if (errno != 0 || *endptr != '\0' || endptr == arg) { |
78 | return 1; | 71 | return 1; |
79 | } | 72 | } |
80 | errno = errno_save; | 73 | errno = errno_save; |
81 | return 0; | 74 | return 0; |
82 | } | 75 | } |
83 | 76 | ||
84 | int safe_strtoull(char *arg, unsigned long long* value) | 77 | int safe_strtol(const char *arg, long* value) |
85 | { | 78 | { |
86 | char *endptr; | 79 | char *endptr; |
87 | int errno_save = errno; | 80 | int errno_save = errno; |
88 | 81 | ||
89 | assert(arg!=NULL); | 82 | assert(arg!=NULL); |
90 | errno = 0; | 83 | errno = 0; |
91 | *value = strtoull(arg, &endptr, 0); | 84 | *value = strtol(arg, &endptr, 0); |
92 | if (errno != 0 || *endptr!='\0' || endptr==arg) { | 85 | if (errno != 0 || *endptr != '\0' || endptr == arg) { |
93 | return 1; | 86 | return 1; |
94 | } | 87 | } |
95 | errno = errno_save; | 88 | errno = errno_save; |
96 | return 0; | 89 | return 0; |
97 | } | 90 | } |
91 | |||
92 | /* TODO: This is what uclibc is doing. Try to do the same? */ | ||
93 | |||
94 | #if 0 | ||
95 | #if defined __HAVE_ELF__ | ||
96 | |||
97 | # define strong_alias(name, aliasname) _strong_alias(name, aliasname) | ||
98 | # define _strong_alias(name, aliasname) \ | ||
99 | extern __typeof (name) aliasname __attribute__ ((alias (#name))); | ||
100 | |||
101 | #else /* !defined __HAVE_ELF__ */ | ||
102 | |||
103 | # define strong_alias(name, aliasname) _strong_alias (name, aliasname) | ||
104 | # define _strong_alias(name, aliasname) \ | ||
105 | __asm__(".global " __C_SYMBOL_PREFIX__ #aliasname "\n" \ | ||
106 | ".set " __C_SYMBOL_PREFIX__ #aliasname "," __C_SYMBOL_PREFIX__ #name); | ||
107 | |||
108 | #endif | ||
109 | #endif | ||
110 | |||
111 | int safe_strtoi(const char *arg, int* value) | ||
112 | { | ||
113 | if (sizeof(long) == sizeof(int)) { | ||
114 | return safe_strtol(arg, (long*)value); | ||
115 | } else { | ||
116 | int error; | ||
117 | long lvalue = *value; | ||
118 | error = safe_strtol(arg, &lvalue); | ||
119 | if (lvalue < INT_MIN || lvalue > INT_MAX) | ||
120 | return 1; | ||
121 | *value = (int) lvalue; | ||
122 | return error; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | int safe_strtou(const char *arg, unsigned* value) | ||
127 | { | ||
128 | if (sizeof(unsigned long) == sizeof(unsigned)) { | ||
129 | return safe_strtoul(arg, (unsigned long*)value); | ||
130 | } else { | ||
131 | int error; | ||
132 | unsigned long lvalue = *value; | ||
133 | error = safe_strtoul(arg, &lvalue); | ||
134 | if (lvalue > UINT_MAX) | ||
135 | return 1; | ||
136 | *value = (unsigned) lvalue; | ||
137 | return error; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | int BUG_safe_strtou32_unimplemented(void); | ||
142 | int safe_strtou32(const char *arg, uint32_t* value) | ||
143 | { | ||
144 | if (sizeof(uint32_t) == sizeof(unsigned)) | ||
145 | return safe_strtou(arg, (unsigned*)value); | ||
146 | if (sizeof(uint32_t) == sizeof(unsigned long)) | ||
147 | return safe_strtoul(arg, (unsigned long*)value); | ||
148 | return BUG_safe_strtou32_unimplemented(); | ||
149 | } | ||