diff --git a/src/cmd/ksh93/sh/lex.c b/src/cmd/ksh93/sh/lex.c index b9e7ef480..d5baf5d0a 100644 --- a/src/cmd/ksh93/sh/lex.c +++ b/src/cmd/ksh93/sh/lex.c @@ -2445,7 +2445,7 @@ static int alias_exceptf(Sfio_t *iop,int type,Sfdisc_t *handle) if(dp!=handle) sfdisc(iop,dp); } - else if(type==SF_FINAL) + else if(type==SF_DPOP || type==SF_FINAL) free((void*)ap); goto done; } diff --git a/src/cmd/ksh93/sh/macro.c b/src/cmd/ksh93/sh/macro.c index 5605a21bc..7af9ca1dc 100644 --- a/src/cmd/ksh93/sh/macro.c +++ b/src/cmd/ksh93/sh/macro.c @@ -2110,6 +2110,7 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type) } sfputc(stkp,c); } + sfputc(stkp,' '); /* rhbz#982142: a=`some_alias` leaked memory, a=`some_alias ` did not! TODO: non-hack fix */ c = stktell(stkp); str=stkfreeze(stkp,1); /* disable verbose and don't save in history file */ diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c index 7137ebab2..032871479 100644 --- a/src/cmd/ksh93/sh/path.c +++ b/src/cmd/ksh93/sh/path.c @@ -612,6 +612,7 @@ static void funload(Shell_t *shp,int fno, const char *name) } while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0); sh_close(fno); + free((void*)pname); return; } sh_onstate(SH_NOLOG); diff --git a/src/cmd/ksh93/tests/leaks.sh b/src/cmd/ksh93/tests/leaks.sh index b29b07355..40d815ccd 100755 --- a/src/cmd/ksh93/tests/leaks.sh +++ b/src/cmd/ksh93/tests/leaks.sh @@ -270,5 +270,45 @@ done after=$(getmem) err_exit_if_leak 'unalias' +# ====== +# Red Hat bug rhbz#982142: command substitution leaks + +# case1: Nested command substitutions +# (reportedly already fixed in 93u+, but let's keep the test) +before=$(getmem) +for ((i=0; i < N; i++)) +do a=`true 1 + \`true 1 + 1\`` # was: a=`expr 1 + \`expr 1 + 1\`` +done +after=$(getmem) +err_exit_if_leak 'nested command substitutions' + +# case2: Command alias +alias ls='true -ltr' # was: alias ls='ls -ltr' +before=$(getmem) +for ((i=0; i < N; i++)) +do eval 'a=`ls`' +done +after=$(getmem) +unalias ls +err_exit_if_leak 'alias in command substitution' + +# case3: Function call via autoload +cat >$tmp/func1 <<\EOF +function func1 +{ + echo "func1 call"; +} +EOF +FPATH=$tmp +autoload func1 +before=$(getmem) +for ((i=0; i < N; i++)) +do a=`func1` +done +after=$(getmem) +unset -f func1 +unset -v FPATH +err_exit_if_leak 'function call via autoload in command substitution' + # ====== exit $((Errors<125?Errors:125))