aboutsummaryrefslogtreecommitdiff
path: root/src/os/exec/lp_windows.go
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2022-06-24 15:36:25 -0400
committerBryan Mills <bcmills@google.com>2022-06-28 19:29:51 +0000
commit3580ef9d64bdc0176cde032d170737a6e67ef8f2 (patch)
treeb8ac2d1a7f02597afe0b60504cd4a3d62484cd55 /src/os/exec/lp_windows.go
parent34f3ac5f165d50356d3a8940dc87b77e9b2b7fb9 (diff)
downloadgo-3580ef9d64bdc0176cde032d170737a6e67ef8f2.tar.xz
os/exec: on Windows, suppress ErrDot if the implicit path matches the explicit one
If the current directory is also listed explicitly in %PATH%, this changes the behavior of LookPath to prefer the explicit name for it (and thereby avoid ErrDot). However, in order to avoid running a different executable from what would have been run by previous Go versions, we still return the implicit path (and ErrDot) if it refers to a different file entirely. Fixes #53536. Updates #43724. Change-Id: I7ab01074e21a0e8b07a176e3bc6d3b8cf0c873cd Reviewed-on: https://go-review.googlesource.com/c/go/+/414054 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/os/exec/lp_windows.go')
-rw-r--r--src/os/exec/lp_windows.go25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
index dab5770298..da047585eb 100644
--- a/src/os/exec/lp_windows.go
+++ b/src/os/exec/lp_windows.go
@@ -96,20 +96,43 @@ func LookPath(file string) (string, error) {
// have configured their environment this way!
// https://docs.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-needcurrentdirectoryforexepathw
// See also go.dev/issue/43947.
+ var (
+ dotf string
+ dotErr error
+ )
if _, found := syscall.Getenv("NoDefaultCurrentDirectoryInExePath"); !found {
if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
- return f, &Error{file, ErrDot}
+ dotf, dotErr = f, &Error{file, ErrDot}
}
}
path := os.Getenv("path")
for _, dir := range filepath.SplitList(path) {
if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
+ if dotErr != nil {
+ // https://go.dev/issue/53536: if we resolved a relative path implicitly,
+ // and it is the same executable that would be resolved from the explicit %PATH%,
+ // prefer the explicit name for the executable (and, likely, no error) instead
+ // of the equivalent implicit name with ErrDot.
+ //
+ // Otherwise, return the ErrDot for the implicit path as soon as we find
+ // out that the explicit one doesn't match.
+ dotfi, dotfiErr := os.Lstat(dotf)
+ fi, fiErr := os.Lstat(f)
+ if dotfiErr != nil || fiErr != nil || !os.SameFile(dotfi, fi) {
+ return dotf, dotErr
+ }
+ }
+
if !filepath.IsAbs(f) {
return f, &Error{file, ErrDot}
}
return f, nil
}
}
+
+ if dotErr != nil {
+ return dotf, dotErr
+ }
return "", &Error{file, ErrNotFound}
}