Browse Source

It's not really possible to make strtonum() deal with unsigned long

long values properly so don't bother trying.  This greatly simplifies
the code.  tedu@ OK with input from otto@ and others.
OPENBSD_3_6
millert 20 years ago
parent
commit
b6d4073b5f
2 changed files with 21 additions and 35 deletions
  1. +11
    -8
      src/lib/libc/stdlib/strtonum.3
  2. +10
    -27
      src/lib/libc/stdlib/strtonum.c

+ 11
- 8
src/lib/libc/stdlib/strtonum.3 View File

@ -1,4 +1,4 @@
.\" $OpenBSD: strtonum.3,v 1.5 2004/05/06 06:19:01 tedu Exp $
.\" $OpenBSD: strtonum.3,v 1.6 2004/08/03 19:38:01 millert Exp $
.\"
.\" Copyright (c) 2004 Ted Unangst
.\"
@ -23,11 +23,11 @@
.Sh SYNOPSIS
.Fd #include <stdlib.h>
.Fd #include <limits.h>
.Ft unsigned long long
.Ft long long
.Fo strtonum
.Fa "const char *nptr"
.Fa "long long minval"
.Fa "unsigned long long maxval"
.Fa "long long maxval"
.Fa "const char **errstr"
.Fc
.Sh DESCRIPTION
@ -35,10 +35,9 @@ The
.Fn strtonum
function converts the string in
.Fa nptr
to an
.Li unsigned long long
to a
.Li long long
value.
Negative values may be obtained by casting the result.
The
.Fn strtonum
function was designed to facilitate safe, robust programming
@ -57,8 +56,8 @@ or
.Ql -
sign.
.Pp
The remainder of the string is converted to an
.Li unsigned long long
The remainder of the string is converted to a
.Li long long
value according to base 10.
.Pp
The value obtained is then checked against the provided
@ -102,6 +101,10 @@ The above example will guarantee that the value of iterations is between
The given string was out of range.
.It Bq Er EINVAL
The given string did not consist solely of digit characters.
.It Bq Er EINVAL
.Ar minval
was larger than
.Ar maxval .
.El
.Pp
If an error occurs, errstr will be set to one of the following strings.


+ 10
- 27
src/lib/libc/stdlib/strtonum.c View File

@ -1,4 +1,5 @@
/* $OpenBSD: strtonum.c,v 1.5 2004/07/16 18:36:05 otto Exp $ */
/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
/*
* Copyright (c) 2004 Ted Unangst and Todd Miller
* All rights reserved.
@ -24,12 +25,11 @@
#define TOOSMALL 2
#define TOOLARGE 3
unsigned long long
strtonum(const char *numstr, long long minval, unsigned long long umaxval,
long long
strtonum(const char *numstr, long long minval, long long maxval,
const char **errstrp)
{
long long ll, maxval = (long long)umaxval;
unsigned long long ull = 0;
long long ll = 0;
char *ep;
int error = 0;
struct errval {
@ -44,24 +44,9 @@ strtonum(const char *numstr, long long minval, unsigned long long umaxval,
ev[0].err = errno;
errno = 0;
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 > umaxval)
error = TOOLARGE;
else if (ull < minval)
error = TOOSMALL;
} else {
if (minval > maxval || maxval < minval) {
error = INVALID;
goto done;
}
if (minval > maxval)
error = INVALID;
else {
ll = strtoll(numstr, &ep, 10);
if (numstr == ep || *ep != '\0')
error = INVALID;
@ -69,14 +54,12 @@ strtonum(const char *numstr, long long minval, unsigned long long umaxval,
error = TOOSMALL;
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
error = TOOLARGE;
ull = (unsigned long long)ll;
}
done:
if (errstrp != NULL)
*errstrp = ev[error].errstr;
errno = ev[error].err;
if (error)
ull = 0;
ll = 0;
return (ull);
return (ll);
}

Loading…
Cancel
Save