Fix handling of skipped directories when autoloading functions
Fix a bug in autoloading functions. Directories in the path search list which should be skipped (e.g. because they don't exist) did not interact correctly with autoloaded functions, so that a function to autoload was not always found. Details: https://github.com/att/ast/issues/1454 Fix backported (and cleaned up) from: https://github.com/att/ast/commit/3bc58164 src/cmd/ksh93/sh/path.c: - path_opentype(): Fix the path search loop so that entries marked with PATH_SKIP are handled correctly. src/cmd/ksh93/tests/functions.sh: - Add regression test verifying an autoloaded function with a PATH that triggered the bug. The bug in path_opentype() fixed by this commit may affect other scenarios but we know it affects autoloaded functions. Hence the test for that scenario. (cherry picked from commit a27903165775309f4f032de5d42ec1785f14cfbc)
This commit is contained in:
parent
482d1c3dd6
commit
eee47df423
8
NEWS
8
NEWS
|
|
@ -4,6 +4,14 @@ For full details, see the git log at:
|
|||
|
||||
Any uppercase BUG_* names are modernish shell bug IDs.
|
||||
|
||||
2020-05-31:
|
||||
|
||||
- Fix a bug in autoloading functions. Directories in the path search list
|
||||
which should be skipped (e.g. because they don't exist) did not interact
|
||||
correctly with autoloaded functions, so that a function to autoload was
|
||||
not always found correctly.
|
||||
Details: https://github.com/att/ast/issues/1454
|
||||
|
||||
2020-05-30:
|
||||
|
||||
- Fix POSIX compliance of 'test'/'[' exit status on error. The command now
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@
|
|||
* David Korn <dgk@research.att.com> *
|
||||
* *
|
||||
***********************************************************************/
|
||||
#define SH_RELEASE "93u+m 2020-05-30"
|
||||
#define SH_RELEASE "93u+m 2020-05-31"
|
||||
|
|
|
|||
|
|
@ -508,7 +508,8 @@ static int path_opentype(Shell_t *shp,const char *name, register Pathcomp_t *pp,
|
|||
{
|
||||
register int fd= -1;
|
||||
struct stat statb;
|
||||
Pathcomp_t *oldpp;
|
||||
Pathcomp_t *nextpp;
|
||||
|
||||
if(!pp && !shp->pathlist)
|
||||
path_init(shp);
|
||||
if(!fun && strchr(name,'/'))
|
||||
|
|
@ -516,12 +517,15 @@ static int path_opentype(Shell_t *shp,const char *name, register Pathcomp_t *pp,
|
|||
if(sh_isoption(SH_RESTRICTED))
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_restricted,name);
|
||||
}
|
||||
|
||||
nextpp = pp;
|
||||
do
|
||||
{
|
||||
pp = path_nextcomp(shp,oldpp=pp,name,0);
|
||||
while(oldpp && (oldpp->flags&PATH_SKIP))
|
||||
oldpp = oldpp->next;
|
||||
if(fun && (!oldpp || !(oldpp->flags&PATH_FPATH)))
|
||||
pp = nextpp;
|
||||
nextpp = path_nextcomp(shp,pp,name,0);
|
||||
if(pp && (pp->flags&PATH_SKIP))
|
||||
continue;
|
||||
if(fun && (!pp || !(pp->flags&PATH_FPATH)))
|
||||
continue;
|
||||
if((fd = sh_open(path_relative(shp,stakptr(PATH_OFFSET)),O_RDONLY,0)) >= 0)
|
||||
{
|
||||
|
|
@ -533,7 +537,8 @@ static int path_opentype(Shell_t *shp,const char *name, register Pathcomp_t *pp,
|
|||
}
|
||||
}
|
||||
}
|
||||
while( fd<0 && pp);
|
||||
while(fd<0 && nextpp);
|
||||
|
||||
if(fd>=0 && (fd = sh_iomovefd(fd)) > 0)
|
||||
{
|
||||
fcntl(fd,F_SETFD,FD_CLOEXEC);
|
||||
|
|
|
|||
|
|
@ -1213,4 +1213,33 @@ rc=$?
|
|||
exp=$((256+$(kill -l TERM) ))
|
||||
[[ $rc == "$exp" ]] || err_exit "expected exitval $exp got $rc"
|
||||
|
||||
# ======
|
||||
# Verify that directories in the path search list which should be skipped
|
||||
# (e.g. because they don't exist) interact correctly with autoloaded functions.
|
||||
# See https://github.com/att/ast/issues/1454
|
||||
expect="Func cd called with |$tmp/usr|
|
||||
$tmp/usr"
|
||||
actual=$(
|
||||
set -- wrong args passed
|
||||
mkdir -p "$tmp/usr/bin"
|
||||
print 'echo "wrong file executed ($*)"' >"$tmp/usr/bin/cd"
|
||||
prefix=$tmp/ksh.$$
|
||||
|
||||
FPATH=$prefix/bad:$prefix/functions
|
||||
mkdir -p "$prefix/functions"
|
||||
print 'function cd { echo "Func cd called with |$*|"; command cd "$@"; }' >"$prefix/functions/cd"
|
||||
typeset -fu cd
|
||||
|
||||
PATH=$tmp/arglebargle:$PATH:$tmp/usr/bin:$tmp/bin
|
||||
cd "$tmp/usr"
|
||||
pwd
|
||||
)
|
||||
actual_status=$?
|
||||
expect_status=0
|
||||
[[ $actual_status == "$expect_status" ]] ||
|
||||
err_exit "autoload function skipped dir test wrong status (expected $expect_status, got $actual_status)"
|
||||
[[ $actual == "$expect" ]] ||
|
||||
err_exit "autoload function skipped dir test wrong output (expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
|
|||
Loading…
Reference in New Issue