Skip to content

Commit

Permalink
Fix handling of skipped directories when autoloading functions
Browse files Browse the repository at this point in the history
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:
att#1454

Fix backported (and cleaned up) from:
att@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)
  • Loading branch information
McDutchie committed Jun 11, 2020
1 parent 482d1c3 commit eee47df
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 7 deletions.
8 changes: 8 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
17 changes: 11 additions & 6 deletions src/cmd/ksh93/sh/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,20 +508,24 @@ 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,'/'))
{
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)
{
Expand All @@ -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);
Expand Down
29 changes: 29 additions & 0 deletions src/cmd/ksh93/tests/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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))

0 comments on commit eee47df

Please sign in to comment.