diff options
author | millert <> | 2004-07-16 16:03:36 +0000 |
---|---|---|
committer | millert <> | 2004-07-16 16:03:36 +0000 |
commit | 5324f527aa491efaf55f123392b79694bc7fca89 (patch) | |
tree | d211ca202a6ae4364ac84885940682f85079a463 | |
parent | e908c5a3dbc60cd83730f45e3ac72f1d79ec5faa (diff) | |
download | openbsd-5324f527aa491efaf55f123392b79694bc7fca89.tar.gz openbsd-5324f527aa491efaf55f123392b79694bc7fca89.tar.bz2 openbsd-5324f527aa491efaf55f123392b79694bc7fca89.zip |
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@.
-rw-r--r-- | src/lib/libc/stdlib/strtonum.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/lib/libc/stdlib/strtonum.c b/src/lib/libc/stdlib/strtonum.c index a656b63f19..4c41c22b8b 100644 --- a/src/lib/libc/stdlib/strtonum.c +++ b/src/lib/libc/stdlib/strtonum.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: strtonum.c,v 1.3 2004/06/21 23:12:25 marc Exp $ */ | 1 | /* $OpenBSD: strtonum.c,v 1.4 2004/07/16 16:03:36 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2004 Ted Unangst and Todd Miller | 3 | * Copyright (c) 2004 Ted Unangst and Todd Miller |
4 | * All rights reserved. | 4 | * All rights reserved. |
@@ -25,12 +25,13 @@ | |||
25 | #define TOOLARGE 3 | 25 | #define TOOLARGE 3 |
26 | 26 | ||
27 | unsigned long long | 27 | unsigned long long |
28 | strtonum(const char *numstr, long long minval, unsigned long long maxval, | 28 | strtonum(const char *numstr, long long minval, unsigned long long umaxval, |
29 | const char **errstrp) | 29 | const char **errstrp) |
30 | { | 30 | { |
31 | unsigned long long ull; | 31 | long long ll, maxval = (long long)umaxval; |
32 | unsigned long long ull = 0; | ||
32 | char *ep; | 33 | char *ep; |
33 | int error; | 34 | int error = 0; |
34 | struct errval { | 35 | struct errval { |
35 | const char *errstr; | 36 | const char *errstr; |
36 | int err; | 37 | int err; |
@@ -43,19 +44,23 @@ strtonum(const char *numstr, long long minval, unsigned long long maxval, | |||
43 | 44 | ||
44 | ev[0].err = errno; | 45 | ev[0].err = errno; |
45 | errno = 0; | 46 | errno = 0; |
46 | error = 0; | 47 | if (umaxval > LLONG_MAX ) { |
47 | ull = 0; | 48 | if (minval < 0) { |
48 | if (minval > maxval || maxval < minval || | 49 | error = INVALID; |
49 | (minval < 0 && maxval > LLONG_MAX)) | 50 | goto done; |
50 | error = INVALID; | 51 | } |
51 | else if (maxval > LLONG_MAX ) { | ||
52 | ull = strtoull(numstr, &ep, 10); | 52 | ull = strtoull(numstr, &ep, 10); |
53 | if (numstr == ep || *ep != '\0') | 53 | if (numstr == ep || *ep != '\0') |
54 | error = INVALID; | 54 | error = INVALID; |
55 | else if ((ull == ULLONG_MAX && errno == ERANGE) || ull > maxval) | 55 | else if ((ull == ULLONG_MAX && errno == ERANGE) || |
56 | ull > umaxval) | ||
56 | error = TOOLARGE; | 57 | error = TOOLARGE; |
57 | } else { | 58 | } else { |
58 | long long ll = strtoll(numstr, &ep, 10); | 59 | if (minval > maxval || maxval < minval) { |
60 | error = INVALID; | ||
61 | goto done; | ||
62 | } | ||
63 | ll = strtoll(numstr, &ep, 10); | ||
59 | if (numstr == ep || *ep != '\0') | 64 | if (numstr == ep || *ep != '\0') |
60 | error = INVALID; | 65 | error = INVALID; |
61 | else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) | 66 | else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) |
@@ -64,6 +69,7 @@ strtonum(const char *numstr, long long minval, unsigned long long maxval, | |||
64 | error = TOOLARGE; | 69 | error = TOOLARGE; |
65 | ull = (unsigned long long)ll; | 70 | ull = (unsigned long long)ll; |
66 | } | 71 | } |
72 | done: | ||
67 | if (errstrp != NULL) | 73 | if (errstrp != NULL) |
68 | *errstrp = ev[error].errstr; | 74 | *errstrp = ev[error].errstr; |
69 | errno = ev[error].err; | 75 | errno = ev[error].err; |