From 32bc1dc40ecac60ca0fe3903d20722f1a489fdc6 Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 14 Mar 2009 18:12:55 +0000 Subject: [PATCH] sprinkle mksh_ari_t to limit arithmetics to 32 bit even on Debian Lenny/amd64 (XXX need more verification; this can be used for 64 bit arithmetics later too) PPID, PGRP, RANDOM, USER_ID are now unsigned by default --- check.t | 31 +++++++++++++++++++++++++++++-- eval.c | 4 ++-- expr.c | 14 +++++++------- funcs.c | 10 +++++----- main.c | 12 ++++++------ misc.c | 4 +++- mksh.1 | 22 +++++++++++++--------- sh.h | 20 ++++++++++++-------- shf.c | 16 ++++++++-------- var.c | 34 +++++++++++++++++----------------- 10 files changed, 102 insertions(+), 65 deletions(-) diff --git a/check.t b/check.t index 12c8a4a..4b1746a 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.256 2009/02/22 18:02:30 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.257 2009/03/14 18:12:50 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -7,7 +7,7 @@ # http://www.research.att.com/~gsf/public/ifs.sh expected-stdout: - @(#)MIRBSD KSH R36 2009/02/22 + @(#)MIRBSD KSH R36 2009/03/14 description: Check version of shell. stdin: @@ -277,6 +277,33 @@ expected-stdout: x6 1975973142 1975973142 x7 right --- +name: arith-limit32-1 +description: + Check if arithmetics are 32 bit +stdin: + # signed vs unsigned + print x1 $((-1)) $((#-1)) + # calculating + typeset -i vs + typeset -Ui vu + vs=2147483647; vu=2147483647 + print x2 $vs $vu + let vs++ vu++ + print x3 $vs $vu + vs=4294967295; vu=4294967295 + print x4 $vs $vu + let vs++ vu++ + print x5 $vs $vu + let vs++ vu++ + print x6 $vs $vu +expected-stdout: + x1 -1 4294967295 + x2 2147483647 2147483647 + x3 -2147483648 2147483648 + x4 -1 4294967295 + x5 0 0 + x6 1 1 +--- name: bksl-nl-ign-1 description: Check that \newline is not collasped after # diff --git a/eval.c b/eval.c index 13df077..161891f 100644 --- a/eval.c +++ b/eval.c @@ -2,7 +2,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.51 2008/12/13 17:02:13 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.52 2009/03/14 18:12:51 tg Exp $"); #ifdef MKSH_SMALL #define MKSH_NOPWNAM @@ -314,7 +314,7 @@ expand(const char *cp, /* input word */ switch (stype & 0x7f) { case '0': { char *beg, *mid, *end, *stg; - long from = 0, num = -1, flen; + mksh_ari_t from = 0, num = -1, flen; /* ! DOBLANK,DOBRACE_,DOTILDE */ f = DOPAT | (f&DONTRUNCOMMAND) | diff --git a/expr.c b/expr.c index 829d424..599bd48 100644 --- a/expr.c +++ b/expr.c @@ -2,7 +2,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.22 2008/12/17 19:39:21 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.23 2009/03/14 18:12:52 tg Exp $"); /* The order of these enums is constrained by the order of opinfo[] */ enum token { @@ -117,9 +117,9 @@ struct expr_state { bool natural; /* unsigned arithmetic calculation */ }; -#define bivui(x, op, y) (es->natural ? \ - (long)((x)->val.u op (y)->val.u) : \ - (long)((x)->val.i op (y)->val.i) \ +#define bivui(x, op, y) (es->natural ? \ + (mksh_ari_t)((x)->val.u op (y)->val.u) : \ + (mksh_ari_t)((x)->val.i op (y)->val.i) \ ) #define chvui(x, op) do { \ if (es->natural) \ @@ -152,7 +152,7 @@ static struct tbl *intvar(Expr_state *, struct tbl *); * parse and evaluate expression */ int -evaluate(const char *expr, long int *rval, int error_ok, bool arith) +evaluate(const char *expr, mksh_ari_t *rval, int error_ok, bool arith) { struct tbl v; int ret; @@ -284,7 +284,7 @@ evalexpr(Expr_state *es, int prec) { struct tbl *vl, *vr = NULL, *vasn; enum token op; - long res = 0; + mksh_ari_t res = 0; if (prec == P_PRIMARY) { op = es->tok; @@ -542,7 +542,7 @@ static struct tbl * do_ppmm(Expr_state *es, enum token op, struct tbl *vasn, bool is_prefix) { struct tbl *vl; - long oval; + mksh_ari_t oval; assign_check(es, op, vasn); diff --git a/funcs.c b/funcs.c index c2be45f..4655bc0 100644 --- a/funcs.c +++ b/funcs.c @@ -5,7 +5,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.93 2008/12/13 17:02:14 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.94 2009/03/14 18:12:52 tg Exp $"); /* A leading = means assignments before command are kept; * a leading * means a POSIX special builtin; @@ -1183,7 +1183,7 @@ int c_let(const char **wp) { int rv = 1; - long val; + mksh_ari_t val; if (wp[1] == NULL) /* at&t ksh does this */ bi_errorf("no arguments"); @@ -1524,7 +1524,7 @@ c_shift(const char **wp) { struct block *l = e->loc; int n; - long val; + mksh_ari_t val; const char *arg; if (ksh_getopt(wp, &builtin_opt, null) == '?') @@ -2533,7 +2533,7 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, int i, s; size_t k; struct stat b1, b2; - long v1, v2; + mksh_ari_t v1, v2; if (!do_eval) return 0; @@ -2965,7 +2965,7 @@ set_ulimit(const struct limits *l, const char *v, int how) if (strcmp(v, "unlimited") == 0) val = (rlim_t)RLIM_INFINITY; else { - long rval; + mksh_ari_t rval; if (!evaluate(v, &rval, KSH_RETURN_ERROR, false)) return (1); diff --git a/main.c b/main.c index 4cd7504..7030c09 100644 --- a/main.c +++ b/main.c @@ -13,7 +13,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.119 2008/12/29 21:34:20 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.120 2009/03/14 18:12:53 tg Exp $"); extern char **environ; @@ -32,8 +32,8 @@ static const char initsubs[] = "${PS2=> } ${PS3=#? } ${PS4=+ }"; static const char *initcoms[] = { "typeset", "-r", initvsn, NULL, "typeset", "-x", "SHELL", "PATH", "HOME", NULL, - "typeset", "-i10", "COLUMNS=0", "LINES=0", "OPTIND=1", "PGRP", "PPID", - "RANDOM", "USER_ID", NULL, + "typeset", "-i10", "COLUMNS=0", "LINES=0", "OPTIND=1", NULL, + "typeset", "-Ui10", "PGRP", "PPID", "RANDOM", "USER_ID", NULL, "eval", "typeset -i10 SECONDS=\"${SECONDS-0}\" TMOUT=\"${TMOUT-0}\"", NULL, "alias", "integer=typeset -i", "local=typeset", NULL, @@ -250,9 +250,9 @@ main(int argc, const char *argv[]) (!ksheuid && !strchr(str_val(vp), '#'))) /* setstr can't fail here */ setstr(vp, safe_prompt, KSH_RETURN_ERROR); - setint(global("PGRP"), (long)(kshpgrp = getpgrp())); - setint(global("PPID"), (long)ppid); - setint(global("USER_ID"), (long)ksheuid); + setint(global("PGRP"), (mksh_uari_t)(kshpgrp = getpgrp())); + setint(global("PPID"), (mksh_uari_t)ppid); + setint(global("USER_ID"), (mksh_uari_t)ksheuid); /* Set this before parsing arguments */ #if HAVE_SETRESUGID diff --git a/misc.c b/misc.c index f3707cc..9e1b200 100644 --- a/misc.c +++ b/misc.c @@ -6,7 +6,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.96 2009/02/22 18:53:03 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.97 2009/03/14 18:12:53 tg Exp $"); #undef USE_CHVT #if defined(TIOCSCTTY) && !defined(MKSH_SMALL) @@ -1390,6 +1390,8 @@ chvt(const char *fn) #ifdef DEBUG char longsizes_are_okay[sizeof (long) == sizeof (unsigned long) ? 1 : -1]; +char arisize_is_okay[sizeof (mksh_ari_t) == 4 ? 1 : -1]; +char uarisize_is_okay[sizeof (mksh_uari_t) == 4 ? 1 : -1]; char * strchr(char *p, int ch) diff --git a/mksh.1 b/mksh.1 index ae4eba8..398a822 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.149 2008/12/29 21:34:20 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.150 2009/03/14 18:12:53 tg Exp $ .\" $OpenBSD: ksh.1,v 1.122 2008/05/17 23:31:52 sobrado Exp $ .\"- .\" Try to make GNU groff and AT&T nroff more compatible @@ -30,7 +30,7 @@ .el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 .. .\"- -.Dd $Mdocdate: December 29 2008 $ +.Dd $Mdocdate: March 14 2009 $ .Dt MKSH 1 .Os MirBSD .Sh NAME @@ -2098,11 +2098,12 @@ as numeric arguments to the command, and as the value of an assignment to an integer parameter. .Pp Expressions are calculated using signed arithmetic and the -.Vt long -host type, unless they begin with a sole +.Vt mksh_ari_t +type (a 32-bit signed integer), unless they begin with a sole .Sq # character, in which case they use -.Vt unsigned long . +.Vt mksh_uari_t +.Po a 32-bit unsigned integer Pc . .Pp Expressions may contain alpha-numeric parameter identifiers, array references, and integer constants and may be combined with the following C operators @@ -2139,10 +2140,13 @@ Grouping operators: ( ) .Ed .Pp -Currently, integer constants and expressions are calculated using the host -.Vt long -type, although some places, such as array indices, may limit them to 32 bits. -They can be signed or unsigned. +Integer constants and expressions are calculated using the +.Vt mksh_ari_t +.Po if signed Pc +or +.Vt mksh_uari_t +.Po if unsigned Pc +type, and are limited to 32 bits. Overflows wrap silently. Integer constants may be specified with arbitrary bases using the notation .Ar base Ns # Ns Ar number , diff --git a/sh.h b/sh.h index 8051987..b59f3d7 100644 --- a/sh.h +++ b/sh.h @@ -102,9 +102,9 @@ #define __SCCSID(x) __IDSTRING(sccsid,x) #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.274 2009/02/22 18:02:31 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.275 2009/03/14 18:12:54 tg Exp $"); #endif -#define MKSH_VERSION "R36 2009/02/22" +#define MKSH_VERSION "R36 2009/03/14" #ifndef MKSH_INCLUDES_ONLY @@ -262,6 +262,10 @@ extern int __cdecl setegid(gid_t); /* Table flag type - needs > 16 and < 32 bits */ typedef int32_t Tflag; +/* arithmetics types */ +typedef int32_t mksh_ari_t; +typedef uint32_t mksh_uari_t; + /* these shall be smaller than 100 */ #ifdef MKSH_SMALL #define NUFILE 32 /* Number of user-accessible files */ @@ -775,8 +779,8 @@ struct tbl { /* table item */ Area *areap; /* area to allocate from */ union { char *s; /* string */ - long i; /* integer */ - unsigned long u; /* unsigned integer */ + mksh_ari_t i; /* integer */ + mksh_uari_t u; /* unsigned integer */ int (*f)(const char **);/* int function */ struct op *t; /* "function" tree */ } val; /* value */ @@ -1297,7 +1301,7 @@ int search_access(const char *, int, int *); int pr_menu(const char *const *); int pr_list(char *const *); /* expr.c */ -int evaluate(const char *, long *, int, bool); +int evaluate(const char *, mksh_ari_t *, int, bool); int v_evaluate(struct tbl *, const char *, volatile int, bool); /* funcs.c */ int c_hash(const char **); @@ -1528,11 +1532,11 @@ void initvar(void); struct tbl *global(const char *); struct tbl *local(const char *, bool); char *str_val(struct tbl *); -long intval(struct tbl *); +mksh_ari_t intval(struct tbl *); int setstr(struct tbl *, const char *, int); struct tbl *setint_v(struct tbl *, struct tbl *, bool); -void setint(struct tbl *, long); -int getint(struct tbl *, long *, bool); +void setint(struct tbl *, mksh_ari_t); +int getint(struct tbl *, mksh_ari_t *, bool); struct tbl *typeset(const char *, Tflag, Tflag, int, int); void unset(struct tbl *, int); const char *skip_varname(const char *, int); diff --git a/shf.c b/shf.c index b45f7be..c50c5ff 100644 --- a/shf.c +++ b/shf.c @@ -2,7 +2,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.24 2008/12/13 17:02:17 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.25 2009/03/14 18:12:55 tg Exp $"); /* flags to shf_emptybuf() */ #define EB_READSW 0x01 /* about to switch to reading */ @@ -728,7 +728,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) int tmp = 0, field, precision, len, flags; unsigned long lnum; /* %#o produces the longest output */ - char numbuf[(8 * sizeof(long) + 2) / 3 + 1]; + char numbuf[(8 * sizeof (long) + 2) / 3 + 1]; /* this stuff for dealing with the buffer */ int nwritten = 0; @@ -847,18 +847,18 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) if (flags & FL_LONG) lnum = va_arg(args, unsigned long); else if ((sizeof (int) < sizeof (long)) && (c == 'd')) - lnum = (long) va_arg(args, int); + lnum = (long)va_arg(args, int); else lnum = va_arg(args, unsigned int); switch (c) { case 'd': case 'i': - if (0 > (long) lnum) - lnum = - (long) lnum, tmp = 1; - else + if (0 > (long)lnum) { + lnum = -(long)lnum; + tmp = 1; + } else tmp = 0; - /* aaahhhh..... */ - + /* FALLTHROUGH */ case 'u': do { *--cp = lnum % 10 + '0'; diff --git a/var.c b/var.c index 912f6dd..106c145 100644 --- a/var.c +++ b/var.c @@ -2,7 +2,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.68 2008/12/29 21:34:22 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.69 2009/03/14 18:12:55 tg Exp $"); /* * Variables @@ -127,7 +127,7 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp) p = skip_varname(n, false); if (p != n && *p == '[' && (len = array_ref_len(p))) { char *sub, *tmp; - long rval; + mksh_ari_t rval; /* Calculate the value of the subscript */ *arrayp = true; @@ -284,17 +284,17 @@ str_val(struct tbl *vp) s = vp->val.s + vp->type; else { /* integer source */ /* worst case number length is when base=2, so use BITS(long) */ - /* minus base # number null */ - char strbuf[1 + 2 + 1 + 8 * sizeof(long) + 1]; + /* minus base # number NUL */ + char strbuf[1 + 2 + 1 + 8 * sizeof (mksh_uari_t) + 1]; const char *digits = (vp->flag & UCASEV_AL) ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "0123456789abcdefghijklmnopqrstuvwxyz"; - unsigned long n; + mksh_uari_t n; int base; s = strbuf + sizeof(strbuf); if (vp->flag & INT_U) - n = (unsigned long) vp->val.i; + n = vp->val.u; else n = (vp->val.i < 0) ? -vp->val.i : vp->val.i; base = (vp->type == 0) ? 10 : vp->type; @@ -333,17 +333,17 @@ str_val(struct tbl *vp) } /* get variable integer value, with error checking */ -long +mksh_ari_t intval(struct tbl *vp) { - long num; + mksh_ari_t num; int base; base = getint(vp, &num, false); if (base == -1) /* XXX check calls - is error here ok by POSIX? */ errorf("%s: bad number", str_val(vp)); - return num; + return (num); } /* set variable to string value */ @@ -393,7 +393,7 @@ setstr(struct tbl *vq, const char *s, int error_ok) /* set variable to integer */ void -setint(struct tbl *vq, long int n) +setint(struct tbl *vq, mksh_ari_t n) { if (!(vq->flag&INTEGER)) { struct tbl *vp = &vtemp; @@ -411,12 +411,12 @@ setint(struct tbl *vq, long int n) } int -getint(struct tbl *vp, long int *nump, bool arith) +getint(struct tbl *vp, mksh_ari_t *nump, bool arith) { char *s; int c, base, neg; bool have_base = false; - long num; + mksh_ari_t num; if (vp->flag&SPECIAL) getspec(vp); @@ -460,7 +460,7 @@ getint(struct tbl *vp, long int *nump, bool arith) wc = *(unsigned char *)s; else if (utf_mbtowc(&wc, s) == (size_t)-1) wc = 0xEF00 + *(unsigned char *)s; - *nump = (long)wc; + *nump = (mksh_ari_t)wc; return (1); } num = 0; @@ -491,7 +491,7 @@ struct tbl * setint_v(struct tbl *vq, struct tbl *vp, bool arith) { int base; - long num; + mksh_ari_t num; if ((base = getint(vp, &num, arith)) == -1) return NULL; @@ -1051,17 +1051,17 @@ getspec(struct tbl *vp) break; case V_HISTSIZE: vp->flag &= ~SPECIAL; - setint(vp, (long)histsize); + setint(vp, (mksh_ari_t)histsize); vp->flag |= SPECIAL; break; case V_OPTIND: vp->flag &= ~SPECIAL; - setint(vp, (long)user_opt.uoptind); + setint(vp, (mksh_ari_t)user_opt.uoptind); vp->flag |= SPECIAL; break; case V_LINENO: vp->flag &= ~SPECIAL; - setint(vp, (long)current_lineno + user_lineno); + setint(vp, (mksh_ari_t)current_lineno + user_lineno); vp->flag |= SPECIAL; break; case V_COLUMNS: