diff options
Diffstat (limited to 'lib/libc/stdlib/strtoul.c')
-rw-r--r-- | lib/libc/stdlib/strtoul.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index 304150a..820c3ab 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -35,6 +35,11 @@ static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#ifndef lint +static const char rcsid[] = +"$FreeBSD$"; +#endif + #include <limits.h> #include <ctype.h> #include <errno.h> @@ -43,7 +48,7 @@ static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; /* * Convert a string to an unsigned long integer. * - * Ignores `locale' stuff. Assumes that the upper and lower case + * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long @@ -52,23 +57,27 @@ strtoul(nptr, endptr, base) char **endptr; register int base; { - register const char *s = nptr; + register const char *s; register unsigned long acc; register unsigned char c; register unsigned long cutoff; - register int neg = 0, any, cutlim; + register int neg, any, cutlim; /* * See strtol for comments as to the logic used. */ + s = nptr; do { c = *s++; } while (isspace(c)); if (c == '-') { neg = 1; c = *s++; - } else if (c == '+') - c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; @@ -77,9 +86,13 @@ strtoul(nptr, endptr, base) } if (base == 0) base = c == '0' ? 8 : 10; - cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; - cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; - for (acc = 0, any = 0;; c = *s++) { + any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for (acc = 0; ; c = *s++) { if (!isascii(c)) break; if (isdigit(c)) @@ -101,9 +114,12 @@ strtoul(nptr, endptr, base) if (any < 0) { acc = ULONG_MAX; errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; } else if (neg) acc = -acc; - if (endptr != 0) + if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } |