zsh-workers
 help / color / mirror / code / Atom feed
From: "Jun T." <takimoto-j@kba.biglobe.ne.jp>
To: zsh-workers@zsh.org
Subject: Re: [Bug] Strange Globing Behaviour when used with sudo
Date: Mon, 4 Jun 2018 01:30:14 +0900	[thread overview]
Message-ID: <7D035B65-A2BA-49F3-807D-A387FF4FE6DB@kba.biglobe.ne.jp> (raw)
In-Reply-To: <20180602181719.vzcnij3fvx7eueuk@Daniels-MacBook-Air.local>


Do we need to fix (or workaround) this problem, given that
very basic commands like "ls" are also broken on macOS?

> 2018/06/03 03:17, Daniel Tameling <tamelingdaniel@gmail.com> wrote:
> 
> $ sudo zsh -c 'echo */../
> file/../

Thanks.

If we really need to workaround this bug, probably the simplest way 
would be not to add a file to pathbuf as in the patch below.

I couldn't put all the patch within a single "#ifdef __APPLE__" because
the return value of addpath() is changed to int.

> Btw:
> I noticed bash manages to trigger the ls error message when zsh
> outputs "no matches found" 
> $ bash -c 'ls */..'
> ls: cannot access '*/..': No such file or directory

Try 'setopt no_nomatch'. See the option NOMATCH in zshoptions(1).


diff --git a/Src/glob.c b/Src/glob.c
index 66a95329f..a36d76ac1 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -259,11 +259,28 @@ struct complist {
 /* Add a component to pathbuf: This keeps track of how    *
  * far we are into a file name, since each path component *
  * must be matched separately.                            */
+#ifdef __APPLE__
+#define BROKEN_STAT
+/*
+ * Workaround for broken stat()/lstat()/access() on macOS.
+ * If called by root, these syscalls mistakenly returns success for paths
+ * like "foo/bar/.", "foo/bar/..", "foo/bar/../" etc. even if bar is a file.
+ * This causes statfullpath() to also succeed for these paths.
+ * To workaround this problem, we do not add s to pathbuf if it is not a
+ * directory and return -1 instead.
+ *
+ * On systems other than macOS, always add s to pathbuf and return 0.
+ */
+#endif
 
 /**/
-static void
+static int
 addpath(char *s, int l)
 {
+#ifdef BROKEN_STAT
+    struct stat stbuf;
+    int oppos = pathpos;
+#endif
     DPUTS(!pathbuf, "BUG: pathbuf not initialised");
     while (pathpos + l + 1 >= pathbufsz)
 	pathbuf = zrealloc(pathbuf, pathbufsz *= 2);
@@ -271,6 +288,14 @@ addpath(char *s, int l)
 	pathbuf[pathpos++] = *s++;
     pathbuf[pathpos++] = '/';
     pathbuf[pathpos] = '\0';
+#ifdef BROKEN_STAT
+    if (stat(unmeta(pathbuf), &stbuf) || !S_ISDIR(stbuf.st_mode)) {
+	pathbuf[pathpos = oppos] = '\0';
+	return -1;
+    }
+    else
+#endif
+	return 0;
 }
 
 /* stat the filename s appended to pathbuf.  l should be true for lstat,    *
@@ -531,9 +556,12 @@ scanner(Complist q, int shortcircuit)
 			       sr.st_dev != sc.st_dev);
 		    }
 		}
-		if (add) {
-		    addpath(str, l);
-		    if (!closure || !statfullpath("", NULL, 1)) {
+		if (add && !addpath(str,l)) {
+		    if (!closure
+#ifndef BROKEN_STAT
+			    || !statfullpath("", NULL, 1)
+#endif
+		    ) {
 			scanner((q->closure) ? q : q->next, shortcircuit);
 			if (shortcircuit && shortcircuit == matchct)
 			    return;
@@ -650,15 +678,17 @@ scanner(Complist q, int shortcircuit)
 
 	    for (fn = subdirs; fn < subdirs+subdirlen; ) {
 		int l = strlen(fn);
-		addpath(fn, l);
+		int fn_is_dir = !addpath(fn, l);
 		fn += l + 1;
 		memcpy((char *)&errsfound, fn, sizeof(int));
 		fn += sizeof(int);
-		/* scan next level */
-		scanner((q->closure) ? q : q->next, shortcircuit); 
-		if (shortcircuit && shortcircuit == matchct)
-		    return;
-		pathbuf[pathpos = oppos] = '\0';
+		if (fn_is_dir) {
+		    /* scan next level */
+		    scanner((q->closure) ? q : q->next, shortcircuit); 
+		    if (shortcircuit && shortcircuit == matchct)
+			return;
+		    pathbuf[pathpos = oppos] = '\0';
+		}
 	    }
 	    hrealloc(subdirs, subdirlen, 0);
 	}



  reply	other threads:[~2018-06-03 16:30 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-30 17:11 Bengt Brodersen
2018-05-30 18:06 ` Bart Schaefer
2018-05-30 19:15   ` Daniel Shahaf
2018-05-30 20:23     ` Phil Pennock
2018-05-30 20:44       ` Bengt Brodersen
2018-05-30 20:49         ` Bengt Brodersen
2018-05-31  8:44           ` Peter Stephenson
     [not found]           ` <20180531094403.05b62bee@camnpupstephen.cam.scsc.local>
2018-05-31  8:49             ` Peter Stephenson
2018-05-31 11:39               ` Jun T
2018-05-31 15:29                 ` Peter Stephenson
2018-05-31 18:15                   ` Daniel Tameling
2018-06-01 14:08                     ` Jun T.
2018-06-02 18:17                       ` Daniel Tameling
2018-06-03 16:30                         ` Jun T. [this message]
2018-06-03 18:48                           ` Daniel Tameling
2018-06-03 19:17                             ` dana
2018-06-04  1:23                               ` Jun T
2018-06-04 12:48                           ` Jun T
2018-06-14 12:26           ` Bengt Brodersen
2018-05-31  6:37       ` Martijn Dekker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7D035B65-A2BA-49F3-807D-A387FF4FE6DB@kba.biglobe.ne.jp \
    --to=takimoto-j@kba.biglobe.ne.jp \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).