summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib/strtoq.c
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>1995-12-21 14:58:36 +0000
committerderaadt <deraadt@openbsd.org>1995-12-21 14:58:36 +0000
commite3237c4acb5ad72dd1ccb9c6fd984121fe0817e6 (patch)
tree1501604c53a9d8bdf136ba4eb06aa4f111b841b5 /lib/libc/stdlib/strtoq.c
parentfrom netbsd; limit the flags that get passed to cpp (diff)
downloadwireguard-openbsd-e3237c4acb5ad72dd1ccb9c6fd984121fe0817e6.tar.xz
wireguard-openbsd-e3237c4acb5ad72dd1ccb9c6fd984121fe0817e6.zip
from netbsd; Rearrange to avoid sign problems with GCC.
Diffstat (limited to 'lib/libc/stdlib/strtoq.c')
-rw-r--r--lib/libc/stdlib/strtoq.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/lib/libc/stdlib/strtoq.c b/lib/libc/stdlib/strtoq.c
index fc559e9d7f0..003c020d719 100644
--- a/lib/libc/stdlib/strtoq.c
+++ b/lib/libc/stdlib/strtoq.c
@@ -37,9 +37,9 @@ static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92";
#include <sys/types.h>
-#include <limits.h>
-#include <errno.h>
#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
#include <stdlib.h>
/*
@@ -55,9 +55,8 @@ strtoq(nptr, endptr, base)
register int base;
{
register const char *s;
- register u_quad_t acc;
+ register quad_t acc, cutoff;
register int c;
- register u_quad_t qbase, cutoff;
register int neg, any, cutlim;
/*
@@ -104,10 +103,16 @@ strtoq(nptr, endptr, base)
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
- qbase = (unsigned)base;
- cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX;
- cutlim = cutoff % qbase;
- cutoff /= qbase;
+ cutoff = neg ? QUAD_MIN : QUAD_MAX;
+ cutlim = cutoff % base;
+ cutoff /= base;
+ if (neg) {
+ if (cutlim > 0) {
+ cutlim -= base;
+ cutoff += 1;
+ }
+ cutlim = -cutlim;
+ }
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
@@ -117,19 +122,30 @@ strtoq(nptr, endptr, base)
break;
if (c >= base)
break;
- if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
- any = -1;
- else {
- any = 1;
- acc *= qbase;
- acc += c;
+ if (any < 0)
+ continue;
+ if (neg) {
+ if (acc < cutoff || acc == cutoff && c > cutlim) {
+ any = -1;
+ acc = QUAD_MIN;
+ errno = ERANGE;
+ } else {
+ any = 1;
+ acc *= base;
+ acc -= c;
+ }
+ } else {
+ if (acc > cutoff || acc == cutoff && c > cutlim) {
+ any = -1;
+ acc = QUAD_MAX;
+ errno = ERANGE;
+ } else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
}
}
- if (any < 0) {
- acc = neg ? QUAD_MIN : QUAD_MAX;
- errno = ERANGE;
- } else if (neg)
- acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);