summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2004-07-16 16:03:37 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2004-07-16 16:03:37 +0000
commit64ef824db05e7fa74e2b4548c1b4b47f0eaa18c2 (patch)
tree2154921208c1fb9eeb3d5862b56679841f0054fc /lib/libc
parent25a92820f089dc87ce3ef9bcb777d7b80c037cc1 (diff)
Avoid comparing unsigned and signed long longs since the signed
one will get implicitly cast to unsigned. Fixes a bug with negative minval noticed by mjc@. Similar to a diff from miod@. OK miod@.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/stdlib/strtonum.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/lib/libc/stdlib/strtonum.c b/lib/libc/stdlib/strtonum.c
index a656b63f19e..4c41c22b8b1 100644
--- a/lib/libc/stdlib/strtonum.c
+++ b/lib/libc/stdlib/strtonum.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strtonum.c,v 1.3 2004/06/21 23:12:25 marc Exp $ */
+/* $OpenBSD: strtonum.c,v 1.4 2004/07/16 16:03:36 millert Exp $ */
/*
* Copyright (c) 2004 Ted Unangst and Todd Miller
* All rights reserved.
@@ -25,12 +25,13 @@
#define TOOLARGE 3
unsigned long long
-strtonum(const char *numstr, long long minval, unsigned long long maxval,
+strtonum(const char *numstr, long long minval, unsigned long long umaxval,
const char **errstrp)
{
- unsigned long long ull;
+ long long ll, maxval = (long long)umaxval;
+ unsigned long long ull = 0;
char *ep;
- int error;
+ int error = 0;
struct errval {
const char *errstr;
int err;
@@ -43,19 +44,23 @@ strtonum(const char *numstr, long long minval, unsigned long long maxval,
ev[0].err = errno;
errno = 0;
- error = 0;
- ull = 0;
- if (minval > maxval || maxval < minval ||
- (minval < 0 && maxval > LLONG_MAX))
- error = INVALID;
- else if (maxval > LLONG_MAX ) {
+ if (umaxval > LLONG_MAX ) {
+ if (minval < 0) {
+ error = INVALID;
+ goto done;
+ }
ull = strtoull(numstr, &ep, 10);
if (numstr == ep || *ep != '\0')
error = INVALID;
- else if ((ull == ULLONG_MAX && errno == ERANGE) || ull > maxval)
+ else if ((ull == ULLONG_MAX && errno == ERANGE) ||
+ ull > umaxval)
error = TOOLARGE;
} else {
- long long ll = strtoll(numstr, &ep, 10);
+ if (minval > maxval || maxval < minval) {
+ error = INVALID;
+ goto done;
+ }
+ ll = strtoll(numstr, &ep, 10);
if (numstr == ep || *ep != '\0')
error = INVALID;
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
@@ -64,6 +69,7 @@ strtonum(const char *numstr, long long minval, unsigned long long maxval,
error = TOOLARGE;
ull = (unsigned long long)ll;
}
+done:
if (errstrp != NULL)
*errstrp = ev[error].errstr;
errno = ev[error].err;