mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
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:
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
4 changed files with 49 additions and 7 deletions
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.
|
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:
|
2020-05-30:
|
||||||
|
|
||||||
- Fix POSIX compliance of 'test'/'[' exit status on error. The command now
|
- Fix POSIX compliance of 'test'/'[' exit status on error. The command now
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
* David Korn <dgk@research.att.com> *
|
* 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;
|
register int fd= -1;
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
Pathcomp_t *oldpp;
|
Pathcomp_t *nextpp;
|
||||||
|
|
||||||
if(!pp && !shp->pathlist)
|
if(!pp && !shp->pathlist)
|
||||||
path_init(shp);
|
path_init(shp);
|
||||||
if(!fun && strchr(name,'/'))
|
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))
|
if(sh_isoption(SH_RESTRICTED))
|
||||||
errormsg(SH_DICT,ERROR_exit(1),e_restricted,name);
|
errormsg(SH_DICT,ERROR_exit(1),e_restricted,name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextpp = pp;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pp = path_nextcomp(shp,oldpp=pp,name,0);
|
pp = nextpp;
|
||||||
while(oldpp && (oldpp->flags&PATH_SKIP))
|
nextpp = path_nextcomp(shp,pp,name,0);
|
||||||
oldpp = oldpp->next;
|
if(pp && (pp->flags&PATH_SKIP))
|
||||||
if(fun && (!oldpp || !(oldpp->flags&PATH_FPATH)))
|
continue;
|
||||||
|
if(fun && (!pp || !(pp->flags&PATH_FPATH)))
|
||||||
continue;
|
continue;
|
||||||
if((fd = sh_open(path_relative(shp,stakptr(PATH_OFFSET)),O_RDONLY,0)) >= 0)
|
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)
|
if(fd>=0 && (fd = sh_iomovefd(fd)) > 0)
|
||||||
{
|
{
|
||||||
fcntl(fd,F_SETFD,FD_CLOEXEC);
|
fcntl(fd,F_SETFD,FD_CLOEXEC);
|
||||||
|
|
|
@ -1213,4 +1213,33 @@ rc=$?
|
||||||
exp=$((256+$(kill -l TERM) ))
|
exp=$((256+$(kill -l TERM) ))
|
||||||
[[ $rc == "$exp" ]] || err_exit "expected exitval $exp got $rc"
|
[[ $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))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue