aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-12-22 13:00:32 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-12-22 13:00:32 +0100
commitba6587295053f369d6e2e9b788f42b49e1baced5 (patch)
tree87adf3c5a302a9f91ba4cc6f97a8f2d2f44eb3e0
parent6a93212b54327c77383d88efd581475105f3b72a (diff)
downloadbusybox-w32-ba6587295053f369d6e2e9b788f42b49e1baced5.tar.gz
busybox-w32-ba6587295053f369d6e2e9b788f42b49e1baced5.tar.bz2
busybox-w32-ba6587295053f369d6e2e9b788f42b49e1baced5.zip
libbb/bb_strtonum: always set end ptr, even on error return
function old new delta handle_errors 69 61 -8 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/bb_strtonum.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/libbb/bb_strtonum.c b/libbb/bb_strtonum.c
index c66c774f4..949f26bee 100644
--- a/libbb/bb_strtonum.c
+++ b/libbb/bb_strtonum.c
@@ -36,14 +36,14 @@ static unsigned long long ret_ERANGE(void)
36 return ULLONG_MAX; 36 return ULLONG_MAX;
37} 37}
38 38
39static unsigned long long handle_errors(unsigned long long v, char **endp, char *endptr) 39static unsigned long long handle_errors(unsigned long long v, char **endp)
40{ 40{
41 if (endp) *endp = endptr; 41 char next_ch = **endp;
42 42
43 /* errno is already set to ERANGE by strtoXXX if value overflowed */ 43 /* errno is already set to ERANGE by strtoXXX if value overflowed */
44 if (endptr[0]) { 44 if (next_ch) {
45 /* "1234abcg" or out-of-range? */ 45 /* "1234abcg" or out-of-range? */
46 if (isalnum(endptr[0]) || errno) 46 if (isalnum(next_ch) || errno)
47 return ret_ERANGE(); 47 return ret_ERANGE();
48 /* good number, just suspicious terminator */ 48 /* good number, just suspicious terminator */
49 errno = EINVAL; 49 errno = EINVAL;
@@ -57,30 +57,37 @@ unsigned long long FAST_FUNC bb_strtoull(const char *arg, char **endp, int base)
57 unsigned long long v; 57 unsigned long long v;
58 char *endptr; 58 char *endptr;
59 59
60 if (!endp) endp = &endptr;
61 *endp = (char*) arg;
62
60 /* strtoul(" -4200000000") returns 94967296, errno 0 (!) */ 63 /* strtoul(" -4200000000") returns 94967296, errno 0 (!) */
61 /* I don't think that this is right. Preventing this... */ 64 /* I don't think that this is right. Preventing this... */
62 if (!isalnum(arg[0])) return ret_ERANGE(); 65 if (!isalnum(arg[0])) return ret_ERANGE();
63 66
64 /* not 100% correct for lib func, but convenient for the caller */ 67 /* not 100% correct for lib func, but convenient for the caller */
65 errno = 0; 68 errno = 0;
66 v = strtoull(arg, &endptr, base); 69 v = strtoull(arg, endp, base);
67 return handle_errors(v, endp, endptr); 70 return handle_errors(v, endp);
68} 71}
69 72
70long long FAST_FUNC bb_strtoll(const char *arg, char **endp, int base) 73long long FAST_FUNC bb_strtoll(const char *arg, char **endp, int base)
71{ 74{
72 unsigned long long v; 75 unsigned long long v;
73 char *endptr; 76 char *endptr;
77 char first;
78
79 if (!endp) endp = &endptr;
80 *endp = (char*) arg;
74 81
75 /* Check for the weird "feature": 82 /* Check for the weird "feature":
76 * a "-" string is apparently a valid "number" for strto[u]l[l]! 83 * a "-" string is apparently a valid "number" for strto[u]l[l]!
77 * It returns zero and errno is 0! :( */ 84 * It returns zero and errno is 0! :( */
78 char first = (arg[0] != '-' ? arg[0] : arg[1]); 85 first = (arg[0] != '-' ? arg[0] : arg[1]);
79 if (!isalnum(first)) return ret_ERANGE(); 86 if (!isalnum(first)) return ret_ERANGE();
80 87
81 errno = 0; 88 errno = 0;
82 v = strtoll(arg, &endptr, base); 89 v = strtoll(arg, endp, base);
83 return handle_errors(v, endp, endptr); 90 return handle_errors(v, endp);
84} 91}
85 92
86#if ULONG_MAX != ULLONG_MAX 93#if ULONG_MAX != ULLONG_MAX
@@ -89,23 +96,30 @@ unsigned long FAST_FUNC bb_strtoul(const char *arg, char **endp, int base)
89 unsigned long v; 96 unsigned long v;
90 char *endptr; 97 char *endptr;
91 98
99 if (!endp) endp = &endptr;
100 *endp = (char*) arg;
101
92 if (!isalnum(arg[0])) return ret_ERANGE(); 102 if (!isalnum(arg[0])) return ret_ERANGE();
93 errno = 0; 103 errno = 0;
94 v = strtoul(arg, &endptr, base); 104 v = strtoul(arg, endp, base);
95 return handle_errors(v, endp, endptr); 105 return handle_errors(v, endp);
96} 106}
97 107
98long FAST_FUNC bb_strtol(const char *arg, char **endp, int base) 108long FAST_FUNC bb_strtol(const char *arg, char **endp, int base)
99{ 109{
100 long v; 110 long v;
101 char *endptr; 111 char *endptr;
112 char first;
102 113
103 char first = (arg[0] != '-' ? arg[0] : arg[1]); 114 if (!endp) endp = &endptr;
115 *endp = (char*) arg;
116
117 first = (arg[0] != '-' ? arg[0] : arg[1]);
104 if (!isalnum(first)) return ret_ERANGE(); 118 if (!isalnum(first)) return ret_ERANGE();
105 119
106 errno = 0; 120 errno = 0;
107 v = strtol(arg, &endptr, base); 121 v = strtol(arg, endp, base);
108 return handle_errors(v, endp, endptr); 122 return handle_errors(v, endp);
109} 123}
110#endif 124#endif
111 125
@@ -115,25 +129,32 @@ unsigned FAST_FUNC bb_strtou(const char *arg, char **endp, int base)
115 unsigned long v; 129 unsigned long v;
116 char *endptr; 130 char *endptr;
117 131
132 if (!endp) endp = &endptr;
133 *endp = (char*) arg;
134
118 if (!isalnum(arg[0])) return ret_ERANGE(); 135 if (!isalnum(arg[0])) return ret_ERANGE();
119 errno = 0; 136 errno = 0;
120 v = strtoul(arg, &endptr, base); 137 v = strtoul(arg, endp, base);
121 if (v > UINT_MAX) return ret_ERANGE(); 138 if (v > UINT_MAX) return ret_ERANGE();
122 return handle_errors(v, endp, endptr); 139 return handle_errors(v, endp);
123} 140}
124 141
125int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base) 142int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base)
126{ 143{
127 long v; 144 long v;
128 char *endptr; 145 char *endptr;
146 char first;
147
148 if (!endp) endp = &endptr;
149 *endp = (char*) arg;
129 150
130 char first = (arg[0] != '-' ? arg[0] : arg[1]); 151 first = (arg[0] != '-' ? arg[0] : arg[1]);
131 if (!isalnum(first)) return ret_ERANGE(); 152 if (!isalnum(first)) return ret_ERANGE();
132 153
133 errno = 0; 154 errno = 0;
134 v = strtol(arg, &endptr, base); 155 v = strtol(arg, endp, base);
135 if (v > INT_MAX) return ret_ERANGE(); 156 if (v > INT_MAX) return ret_ERANGE();
136 if (v < INT_MIN) return ret_ERANGE(); 157 if (v < INT_MIN) return ret_ERANGE();
137 return handle_errors(v, endp, endptr); 158 return handle_errors(v, endp);
138} 159}
139#endif 160#endif