From 61afb8dc8d75106940ac4248632cb14823a3650e Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 21 Aug 2015 10:04:13 +0100 Subject: 36262: Replace fix for missing unmeta in chdir(). It was needed in the argument to one of a pair of lchdir()s rather than within zchdir(). Add tests for the case of a character with 0x83 within it. --- ChangeLog | 4 ++++ Src/builtin.c | 2 +- Src/compat.c | 11 ++++++++--- Src/utils.c | 13 +++++++++---- Test/D07multibyte.ztst | 12 ++++++++++++ 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2975a651c..ace02a203 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2015-08-21 Peter Stephenson + * 36262: Src/builin.c, Src/compat.c, Src/utils.c, + Test/D07multibyte.ztst: replace 36232: the unmeta() + was needed at a place higher up. Add test. + * 36250, tweaked: README, NEWS: highlight bracketed paste mode; next version will be 5.1 rather than 5.0.9. diff --git a/Src/builtin.c b/Src/builtin.c index 572a0dd68..3d34aa74c 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1163,7 +1163,7 @@ cd_try_chdir(char *pfix, char *dest, int hard) * or a parent directory is renamed in the interim. */ if (lchdir(buf, NULL, hard) && - (pfix || *dest == '/' || lchdir(dest, NULL, hard))) { + (pfix || *dest == '/' || lchdir(unmeta(dest), NULL, hard))) { free(buf); return NULL; } diff --git a/Src/compat.c b/Src/compat.c index a0ce1823c..db468529a 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -454,8 +454,13 @@ zgetcwd(void) return ret; } -/* chdir with arbitrary long pathname. Returns 0 on success, -1 on normal * - * failure and -2 when chdir failed and the current directory is lost. */ +/* + * chdir with arbitrary long pathname. Returns 0 on success, -1 on normal * + * failure and -2 when chdir failed and the current directory is lost. + * + * This is to be treated as if at system level, so dir is unmetafied but + * terminated by a NULL. + */ /**/ mod_export int @@ -465,7 +470,7 @@ zchdir(char *dir) int currdir = -2; for (;;) { - if (!*dir || chdir(unmeta(dir)) == 0) { + if (!*dir || chdir(dir) == 0) { #ifdef HAVE_FCHDIR if (currdir >= 0) close(currdir); diff --git a/Src/utils.c b/Src/utils.c index 20e01a207..4c4dc55cd 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -6440,10 +6440,15 @@ init_dirsav(Dirsav d) d->dirfd = d->level = -1; } -/* Change directory, without following symlinks. Returns 0 on success, -1 * - * on failure. Sets errno to ENOTDIR if any symlinks are encountered. If * - * fchdir() fails, or the current directory is unreadable, we might end up * - * in an unwanted directory in case of failure. */ +/* + * Change directory, without following symlinks. Returns 0 on success, -1 + * on failure. Sets errno to ENOTDIR if any symlinks are encountered. If + * fchdir() fails, or the current directory is unreadable, we might end up + * in an unwanted directory in case of failure. + * + * path is an unmetafied but null-terminated string, as needed by system + * calls. + */ /**/ mod_export int diff --git a/Test/D07multibyte.ztst b/Test/D07multibyte.ztst index 644d28046..0e3e98d38 100644 --- a/Test/D07multibyte.ztst +++ b/Test/D07multibyte.ztst @@ -496,3 +496,15 @@ >OK >OK >OK + + () { + emulate -L zsh + setopt errreturn + local cdpath=(.) + mkdir ホ + cd ホ + cd .. + cd ./ホ + cd .. + } +0:cd with special characters -- cgit 1.4.1