aboutsummaryrefslogtreecommitdiff
path: root/libbb/safe_strtol.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/safe_strtol.c')
-rw-r--r--libbb/safe_strtol.c102
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
15int safe_strtoi(char *arg, int* value) 13int 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
24int 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
39int safe_strtol(char *arg, long* value) 28int 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
54int safe_strtoul(char *arg, unsigned long* value) 45int 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
69int safe_strtoll(char *arg, long long* value) 60int 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
84int safe_strtoull(char *arg, unsigned long long* value) 77int 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
111int 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
126int 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
141int BUG_safe_strtou32_unimplemented(void);
142int 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}