diff --git a/NEWS b/NEWS index 9ab2d57804e8..e97a6150f487 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,9 @@ Any uppercase BUG_* names are modernish shell bug IDs. - Fixed a crash when listing indexed arrays. +- Fixed a memory leak when restoring PATH when temporarily setting PATH + for a command (e.g. PATH=/foo/bar command ...) or in a virtual subshell. + 2020-07-07: - Four of the date formats accepted by 'printf %()T' have had their diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c index 25ade4073dad..3059bafbe429 100644 --- a/src/cmd/ksh93/sh/path.c +++ b/src/cmd/ksh93/sh/path.c @@ -1800,7 +1800,9 @@ void path_alias(register Namval_t *np,register Pathcomp_t *pp) Pathcomp_t *old; nv_offattr(np,NV_NOPRINT); nv_stack(np,&talias_init); - old = np->nvalue.pathcomp; + old = (Pathcomp_t*)np->nvalue.cp; + if (old && (--old->refcount <= 0)) + free((void*)old); np->nvalue.cp = (char*)pp; pp->refcount++; nv_setattr(np,NV_TAGGED|NV_NOFREE); diff --git a/src/cmd/ksh93/tests/leaks.sh b/src/cmd/ksh93/tests/leaks.sh index 2fd0aacf3aa3..9336289bc503 100755 --- a/src/cmd/ksh93/tests/leaks.sh +++ b/src/cmd/ksh93/tests/leaks.sh @@ -121,5 +121,20 @@ after=$(getmem) (( after > before )) && err_exit 'unset of associative array causes memory leak' \ "(leaked $((after - before)) $unit)" +# ====== +# Memory leak when resetting PATH and clearing hash table +# ...steady memory state: +command -v ls >/dev/null # add something to hash table +PATH=/dev/null true # set/restore PATH & clear hash table +# ...test for leak: +before=$(getmem) +for ((i=0; i<16; i++)) +do PATH=/dev/null true # set/restore PATH & clear hash table + command -v ls # do PATH search, add to hash table +done >/dev/null +after=$(getmem) +(( after > before )) && err_exit 'memory leak on PATH reset before subshell PATH search' \ + "(leaked $((after - before)) $unit)" + # ====== exit $((Errors<125?Errors:125))