zsh-workers
 help / color / mirror / code / Atom feed
* bug with $PWD in /
@ 2015-09-16 16:26 Stephane Chazelas
  2015-09-16 20:37 ` Bart Schaefer
  2015-09-19 18:08 ` Bart Schaefer
  0 siblings, 2 replies; 9+ messages in thread
From: Stephane Chazelas @ 2015-09-16 16:26 UTC (permalink / raw)
  To: Zsh hackers list

Hiya,

It looks like zsh has a similar issue as bash as reported at:
http://thread.gmane.org/gmane.comp.shells.bash.bugs/24162

$ cd /
/$ PWD=.. zsh -c pwd
..
/$ PWD=.. zsh -c 'cd /usr/local/bin; cd -; pwd'
/usr/local

-- 
Stephane


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-16 16:26 bug with $PWD in / Stephane Chazelas
@ 2015-09-16 20:37 ` Bart Schaefer
  2015-09-16 20:56   ` Bart Schaefer
  2015-09-19 18:08 ` Bart Schaefer
  1 sibling, 1 reply; 9+ messages in thread
From: Bart Schaefer @ 2015-09-16 20:37 UTC (permalink / raw)
  To: Stephane Chazelas, Zsh hackers list

On Sep 16,  5:26pm, Stephane Chazelas wrote:
}
} It looks like zsh has a similar issue as bash as reported at:
} http://thread.gmane.org/gmane.comp.shells.bash.bugs/24162

Curious that this only occurs when the real directory is the root.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-16 20:37 ` Bart Schaefer
@ 2015-09-16 20:56   ` Bart Schaefer
  0 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2015-09-16 20:56 UTC (permalink / raw)
  To: Stephane Chazelas, Zsh hackers list

On Sep 16,  1:37pm, Bart Schaefer wrote:
}
} Curious that this only occurs when the real directory is the root.

Ah.  Zsh ignores the environment PWD unless it already points to the
actual current directory.  Since, in the root, .. and . and any path
containing nothing but those all loop back to the current directory,
zsh accepts the value.

Hence also PWD="../$(basename $PWD)" will be accepted anywhere.  This
also seems to be the rule bash is following.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-16 16:26 bug with $PWD in / Stephane Chazelas
  2015-09-16 20:37 ` Bart Schaefer
@ 2015-09-19 18:08 ` Bart Schaefer
  2015-09-19 19:28   ` Stephane Chazelas
  2015-09-19 20:01   ` Peter Stephenson
  1 sibling, 2 replies; 9+ messages in thread
From: Bart Schaefer @ 2015-09-19 18:08 UTC (permalink / raw)
  To: Zsh hackers list

On Sep 16,  5:26pm, Stephane Chazelas wrote:
} 
} It looks like zsh has a similar issue as bash as reported at:
} http://thread.gmane.org/gmane.comp.shells.bash.bugs/24162

How about this?

diff --git a/Src/utils.c b/Src/utils.c
index 1de3d95..0016fa1 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -692,9 +692,19 @@ ispwd(char *s)
 {
     struct stat sbuf, tbuf;
 
-    if (stat(unmeta(s), &sbuf) == 0 && stat(".", &tbuf) == 0)
-	if (sbuf.st_dev == tbuf.st_dev && sbuf.st_ino == tbuf.st_ino)
-	    return 1;
+    if (stat((s = unmeta(s)), &sbuf) == 0 && stat(".", &tbuf) == 0)
+	if (sbuf.st_dev == tbuf.st_dev && sbuf.st_ino == tbuf.st_ino) {
+	    /* POSIX: No element of $PWD may be "." or ".." */
+	    while (*s) {
+		if (s[0] == '.' &&
+		    (!s[1] || s[1] == '/' ||
+		     (s[1] == '.' && (!s[2] || s[2] == '/'))))
+		    break;
+		while (*s++ != '/' && *s)
+		    continue;
+	    }
+	    return !*s;
+	}
     return 0;
 }
 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-19 18:08 ` Bart Schaefer
@ 2015-09-19 19:28   ` Stephane Chazelas
  2015-09-19 20:47     ` Bart Schaefer
  2015-09-19 20:01   ` Peter Stephenson
  1 sibling, 1 reply; 9+ messages in thread
From: Stephane Chazelas @ 2015-09-19 19:28 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh hackers list

2015-09-19 11:08:00 -0700, Bart Schaefer:
> On Sep 16,  5:26pm, Stephane Chazelas wrote:
> } 
> } It looks like zsh has a similar issue as bash as reported at:
> } http://thread.gmane.org/gmane.comp.shells.bash.bugs/24162
> 
> How about this?
> 
> diff --git a/Src/utils.c b/Src/utils.c
> index 1de3d95..0016fa1 100644
> --- a/Src/utils.c
> +++ b/Src/utils.c
> @@ -692,9 +692,19 @@ ispwd(char *s)
>  {
>      struct stat sbuf, tbuf;
>  
> -    if (stat(unmeta(s), &sbuf) == 0 && stat(".", &tbuf) == 0)
> -	if (sbuf.st_dev == tbuf.st_dev && sbuf.st_ino == tbuf.st_ino)
> -	    return 1;
> +    if (stat((s = unmeta(s)), &sbuf) == 0 && stat(".", &tbuf) == 0)
> +	if (sbuf.st_dev == tbuf.st_dev && sbuf.st_ino == tbuf.st_ino) {
> +	    /* POSIX: No element of $PWD may be "." or ".." */
[...]

Also, as mentioned on the bash thread:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03

SUSv4> PWD
SUSv4>    Set by the shell and by the cd utility. In the shell the value
SUSv4>    shall be initialized from the environment as follows. If a value
SUSv4>    for PWD is passed to the shell in the environment when it is
SUSv4>    executed, the value is an absolute pathname of the current working
SUSv4>    directory that is no longer than {PATH_MAX} bytes including the
SUSv4>    terminating null byte, and the value does not contain any
SUSv4>    components that are dot or dot-dot, then the shell shall set PWD
SUSv4>    to the value from the environment. Otherwise, if a value for PWD
SUSv4>    is passed to the shell in the environment when it is executed, the
SUSv4>    value is an absolute pathname of the current working directory,
SUSv4>    and the value does not contain any components that are dot or
SUSv4>    dot-dot, then it is unspecified whether the shell sets PWD to the
SUSv4>    value from the environment or sets PWD to the pathname that would
SUSv4>    be output by pwd -P. Otherwise, the sh utility sets PWD to the
SUSv4>    pathname that would be output by pwd -P. In cases where PWD is set
SUSv4>    to the value from the environment, the value can contain
SUSv4>    components that refer to files of type symbolic link. In cases
SUSv4>    where PWD is set to the pathname that would be output by pwd -P,
SUSv4>    if there is insufficient permission on the current working
SUSv4>    directory, or on any parent of that directory, to determine what
SUSv4>    that pathname would be, the value of PWD is unspecified.
SUSv4>    Assignments to this variable may be ignored. If an application
SUSv4>    sets or unsets the value of PWD, the behaviors of the cd and pwd
SUSv4>    utilities are unspecified.

So, the should recompute $PWD if the one it gets from the
environment is a relative path (it's not only about . or ..,
think of symlinks).

-- 
Stephane


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-19 18:08 ` Bart Schaefer
  2015-09-19 19:28   ` Stephane Chazelas
@ 2015-09-19 20:01   ` Peter Stephenson
  1 sibling, 0 replies; 9+ messages in thread
From: Peter Stephenson @ 2015-09-19 20:01 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh hackers list

On Sat, 19 Sep 2015 11:08:00 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Sep 16,  5:26pm, Stephane Chazelas wrote:
> } 
> } It looks like zsh has a similar issue as bash as reported at:
> } http://thread.gmane.org/gmane.comp.shells.bash.bugs/24162
> 
> How about this?

I suppose we don't *need* to sanity check for a ".", but I also suppose
"A valid PWD may not contain relative path segments, even within an
absolute path (beginning with '/')" is a reasonable rule.

pws


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-19 19:28   ` Stephane Chazelas
@ 2015-09-19 20:47     ` Bart Schaefer
  2015-09-28 18:13       ` Daniel Shahaf
  0 siblings, 1 reply; 9+ messages in thread
From: Bart Schaefer @ 2015-09-19 20:47 UTC (permalink / raw)
  To: Zsh hackers list

On Sep 19,  8:28pm, Stephane Chazelas wrote:
} Subject: Re: bug with $PWD in /
}
} So, the should recompute $PWD if the one it gets from the
} environment is a relative path (it's not only about . or ..,
} think of symlinks).

It'd have to be a symlink from the current directory to itself, tho.
Other symbolic links are explicitly permitted by the text you quoted.

This replaces the previous patch, although it's 90% the same.

diff --git a/Src/utils.c b/Src/utils.c
index 1de3d95..ab3b0c2 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -692,9 +692,23 @@ ispwd(char *s)
 {
     struct stat sbuf, tbuf;
 
-    if (stat(unmeta(s), &sbuf) == 0 && stat(".", &tbuf) == 0)
-	if (sbuf.st_dev == tbuf.st_dev && sbuf.st_ino == tbuf.st_ino)
-	    return 1;
+    /* POSIX: environment PWD must be absolute */
+    if (*s != '/')
+	return 0;
+
+    if (stat((s = unmeta(s)), &sbuf) == 0 && stat(".", &tbuf) == 0)
+	if (sbuf.st_dev == tbuf.st_dev && sbuf.st_ino == tbuf.st_ino) {
+	    /* POSIX: No element of $PWD may be "." or ".." */
+	    while (*s) {
+		if (s[0] == '.' &&
+		    (!s[1] || s[1] == '/' ||
+		     (s[1] == '.' && (!s[2] || s[2] == '/'))))
+		    break;
+		while (*s++ != '/' && *s)
+		    continue;
+	    }
+	    return !*s;
+	}
     return 0;
 }
 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-19 20:47     ` Bart Schaefer
@ 2015-09-28 18:13       ` Daniel Shahaf
  2015-09-28 22:04         ` Bart Schaefer
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Shahaf @ 2015-09-28 18:13 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh hackers list, Stephane Chazelas

Bart Schaefer wrote on Sat, Sep 19, 2015 at 13:47:40 -0700:
> On Sep 19,  8:28pm, Stephane Chazelas wrote:
> } Subject: Re: bug with $PWD in /
> }
> } So, the should recompute $PWD if the one it gets from the
> } environment is a relative path (it's not only about . or ..,
> } think of symlinks).
> 
> It'd have to be a symlink from the current directory to itself, tho.
> Other symbolic links are explicitly permitted by the text you quoted.

Looking at the sole caller of ispwd(), setupvals(), it sometimes
initializes $PWD from getenv("HOME").  Is something like this needed,
then?

Or perhaps the condition should be "if not POSIX" rather than "if zsh".

diff --git a/Src/init.c b/Src/init.c
index 22db4b3..24a50c7 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1019,7 +1019,7 @@ setupvals(void)
        ptr = home;
     else
        ptr = zgetenv("HOME");
-    if (ptr && ispwd(ptr))
+    if (EMULATION(EMULATE_ZSH) && ptr && ispwd(ptr))
        pwd = ztrdup(ptr);
     else if ((ptr = zgetenv("PWD")) && (strlen(ptr) < PATH_MAX) &&
             (ptr = metafy(ptr, -1, META_STATIC), ispwd(ptr)))


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug with $PWD in /
  2015-09-28 18:13       ` Daniel Shahaf
@ 2015-09-28 22:04         ` Bart Schaefer
  0 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2015-09-28 22:04 UTC (permalink / raw)
  To: Zsh hackers list

On Sep 28,  6:13pm, Daniel Shahaf wrote:
} Subject: Re: bug with $PWD in /
}
} Looking at the sole caller of ispwd(), setupvals(), it sometimes
} initializes $PWD from getenv("HOME").  Is something like this needed,
} then?

What you're asking is: Are we required to accept PWD instead of HOME
when they both refer to the current directory but PWD gets there via
a symlink path?

I think the answer is "no" but I also don't think your patch did what
you intend.  We already ignore both $HOME and $PWD when EMULATE_ZSH
(and the current directory actually is the home directory).


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-09-28 22:04 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-16 16:26 bug with $PWD in / Stephane Chazelas
2015-09-16 20:37 ` Bart Schaefer
2015-09-16 20:56   ` Bart Schaefer
2015-09-19 18:08 ` Bart Schaefer
2015-09-19 19:28   ` Stephane Chazelas
2015-09-19 20:47     ` Bart Schaefer
2015-09-28 18:13       ` Daniel Shahaf
2015-09-28 22:04         ` Bart Schaefer
2015-09-19 20:01   ` Peter Stephenson

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).