mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
lex.c: prevent restoring outdated stack pointer
Lexical levels are stored in a dynamically grown array of int values grown by the stack_grow function. The pointer lex_match and the maximum index lex_max are part of the lexer state struct that is now saved and restored in various places -- see e.g.37044047,a2bc49be. If the stack needs to be grown, it is reallocated in stack_grow() using sh_realloc(). If that happens between saving and restoring the lexer state, then an outdated pointer is restored, and crash. src/cmd/ksh93/include/shlex.h, src/cmd/ksh93/sh/lex.c: - Take lex_match and lex_max out of the lexer state struct and make them separate static variables. src/cmd/ksh93/edit/edit.c: - While we're at it, save and restore the lexer state in a way that is saner than the 93v- beta approach (re:37044047) as well as more readable. Instead of permanently allocating memory, use a local variable to save the struct. Save/restore directly around the sh_trap() call that actually needs this done. Resolves: https://github.com/ksh93/ksh/issues/482
This commit is contained in:
parent
d8dc2a1d81
commit
da97587e9e
4 changed files with 17 additions and 20 deletions
|
|
@ -62,13 +62,13 @@ local_iswblank(wchar_t wc)
|
|||
|
||||
#endif
|
||||
|
||||
#define pushlevel(lp,c,s) ((lp->lexd.level>=lp->lexd.lex_max?stack_grow(lp):1) &&\
|
||||
((lp->lexd.lex_match[lp->lexd.level++]=lp->lexd.lastc),\
|
||||
#define pushlevel(lp,c,s) ((lp->lexd.level>=lex_max?stack_grow():1) &&\
|
||||
((lex_match[lp->lexd.level++]=lp->lexd.lastc),\
|
||||
lp->lexd.lastc=(((s)<<CHAR_BIT)|(c))))
|
||||
#define oldmode(lp) (lp->lexd.lastc>>CHAR_BIT)
|
||||
#define endchar(lp) (lp->lexd.lastc&0xff)
|
||||
#define setchar(lp,c) (lp->lexd.lastc = ((lp->lexd.lastc&~0xff)|(c)))
|
||||
#define poplevel(lp) (lp->lexd.lastc=lp->lexd.lex_match[--lp->lexd.level])
|
||||
#define poplevel(lp) (lp->lexd.lastc=lex_match[--lp->lexd.level])
|
||||
|
||||
static char *fmttoken(Lex_t*, int);
|
||||
static struct argnod *endword(int);
|
||||
|
|
@ -77,9 +77,12 @@ static void setupalias(Lex_t*,const char*, Namval_t*);
|
|||
static int comsub(Lex_t*,int);
|
||||
static void nested_here(Lex_t*);
|
||||
static int here_copy(Lex_t*, struct ionod*);
|
||||
static int stack_grow(Lex_t*);
|
||||
static int stack_grow(void);
|
||||
static const Sfdisc_t alias_disc = { NULL, NULL, NULL, alias_exceptf, NULL };
|
||||
|
||||
/* these were taken out of the Lex_t struct because they should never be saved and restored (see stack_grow()) */
|
||||
static int lex_max, *lex_match;
|
||||
|
||||
#if SHOPT_KIA
|
||||
|
||||
static void refvar(Lex_t *lp, int type)
|
||||
|
|
@ -2472,12 +2475,12 @@ static void setupalias(Lex_t *lp, const char *string,Namval_t *np)
|
|||
/*
|
||||
* grow storage stack for nested constructs by STACK_ARRAY
|
||||
*/
|
||||
static int stack_grow(Lex_t *lp)
|
||||
static int stack_grow(void)
|
||||
{
|
||||
lp->lexd.lex_max += STACK_ARRAY;
|
||||
if(lp->lexd.lex_match)
|
||||
lp->lexd.lex_match = (int*)sh_realloc((char*)lp->lexd.lex_match,sizeof(int)*lp->lexd.lex_max);
|
||||
lex_max += STACK_ARRAY;
|
||||
if(lex_match)
|
||||
lex_match = (int*)sh_realloc((char*)lex_match,sizeof(int)*lex_max);
|
||||
else
|
||||
lp->lexd.lex_match = (int*)sh_malloc(sizeof(int)*STACK_ARRAY);
|
||||
lex_match = (int*)sh_malloc(sizeof(int)*STACK_ARRAY);
|
||||
return(1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue