1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

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:
860d27f/components/ksh93/patches/270-23319761.patch
This commit is contained in:
Johnothan King 2020-06-26 15:36:29 -07:00 committed by GitHub
parent eaaa0de74d
commit bb4745e897
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 27 deletions

View file

@ -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;