diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2004-07-16 16:03:37 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2004-07-16 16:03:37 +0000 |
commit | 64ef824db05e7fa74e2b4548c1b4b47f0eaa18c2 (patch) | |
tree | 2154921208c1fb9eeb3d5862b56679841f0054fc /lib/libc/stdlib | |
parent | 25a92820f089dc87ce3ef9bcb777d7b80c037cc1 (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/stdlib')
-rw-r--r-- | lib/libc/stdlib/strtonum.c | 30 |
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; |