diff options
| -rw-r--r-- | bin/expr/expr.y | 59 | ||||
| -rw-r--r-- | bin/test/test.c | 56 | ||||
| -rw-r--r-- | usr.bin/printf/printf.c | 31 |
3 files changed, 96 insertions, 50 deletions
diff --git a/bin/expr/expr.y b/bin/expr/expr.y index 117270a14f77..5f453733cebc 100644 --- a/bin/expr/expr.y +++ b/bin/expr/expr.y @@ -7,12 +7,14 @@ * $FreeBSD$ */ +#include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> #include <ctype.h> #include <err.h> +#include <regex.h> enum valtype { integer, numeric_string, string @@ -22,7 +24,7 @@ struct val { enum valtype type; union { char *s; - int i; + quad_t i; } u; } ; @@ -87,7 +89,7 @@ expr: TOKEN struct val * make_integer (i) -int i; +quad_t i; { struct val *vp; @@ -139,11 +141,11 @@ struct val *vp; } -int +quad_t to_integer (vp) struct val *vp; { - int i; + quad_t i; if (vp->type == integer) return 1; @@ -152,7 +154,7 @@ struct val *vp; return 0; /* vp->type == numeric_string, make it numeric */ - i = atoi(vp->u.s); + i = strtoq(vp->u.s, (char**)NULL, 10); free (vp->u.s); vp->u.i = i; vp->type = integer; @@ -173,7 +175,7 @@ struct val *vp; errx (2, "malloc() failed"); } - sprintf (tmp, "%d", vp->u.i); + sprintf (tmp, "%qd", vp->u.i); vp->type = string; vp->u.s = tmp; } @@ -239,7 +241,7 @@ char **argv; yyparse (); if (result->type == integer) - printf ("%d\n", result->u.i); + printf ("%qd\n", result->u.i); else printf ("%s\n", result->u.s); @@ -274,7 +276,7 @@ struct val *a, *b; if (is_zero_or_null (a) || is_zero_or_null (b)) { free_value (a); free_value (b); - return (make_integer (0)); + return (make_integer ((quad_t)0)); } else { free_value (b); return (a); @@ -290,11 +292,11 @@ struct val *a, *b; if (isstring (a) || isstring (b)) { to_string (a); to_string (b); - r = make_integer (strcoll (a->u.s, b->u.s) == 0); + r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0)); } else { (void)to_integer(a); (void)to_integer(b); - r = make_integer (a->u.i == b->u.i); + r = make_integer ((quad_t)(a->u.i == b->u.i)); } free_value (a); @@ -311,11 +313,11 @@ struct val *a, *b; if (isstring (a) || isstring (b)) { to_string (a); to_string (b); - r = make_integer (strcoll (a->u.s, b->u.s) > 0); + r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0)); } else { (void)to_integer(a); (void)to_integer(b); - r= make_integer (a->u.i > b->u.i); + r = make_integer ((quad_t)(a->u.i > b->u.i)); } free_value (a); @@ -332,11 +334,11 @@ struct val *a, *b; if (isstring (a) || isstring (b)) { to_string (a); to_string (b); - r = make_integer (strcoll (a->u.s, b->u.s) < 0); + r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0)); } else { (void)to_integer(a); (void)to_integer(b); - r = make_integer (a->u.i < b->u.i); + r = make_integer ((quad_t)(a->u.i < b->u.i)); } free_value (a); @@ -353,11 +355,11 @@ struct val *a, *b; if (isstring (a) || isstring (b)) { to_string (a); to_string (b); - r = make_integer (strcoll (a->u.s, b->u.s) >= 0); + r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0)); } else { (void)to_integer(a); (void)to_integer(b); - r = make_integer (a->u.i >= b->u.i); + r = make_integer ((quad_t)(a->u.i >= b->u.i)); } free_value (a); @@ -374,11 +376,11 @@ struct val *a, *b; if (isstring (a) || isstring (b)) { to_string (a); to_string (b); - r = make_integer (strcoll (a->u.s, b->u.s) <= 0); + r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0)); } else { (void)to_integer(a); (void)to_integer(b); - r = make_integer (a->u.i <= b->u.i); + r = make_integer ((quad_t)(a->u.i <= b->u.i)); } free_value (a); @@ -395,11 +397,11 @@ struct val *a, *b; if (isstring (a) || isstring (b)) { to_string (a); to_string (b); - r = make_integer (strcoll (a->u.s, b->u.s) != 0); + r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0)); } else { (void)to_integer(a); (void)to_integer(b); - r = make_integer (a->u.i != b->u.i); + r = make_integer ((quad_t)(a->u.i != b->u.i)); } free_value (a); @@ -417,7 +419,7 @@ struct val *a, *b; errx (2, "non-numeric argument"); } - r = make_integer (a->u.i + b->u.i); + r = make_integer (/*(quad_t)*/(a->u.i + b->u.i)); free_value (a); free_value (b); return r; @@ -433,7 +435,7 @@ struct val *a, *b; errx (2, "non-numeric argument"); } - r = make_integer (a->u.i - b->u.i); + r = make_integer (/*(quad_t)*/(a->u.i - b->u.i)); free_value (a); free_value (b); return r; @@ -449,7 +451,7 @@ struct val *a, *b; errx (2, "non-numeric argument"); } - r = make_integer (a->u.i * b->u.i); + r = make_integer (/*(quad_t)*/(a->u.i * b->u.i)); free_value (a); free_value (b); return (r); @@ -469,7 +471,7 @@ struct val *a, *b; errx (2, "division by zero"); } - r = make_integer (a->u.i / b->u.i); + r = make_integer (/*(quad_t)*/(a->u.i / b->u.i)); free_value (a); free_value (b); return r; @@ -489,15 +491,12 @@ struct val *a, *b; errx (2, "division by zero"); } - r = make_integer (a->u.i % b->u.i); + r = make_integer (/*(quad_t)*/(a->u.i % b->u.i)); free_value (a); free_value (b); return r; } -#include <sys/types.h> -#include <regex.h> - struct val * op_colon (a, b) struct val *a, *b; @@ -526,11 +525,11 @@ struct val *a, *b; v = make_str (a->u.s + rm[1].rm_so); } else { - v = make_integer (rm[0].rm_eo - rm[0].rm_so); + v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so)); } } else { if (rp.re_nsub == 0) { - v = make_integer (0); + v = make_integer ((quad_t)0); } else { v = make_str (""); } diff --git a/bin/test/test.c b/bin/test/test.c index c9df4e3cb758..73e6ebf935df 100644 --- a/bin/test/test.c +++ b/bin/test/test.c @@ -153,6 +153,8 @@ static int binop __P((void)); static int filstat __P((char *, enum token)); static int isoperand __P((void)); static int getn __P((const char *)); +static quad_t getq __P((const char *)); +static int intcmp __P((const char *, const char *)); static int newerf __P((const char *, const char *)); static int olderf __P((const char *, const char *)); static int equalf __P((const char *, const char *)); @@ -298,17 +300,17 @@ binop() case STRGT: return strcmp(opnd1, opnd2) > 0; case INTEQ: - return getn(opnd1) == getn(opnd2); + return intcmp(opnd1, opnd2) == 0; case INTNE: - return getn(opnd1) != getn(opnd2); + return intcmp(opnd1, opnd2) != 0; case INTGE: - return getn(opnd1) >= getn(opnd2); + return intcmp(opnd1, opnd2) >= 0; case INTGT: - return getn(opnd1) > getn(opnd2); + return intcmp(opnd1, opnd2) > 0; case INTLE: - return getn(opnd1) <= getn(opnd2); + return intcmp(opnd1, opnd2) <= 0; case INTLT: - return getn(opnd1) < getn(opnd2); + return intcmp(opnd1, opnd2) < 0; case FILNT: return newerf (opnd1, opnd2); case FILOT: @@ -443,6 +445,48 @@ getn(s) return (int) r; } +/* atoi with error detection and 64 bit range */ +static quad_t +getq(s) + const char *s; +{ + char *p; + quad_t r; + + errno = 0; + r = strtoq(s, &p, 10); + + if (errno != 0) + errx(2, "%s: out of range", s); + + while (isspace((unsigned char)*p)) + p++; + + if (*p) + errx(2, "%s: bad number", s); + + return r; +} + +static int +intcmp (s1, s2) + const char *s1, *s2; +{ + quad_t q1, q2; + + + q1 = getq(s1); + q2 = getq(s2); + + if (q1 > q2) + return 1; + + if (q1 < q2) + return -1; + + return 0; +} + static int newerf (f1, f2) const char *f1, *f2; diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c index f135f569fdf6..df65f5a886af 100644 --- a/usr.bin/printf/printf.c +++ b/usr.bin/printf/printf.c @@ -86,7 +86,7 @@ static void escape __P((char *)); static int getchr __P((void)); static double getdouble __P((void)); static int getint __P((int *)); -static int getlong __P((long *)); +static int getquad __P((quad_t *)); static char *getstr __P((void)); static char *mklong __P((char *, int)); static void usage __P((void)); @@ -214,12 +214,12 @@ next: for (start = fmt;; ++fmt) { break; } case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { - long p; + quad_t p; char *f; if ((f = mklong(start, convch)) == NULL) return (1); - if (getlong(&p)) + if (getquad(&p)) return (1); PF(f, p); break; @@ -249,8 +249,11 @@ mklong(str, ch) int len; len = strlen(str) + 2; + if (len > sizeof copy) + return NULL; + memmove(copy, str, len - 3); - copy[len - 3] = 'l'; + copy[len - 3] = 'q'; copy[len - 2] = ch; copy[len - 1] = '\0'; return (copy); @@ -338,23 +341,23 @@ static int getint(ip) int *ip; { - long val; + quad_t val; - if (getlong(&val)) + if (getquad(&val)) return (1); - if (val > INT_MAX) { + if (val < INT_MIN || val > INT_MAX) { warnx3("%s: %s", *gargv, strerror(ERANGE)); return (1); } - *ip = val; + *ip = (int)val; return (0); } static int -getlong(lp) - long *lp; +getquad(lp) + quad_t *lp; { - long val; + quad_t val; char *ep; if (!*gargv) { @@ -363,17 +366,17 @@ getlong(lp) } if (strchr(Number, **gargv)) { errno = 0; - val = strtol(*gargv, &ep, 0); + val = strtoq(*gargv, &ep, 0); if (*ep != '\0') { warnx2("%s: illegal number", *gargv, NULL); return (1); } if (errno == ERANGE) - if (val == LONG_MAX) { + if (val == QUAD_MAX) { warnx3("%s: %s", *gargv, strerror(ERANGE)); return (1); } - if (val == LONG_MIN) { + if (val == QUAD_MIN) { warnx3("%s: %s", *gargv, strerror(ERANGE)); return (1); } |
