Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible overflow issue on expressions. #101

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions sh.decls.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ extern int find_cmd (Char *, int);
* sh.exp.c
*/
extern Char *filetest (Char *, Char ***, int);
extern tcsh_number_t expr (Char ***);
extern tcsh_number_t exp0 (Char ***, int);
extern unsigned tcsh_number_t expr (Char ***);
extern unsigned tcsh_number_t exp0 (Char ***, int);

/*
* sh.file.c
Expand Down Expand Up @@ -379,8 +379,8 @@ extern void mypipe (int *);
extern struct varent *adrof1 (const Char *, struct varent *);
extern void doset (Char **, struct command *);
extern void dolet (Char **, struct command *);
extern Char *putn (tcsh_number_t);
extern tcsh_number_t getn (const Char *);
extern Char *putn (unsigned tcsh_number_t);
extern unsigned tcsh_number_t getn (const Char *);
extern Char *value1 (Char *, struct varent *);
extern void setcopy (const Char *, const Char *, int);
extern void setv (const Char *, Char *, int);
Expand Down
7 changes: 5 additions & 2 deletions sh.err.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ extern int enterhist;
#define ERR_BADCOLORVAR 134
#define ERR_EOF 135
#define ERR_UNAVAILABLE 136
#define NO_ERRORS 137
#define ERR_DIVOF 137
#define ERR_MODOF 138
#define NO_ERRORS 139

static const char *elst[NO_ERRORS] INIT_ZERO_STRUCT;

Expand Down Expand Up @@ -367,7 +369,8 @@ errinit(void)
elst[ERR_BADCOLORVAR] = CSAVS(1, 137, "Unknown %s color variable '%c%c'");
elst[ERR_EOF] = CSAVS(1, 138, "Unexpected end of file");
elst[ERR_UNAVAILABLE] = CSAVS(1, 139, "%s: Feature is not available for this platform");

elst[ERR_DIVOF] = CSAVS(1, 140, "Division overflow");
elst[ERR_MODOF] = CSAVS(1, 141, "Mod overflow");
}

/* Cleanup data. */
Expand Down
140 changes: 99 additions & 41 deletions sh.exp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@
#define NOTEQMATCH 8

static int sh_access (const Char *, int);
static tcsh_number_t exp1 (Char ***, int);
static tcsh_number_t exp2x (Char ***, int);
static tcsh_number_t exp2a (Char ***, int);
static tcsh_number_t exp2b (Char ***, int);
static tcsh_number_t exp2c (Char ***, int);
static unsigned tcsh_number_t exp1 (Char ***, int);
static unsigned tcsh_number_t exp2x (Char ***, int);
static unsigned tcsh_number_t exp2a (Char ***, int);
static unsigned tcsh_number_t exp2b (Char ***, int);
static unsigned tcsh_number_t exp2c (Char ***, int);
static Char *exp3 (Char ***, int);
static Char *exp3a (Char ***, int);
static Char *exp4 (Char ***, int);
static Char *exp5 (Char ***, int);
static Char *exp6 (Char ***, int);
static void evalav (Char **);
static int isa (Char *, int);
static tcsh_number_t egetn (const Char *);
static unsigned tcsh_number_t egetn (const Char *);

#ifdef EDEBUG
static void etracc (const char *, const Char *, Char ***);
Expand Down Expand Up @@ -177,20 +177,20 @@ sh_access(const Char *fname, int mode)
#endif /* !POSIX */
}

tcsh_number_t
unsigned tcsh_number_t
expr(Char ***vp)
{
return (exp0(vp, 0));
}

tcsh_number_t
unsigned tcsh_number_t
exp0(Char ***vp, int ignore)
{
tcsh_number_t p1 = exp1(vp, ignore);
unsigned tcsh_number_t p1 = exp1(vp, ignore);

etraci("exp0 p1", p1, vp);
while (**vp && eq(**vp, STRor2)) {
int p2;
unsigned tcsh_number_t p2;

(*vp)++;

Expand All @@ -206,14 +206,14 @@ exp0(Char ***vp, int ignore)
return (p1);
}

static tcsh_number_t
static unsigned tcsh_number_t
exp1(Char ***vp, int ignore)
{
tcsh_number_t p1 = exp2x(vp, ignore);
unsigned tcsh_number_t p1 = exp2x(vp, ignore);

etraci("exp1 p1", p1, vp);
while (**vp && eq(**vp, STRand2)) {
tcsh_number_t p2;
unsigned tcsh_number_t p2;

(*vp)++;
p2 = compat_expr ?
Expand All @@ -230,14 +230,14 @@ exp1(Char ***vp, int ignore)
return (p1);
}

static tcsh_number_t
static unsigned tcsh_number_t
exp2x(Char ***vp, int ignore)
{
tcsh_number_t p1 = exp2a(vp, ignore);
unsigned tcsh_number_t p1 = exp2a(vp, ignore);

etraci("exp2x p1", p1, vp);
while (**vp && eq(**vp, STRor)) {
tcsh_number_t p2;
unsigned tcsh_number_t p2;

(*vp)++;
p2 = compat_expr ?
Expand All @@ -253,14 +253,14 @@ exp2x(Char ***vp, int ignore)
return (p1);
}

static tcsh_number_t
static unsigned tcsh_number_t
exp2a(Char ***vp, int ignore)
{
tcsh_number_t p1 = exp2b(vp, ignore);
unsigned tcsh_number_t p1 = exp2b(vp, ignore);

etraci("exp2a p1", p1, vp);
while (**vp && eq(**vp, STRcaret)) {
tcsh_number_t p2;
unsigned tcsh_number_t p2;

(*vp)++;
p2 = compat_expr ?
Expand All @@ -276,14 +276,14 @@ exp2a(Char ***vp, int ignore)
return (p1);
}

static tcsh_number_t
static unsigned tcsh_number_t
exp2b(Char ***vp, int ignore)
{
tcsh_number_t p1 = exp2c(vp, ignore);
unsigned tcsh_number_t p1 = exp2c(vp, ignore);

etraci("exp2b p1", p1, vp);
while (**vp && eq(**vp, STRand)) {
tcsh_number_t p2;
unsigned tcsh_number_t p2;

(*vp)++;
p2 = compat_expr ?
Expand All @@ -299,12 +299,12 @@ exp2b(Char ***vp, int ignore)
return (p1);
}

static tcsh_number_t
static unsigned tcsh_number_t
exp2c(Char ***vp, int ignore)
{
Char *p1 = exp3(vp, ignore);
Char *p2;
tcsh_number_t i;
unsigned tcsh_number_t i;

cleanup_push(p1, xfree);
etracc("exp2c p1", p1, vp);
Expand Down Expand Up @@ -346,7 +346,7 @@ static Char *
exp3(Char ***vp, int ignore)
{
Char *p1, *p2;
tcsh_number_t i;
unsigned tcsh_number_t i;

p1 = exp3a(vp, ignore);
etracc("exp3 p1", p1, vp);
Expand All @@ -362,21 +362,58 @@ exp3(Char ***vp, int ignore)
etracc("exp3 p2", p2, vp);
if (!(ignore & TEXP_IGNORE))
switch ((int)i) {
tcsh_number_t is;

case GTR:
i = egetn(p1) > egetn(p2);
if ((i = egetn(p1)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
is = -(tcsh_number_t) -i;
else
is = i;
if ((i = egetn(p2)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
i = is > -(tcsh_number_t) -i;
else
i = is > (tcsh_number_t) i;
break;

case GTR | 1:
i = egetn(p1) >= egetn(p2);
if ((i = egetn(p1)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
is = -(tcsh_number_t) -i;
else
is = i;
if ((i = egetn(p2)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
i = is >= -(tcsh_number_t) -i;
else
i = is >= (tcsh_number_t) i;
break;

case LSS:
i = egetn(p1) < egetn(p2);
if ((i = egetn(p1)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
is = -(tcsh_number_t) -i;
else
is = i;
if ((i = egetn(p2)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
i = is < -(tcsh_number_t) -i;
else
i = is < (tcsh_number_t) i;
break;

case LSS | 1:
i = egetn(p1) <= egetn(p2);
if ((i = egetn(p1)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
is = -(tcsh_number_t) -i;
else
is = i;
if ((i = egetn(p2)) &
~(~(unsigned tcsh_number_t) 0 >> 1))
i = is <= -(tcsh_number_t) -i;
else
i = is <= (tcsh_number_t) i;
break;
}
cleanup_until(p1);
Expand All @@ -393,7 +430,7 @@ exp3a(Char ***vp, int ignore)
{
Char *p1, *p2;
const Char *op;
tcsh_number_t i;
unsigned tcsh_number_t i;

p1 = exp4(vp, ignore);
etracc("exp3a p1", p1, vp);
Expand Down Expand Up @@ -421,7 +458,7 @@ static Char *
exp4(Char ***vp, int ignore)
{
Char *p1, *p2;
tcsh_number_t i = 0;
unsigned tcsh_number_t i = 0;

p1 = exp5(vp, ignore);
etracc("exp4 p1", p1, vp);
Expand Down Expand Up @@ -458,7 +495,7 @@ static Char *
exp5(Char ***vp, int ignore)
{
Char *p1, *p2;
tcsh_number_t i = 0;
unsigned tcsh_number_t i = 0;

p1 = exp6(vp, ignore);
etracc("exp5 p1", p1, vp);
Expand All @@ -482,23 +519,44 @@ exp5(Char ***vp, int ignore)
etracc("exp5 p2", p2, vp);
if (!(ignore & TEXP_IGNORE))
switch (op[0]) {
tcsh_number_t is;

case '*':
i = egetn(p1) * egetn(p2);
break;

case '/':
i = egetn(p2);
if (i == 0)
if ((i = egetn(p2)) == 0)
stderror(ERR_DIV0);
i = egetn(p1) / i;
if (i & ~(~(unsigned tcsh_number_t) 0 >> 1))
is = -(tcsh_number_t) -i;
else
is = i;
if ((i = egetn(p1)) ==
~(~(unsigned tcsh_number_t) 0 >> 1) &&
is == -1)
stderror(ERR_DIVOF);
if (i & ~(~(unsigned tcsh_number_t) 0 >> 1))
i = -(tcsh_number_t) -i / is;
else
i /= is;
break;

case '%':
i = egetn(p2);
if (i == 0)
if ((i = egetn(p2)) == 0)
stderror(ERR_MOD0);
i = egetn(p1) % i;
if (i & ~(~(unsigned tcsh_number_t) 0 >> 1))
is = -(tcsh_number_t) -i;
else
is = i;
if ((i = egetn(p1)) ==
~(~(unsigned tcsh_number_t) 0 >> 1) &&
is == -1)
stderror(ERR_MODOF);
if (i & ~(~(unsigned tcsh_number_t) 0 >> 1))
i = -(tcsh_number_t) -i % is;
else
i %= is;
break;
}
cleanup_until(p1);
Expand All @@ -513,8 +571,8 @@ exp5(Char ***vp, int ignore)
static Char *
exp6(Char ***vp, int ignore)
{
tcsh_number_t ccode;
tcsh_number_t i = 0;
unsigned tcsh_number_t ccode,
i = 0;
Char *cp;

if (**vp == 0)
Expand Down Expand Up @@ -1022,7 +1080,7 @@ isa(Char *cp, int what)
return (0);
}

static tcsh_number_t
static unsigned tcsh_number_t
egetn(const Char *cp)
{
if (*cp && *cp != '-' && !Isdigit(*cp))
Expand Down
4 changes: 2 additions & 2 deletions sh.func.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ islogin(void)
void
doif(Char **v, struct command *kp)
{
int i;
unsigned tcsh_number_t i;
Char **vv;

v++;
Expand Down Expand Up @@ -558,7 +558,7 @@ doforeach(Char **v, struct command *c)
void
dowhile(Char **v, struct command *c)
{
int status;
unsigned tcsh_number_t status;
int again = whyles != 0 &&
SEEKEQ(&whyles->w_start, &lineloc) &&
whyles->w_fename == 0;
Expand Down
4 changes: 2 additions & 2 deletions sh.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ static __inline void tcsh_ignore(intptr_t a)
#endif /* __HP_CXD_SPP && !__hpux */

#ifdef HAVE_LONG_LONG
typedef long long tcsh_number_t;
#define tcsh_number_t long long
#else
typedef long tcsh_number_t;
#define tcsh_number_t long
#endif
/*
* This macro compares the st_dev field of struct stat. On aix on ibmESA
Expand Down
Loading