Skip to content

Commit

Permalink
whence -v: fix path canonicalisation
Browse files Browse the repository at this point in the history
This bug was mediated by the fact that path_search() prefixes the
present working directory to any relative path, but does not do any
other canonicalisation. A faulty check then caused that path to be
considered an absolute path and not in need of canonicalising, even
if it contained '.' and '..' elements or double slashes.

src/cmd/ksh93/bltins/whence.c:
- Remove faulty check for initial '/' that prevented
  path_fullname() from ever being called.

src/cmd/ksh93/tests/builtins.sh:
- Add two 'whence -v' path canonicalisation tests.
- Tweak other 'whence' tests for consistency.

Fixes #84
  • Loading branch information
McDutchie committed Jul 21, 2020
1 parent db72f41 commit 13ec0d1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 16 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Any uppercase BUG_* names are modernish shell bug IDs.
- If a shell function and a built-in command by the same name exist,
'whence -a' and 'type -a' now report both.

- 'whence -v' now canonicalizes relative paths properly.

- Fixed a bug that caused file descriptors opened with 'redirect' or 'exec'
to survive a subshell environment after exiting it.

Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/bltins/whence.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
cp = stakptr(PATH_OFFSET);
if(*cp==0)
cp = 0;
else if(*cp!='/')
else
{
cp = path_fullname(shp,cp);
tofree=1;
Expand Down
44 changes: 29 additions & 15 deletions src/cmd/ksh93/tests/builtins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -732,42 +732,56 @@ foo=BUG command eval ':'
[[ $foo == BUG ]] && err_exit '`command` fails to disable the special properties of special builtins'
# ======
# 'whence -a' tests
# whence -a/-v tests
# wrong path to tracked aliases after loading builtin: https://github.com/ksh93/ksh/pull/25
actual=$("$SHELL" -c '
whence chmod >/dev/null # add to hash table (create tracked alias)
builtin chmod
whence -a chmod
')
expected="chmod is a shell builtin
expect="chmod is a shell builtin
$(whence -a -p chmod | sed 's/^/chmod is /')
chmod is a tracked alias for $(whence -p chmod)"
[[ $actual == $expected ]] || err_exit "'whence -a' does not work correctly with tracked aliases" \
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
[[ $actual == $expect ]] || err_exit "'whence -a' does not work correctly with tracked aliases" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
# spurious 'undefined function' message: https://github.com/ksh93/ksh/issues/26
actual=$("$SHELL" -c 'whence -a printf')
expected="printf is a shell builtin
expect="printf is a shell builtin
$(whence -a -p printf | sed 's/^/printf is /')"
[[ $actual == $expected ]] || err_exit "'whence -a': incorrect output" \
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
[[ $actual == $expect ]] || err_exit "'whence -a': incorrect output" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
# 'whence -a'/'type -a' failed to list builtin if function exists: https://github.com/ksh93/ksh/issues/83
actual=$(printf() { :; }; whence -a printf)
expected="printf is a function
expect="printf is a function
printf is a shell builtin
$(whence -a -p printf | sed 's/^/printf is /')"
[[ $actual == $expected ]] || err_exit "'whence -a': incorrect output for function+builtin" \
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
# 'whence -a'/'type -a' failed to list builtin if autoload function exists: https://github.com/ksh93/ksh/issues/83
[[ $actual == $expect ]] || err_exit "'whence -a': incorrect output for function+builtin" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
actual=$(autoload printf; whence -a printf)
expected="printf is an undefined function
expect="printf is an undefined function
printf is a shell builtin
$(whence -a -p printf | sed 's/^/printf is /')"
[[ $actual == $expected ]] || err_exit "'whence -a': incorrect output for autoload+builtin" \
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
[[ $actual == $expect ]] || err_exit "'whence -a': incorrect output for autoload+builtin" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
# 'whence -v' canonicalized paths improperly: https://github.com/ksh93/ksh/issues/84
cmdpath=${ whence -p printf; }
actual=$(cd /; whence -v "${cmdpath#/}")
expect="${cmdpath#/} is $cmdpath"
[[ $actual == $expect ]] || err_exit "'whence -v': incorrect canonicalization of initial /" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
dotdot=
num=$(set -f; IFS=/; set -- $PWD; echo $#)
for ((i=1; i<num; i++))
do dotdot+='../'
done
actual=$(cd /; whence -v "$dotdot${cmdpath#/}")
expect="$dotdot${cmdpath#/} is $cmdpath"
[[ $actual == $expect ]] || err_exit "'whence -v': incorrect canonicalization of pathname containing '..'" \
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
# ======
# 'cd ../.foo' should not exclude the '.' in '.foo'
Expand Down

0 comments on commit 13ec0d1

Please sign in to comment.