about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2015-08-21 10:04:13 +0100
committerPeter Stephenson <pws@zsh.org>2015-08-21 10:04:13 +0100
commit61afb8dc8d75106940ac4248632cb14823a3650e (patch)
treee557d9c3a3bcc506f12fe7a4b7ca5fd48680e1c8
parent364e1717f06ff4ac8ec3b9d605ae7c272fa73ff4 (diff)
downloadzsh-61afb8dc8d75106940ac4248632cb14823a3650e.tar.gz
zsh-61afb8dc8d75106940ac4248632cb14823a3650e.tar.xz
zsh-61afb8dc8d75106940ac4248632cb14823a3650e.zip
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.
-rw-r--r--ChangeLog4
-rw-r--r--Src/builtin.c2
-rw-r--r--Src/compat.c11
-rw-r--r--Src/utils.c13
-rw-r--r--Test/D07multibyte.ztst12
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  <p.stephenson@samsung.com>
 
+	* 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