aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbb/bb_strtonum.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/libbb/bb_strtonum.c b/libbb/bb_strtonum.c
index 2433f1f1f..4a0da0ae0 100644
--- a/libbb/bb_strtonum.c
+++ b/libbb/bb_strtonum.c
@@ -18,6 +18,16 @@
18 * errno = ERANGE if value is out of range, missing, etc. 18 * errno = ERANGE if value is out of range, missing, etc.
19 * errno = ERANGE if value had minus sign for strtouXX (even "-0" is not ok ) 19 * errno = ERANGE if value had minus sign for strtouXX (even "-0" is not ok )
20 * return value is all-ones in this case. 20 * return value is all-ones in this case.
21 *
22 * Test code:
23 * char *endptr;
24 * const char *minus = "-";
25 * errno = 0;
26 * bb_strtoi(minus, &endptr, 0); // must set ERANGE
27 * printf("minus:%p endptr:%p errno:%d EINVAL:%d\n", minus, endptr, errno, EINVAL);
28 * errno = 0;
29 * bb_strtoi("-0-", &endptr, 0); // must set EINVAL and point to second '-'
30 * printf("endptr[0]:%c errno:%d EINVAL:%d\n", endptr[0], errno, EINVAL);
21 */ 31 */
22 32
23static unsigned long long ret_ERANGE(void) 33static unsigned long long ret_ERANGE(void)
@@ -38,11 +48,6 @@ static unsigned long long handle_errors(unsigned long long v, char **endp, char
38 /* good number, just suspicious terminator */ 48 /* good number, just suspicious terminator */
39 errno = EINVAL; 49 errno = EINVAL;
40 } 50 }
41 /* Check for the weird "feature":
42 * a "-" string is apparently a valid "number" for strto[u]l[l]!
43 * It returns zero and errno is 0! :( */
44 if (endptr[-1] == '-')
45 return ret_ERANGE();
46 return v; 51 return v;
47} 52}
48 53
@@ -67,7 +72,12 @@ long long FAST_FUNC bb_strtoll(const char *arg, char **endp, int base)
67 unsigned long long v; 72 unsigned long long v;
68 char *endptr; 73 char *endptr;
69 74
70 if (arg[0] != '-' && !isalnum(arg[0])) return ret_ERANGE(); 75 /* Check for the weird "feature":
76 * a "-" string is apparently a valid "number" for strto[u]l[l]!
77 * It returns zero and errno is 0! :( */
78 char first = (arg[0] != '-' ? arg[0] : arg[1]);
79 if (!isalnum(first)) return ret_ERANGE();
80
71 errno = 0; 81 errno = 0;
72 v = strtoll(arg, &endptr, base); 82 v = strtoll(arg, &endptr, base);
73 return handle_errors(v, endp, endptr); 83 return handle_errors(v, endp, endptr);
@@ -90,7 +100,9 @@ long FAST_FUNC bb_strtol(const char *arg, char **endp, int base)
90 long v; 100 long v;
91 char *endptr; 101 char *endptr;
92 102
93 if (arg[0] != '-' && !isalnum(arg[0])) return ret_ERANGE(); 103 char first = (arg[0] != '-' ? arg[0] : arg[1]);
104 if (!isalnum(first)) return ret_ERANGE();
105
94 errno = 0; 106 errno = 0;
95 v = strtol(arg, &endptr, base); 107 v = strtol(arg, &endptr, base);
96 return handle_errors(v, endp, endptr); 108 return handle_errors(v, endp, endptr);
@@ -115,7 +127,9 @@ int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base)
115 long v; 127 long v;
116 char *endptr; 128 char *endptr;
117 129
118 if (arg[0] != '-' && !isalnum(arg[0])) return ret_ERANGE(); 130 char first = (arg[0] != '-' ? arg[0] : arg[1]);
131 if (!isalnum(first)) return ret_ERANGE();
132
119 errno = 0; 133 errno = 0;
120 v = strtol(arg, &endptr, base); 134 v = strtol(arg, &endptr, base);
121 if (v > INT_MAX) return ret_ERANGE(); 135 if (v > INT_MAX) return ret_ERANGE();