From bb4745e89702e4291472809f5938080cf7371c6a Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Fri, 26 Jun 2020 15:36:29 -0700 Subject: [PATCH] Fix incorrect behavior of 'cd ../.foo' (#46) The cd builtin was removing '.' from directory names when combined with a preceding '../', which caused commands like 'cd ../.local' to become 'cd ../local'. This patch fixes the problem by limiting the extra handling to leading '..'. The bugfix comes from ksh93v- 2013-10-10-alpha, although this version is a shortened patch from Solaris (as ksh93v- refactored a decent amount of the code for the cd builtin). src/cmd/ksh93/bltins/cd_pwd.c: - cd should only check for leading '..', as trying to handle a lone '.' only causes problems. src/cmd/ksh93/tests/builtins.sh: - Add a regression test for this problem based on the test present in ksh93v- 2013-10-10-alpha. Patch from Solaris: https://github.com/oracle/solaris-userland/blob/860d27f/components/ksh93/patches/270-23319761.patch --- NEWS | 5 +++++ src/cmd/ksh93/bltins/cd_pwd.c | 38 +++++++++++---------------------- src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/tests/builtins.sh | 9 ++++++++ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/NEWS b/NEWS index 3379fb49efc6..2be362787fb9 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,11 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2020-06-26: + +- Changing to a directory that has a name starting with a '.' will no + longer fail if preceded by '../' (i.e. 'cd ../.local' will now work). + 2020-06-24: - Fixed buggy tab completion of tilde-expanded paths such as diff --git a/src/cmd/ksh93/bltins/cd_pwd.c b/src/cmd/ksh93/bltins/cd_pwd.c index cebcba38c51e..bd64d225e6a9 100644 --- a/src/cmd/ksh93/bltins/cd_pwd.c +++ b/src/cmd/ksh93/bltins/cd_pwd.c @@ -109,34 +109,20 @@ int b_cd(int argc, char *argv[],Shbltin_t *context) if(!oldpwd) oldpwd = path_pwd(shp,1); } - if(*dir=='.') + if(*dir!='/') { - /* test for pathname . ./ .. or ../ */ - int n=0; - char *sp; - for(dp=dir; *dp=='.'; dp++) + /* check for leading .. */ + char *cp; + sfprintf(shp->strbuf,"%s",dir); + cp = sfstruse(shp->strbuf); + pathcanon(cp, 0); + if(cp[0]=='.' && cp[1]=='.' && (cp[2]=='/' || cp[2]==0)) { - if(*++dp=='.' && (*++dp=='/' || *dp==0)) - n++; - else if(*dp && *dp!='/') - break; - if(*dp==0) - break; - } - if(n) - { - cdpath = 0; - sp = oldpwd + strlen(oldpwd); - while(n--) - { - while(--sp > oldpwd && *sp!='/'); - if(sp==oldpwd) - break; - - } - sfwrite(shp->strbuf,oldpwd,sp+1-oldpwd); - sfputr(shp->strbuf,dp,0); - dir = sfstruse(shp->strbuf); + if(!shp->strbuf2) + shp->strbuf2 = sfstropen(); + sfprintf(shp->strbuf2,"%s/%s",oldpwd,cp); + dir = sfstruse(shp->strbuf2); + pathcanon(dir, 0); } } rval = -1; diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 041e40b3bc2d..82f82c5b99f0 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-06-24" +#define SH_RELEASE "93u+m 2020-06-26" diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh index 948c1c4515d6..b39c26d89d63 100755 --- a/src/cmd/ksh93/tests/builtins.sh +++ b/src/cmd/ksh93/tests/builtins.sh @@ -717,5 +717,14 @@ chmod is $(whence -p chmod) chmod is a tracked alias for $(whence -p chmod)" [[ $actual == $expected ]] || err_exit '`whence -a` does not work correctly with tracked aliases' +# ====== +# 'cd ../.foo' should not exclude the '.' in '.foo' +( + cd "$tmp" + mkdir foo .bar + cd foo + cd ../.bar +) || err_exit 'cd ../.bar when ../.bar exists should not fail' + # ====== exit $((Errors<125?Errors:125))