PowerShell icon indicating copy to clipboard operation
PowerShell copied to clipboard

Adding '.' to env:PATH adds/remembers the directory where the command was issued, does not denote the ambient current directory later on

Open cklutz opened this issue 4 years ago • 10 comments

Prerequisites

Steps to reproduce

When adding '.' to $env:PATH inside PowerShell (like suggested in #14106), the '.' seems to refer to the directory where the $env:PATH = $env:PATH + ';.' was issued, but does not denote the actual "current directory", when you change the current directory (using Set-Location).

(PS> $env:PATH="")
PS> mkdir $env:TEMP\a
PS> mkdir $env:TEMP\b
PS> echo "@echo from a" > $env:TEMP\a\t.cmd
PS> echo "@echo from b" > $env:TEMP\b\t.cmd
PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\b
PS> t.cmd
from a

That last line should output from b (also see "Expected haviour" below). Note that clearing env:PATH before all this is "optional" - the behavior is the same.

Interestingly, if you repeat $env:PATH=$env:PATH + ';.' in another directory (like above in $env:TEMP\b), then this new directory will be considered for the '.' (that is above invoking t.cmd would output from b, regardless of where the actual Get-Location is at).

Example:

PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\b
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from b
PS> cd $env:TEMP\a
PS> t.cmd
from b

Tests have been done with 7.1.3, but same behavior can be observed with 7.2.0-preview7.

Expected behavior

PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\a
PS> t.cmd
from b

Actual behavior

PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\a
PS> t.cmd
from a

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.1.3
PSEdition                      Core
GitCommitId                    7.1.3
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

cklutz avatar Jul 19 '21 06:07 cklutz

Hi, any news or opinions on this? I would have thought this to be a common issue with people migrating from typical CMD based envs, but then may not :-)

cklutz avatar Sep 06 '21 07:09 cklutz

I vote to get this triaged also.

Adding '.' to the PATH list should always resolve to the current path when you change directories!

timkgithub avatar Oct 15 '21 00:10 timkgithub

What is cmd.exe and bash behavior?

iSazonov avatar Oct 15 '21 12:10 iSazonov

Bash and CMD.EXE treat it exactly like this. As possibly any other shell (csh ksh sh …). Which is why I opened this issue in the first place. I think even Windows powershell does it that way, but cannot verify right now.

cklutz avatar Oct 15 '21 15:10 cklutz

It looks to me PowerShell command discovery somehow cached the t.cmd it found from the first time. From your example repro above, continue to run the following:

> cd c:\   # move to a completely unrelated location, which doesn't contain a 't.cmd' file
> t.cmd
from a

daxian-dbw avatar Nov 10 '21 23:11 daxian-dbw

@daxian-dbw, it looks like it isn't the specific command whose location is cached, it is the entire $env:PATH value, with . getting resolved to the current directory at the time of caching.

Given PowerShell's - sensible - requirement to use .\ or ./ to invoke executables located in the current directory, I think it would make more sense to simply ignore attempts to add . to $env:PATH.

Arguably, even the current - obscure and probably accidental - behavior introduces a security vulnerability from that perspective.

mklement0 avatar Apr 12 '23 22:04 mklement0

@mklement0 I agree with your general sentiment about security. On some unix systems (or with some accounts) you also don't want to have the dot in your path and invoke all commands explicitly using ./command.

However, that should be the user's choice! Not the default forced upon by the shell.

(One could image a variable, say, $CurrentDirectoryWarningBehavior with a value of Enabled, that prints a warning every time PS uses the . to resolve a command from the path. - if that is possible at all, I don't know)

Because this issue is a regression to existing behavior and "prior work", confusing and annoying to users coming from or being experienced with:

  • PowerShell (for Windows)
  • a diversity of UNIX shells
  • CMD.exe

cklutz avatar Apr 13 '23 03:04 cklutz

@cklutz, you're right, I didn't realize it was a regression (I mistakenly thought it was broken in Windows PowerShell too).

By the way, on macOS a . entry is seemingly ignored altogether, whereas WSL with Ubuntu 20.04 seems to exhibit the same behavior as on Windows.

We're clearly dealing with a bug that needs to be resolved one way or the other.

I see your point about not forcing a choice upon the user, and personally I have no strong feelings about how this should be resolved.

To mention another possibility: emit a warning by default if . is found in $env:PATH on startup or whenever $env:PATH is modified in session with a value that has a . entry, and offer an opt-out preference variable.

mklement0 avatar Apr 13 '23 11:04 mklement0

P.S., @cklutz

As a workaround or possibly even something you may adopt as an alternative to trying to put . in $env:PATH you can rely on tab-completion to avoid having to type .\ or ./ every time.

This works as intended by default on Windows, but requires some tweaking on Unix-like platforms for a smooth experience (see this SO answer).

mklement0 avatar Apr 13 '23 12:04 mklement0

I gotta agree with @timkgithub and @cklutz. Let it do the obvious thing that everyone would expect. I hope this can be fixed the straightforward way.

szalapski avatar Apr 13 '23 18:04 szalapski

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

Hello everyone, This is still very much a problem. A resolution would be rather welcome eventually. Let me ping the bot if I can. 🌴

fguitton avatar Nov 16 '23 13:11 fguitton

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Please don't close issues that are real and affecting many.

szalapski avatar Nov 24 '23 01:11 szalapski

The @WG group discussed this and agree that it's a bug. While there is a security aspect about this, it's still an explicit action that the user has taken. However, the real issue is that if you add "." to your path, the wrong location has been added to you path, once you change your location the previous location is remembered. and $env:PATH may not represent the actual path (since . has been changed to /tmp but is not reflected.

JamesWTruher avatar Feb 05 '24 20:02 JamesWTruher

This needs to stay open a bit longer; presumably until @JamesWTruher comes back to us with another update on this bug 🐞

fguitton avatar Aug 05 '24 08:08 fguitton