summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillert <>2004-07-16 16:03:36 +0000
committermillert <>2004-07-16 16:03:36 +0000
commit5324f527aa491efaf55f123392b79694bc7fca89 (patch)
treed211ca202a6ae4364ac84885940682f85079a463
parente908c5a3dbc60cd83730f45e3ac72f1d79ec5faa (diff)
downloadopenbsd-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.c30
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
27unsigned long long 27unsigned long long
28strtonum(const char *numstr, long long minval, unsigned long long maxval, 28strtonum(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 }
72done:
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;