Skip to content

Commit 6161935

Browse files
qiulaidongfenggopherbot
authored andcommitted
os/exec: avoid calling LookPath in cmd.Start for resolved paths
Follow up on CL 511458, see https://go-review.googlesource.com/c/go/+/511458/2..4/src/cmd/go/main.go#b270 . For #36768. Change-Id: Icc2a4dbb1219b1d69dd10a900478957b0e975847 Change-Id: Icc2a4dbb1219b1d69dd10a900478957b0e975847 GitHub-Last-Rev: bac7e66 GitHub-Pull-Request: #61517 Reviewed-on: https://go-review.googlesource.com/c/go/+/512155 Auto-Submit: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]>
1 parent 7fed338 commit 6161935

File tree

5 files changed

+65
-32
lines changed

5 files changed

+65
-32
lines changed

src/os/exec/exec.go

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -590,32 +590,6 @@ func (c *Cmd) Run() error {
590590
return c.Wait()
591591
}
592592

593-
// lookExtensions finds windows executable by its dir and path.
594-
// It uses LookPath to try appropriate extensions.
595-
// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
596-
func lookExtensions(path, dir string) (string, error) {
597-
if filepath.Base(path) == path {
598-
path = "." + string(filepath.Separator) + path
599-
}
600-
if dir == "" {
601-
return LookPath(path)
602-
}
603-
if filepath.VolumeName(path) != "" {
604-
return LookPath(path)
605-
}
606-
if len(path) > 1 && os.IsPathSeparator(path[0]) {
607-
return LookPath(path)
608-
}
609-
dirandpath := filepath.Join(dir, path)
610-
// We assume that LookPath will only add file extension.
611-
lp, err := LookPath(dirandpath)
612-
if err != nil {
613-
return "", err
614-
}
615-
ext := strings.TrimPrefix(lp, dirandpath)
616-
return path + ext, nil
617-
}
618-
619593
// Start starts the specified command but does not wait for it to complete.
620594
//
621595
// If Start returns successfully, the c.Process field will be set.
@@ -649,13 +623,11 @@ func (c *Cmd) Start() error {
649623
}
650624
return c.Err
651625
}
652-
if runtime.GOOS == "windows" {
653-
lp, err := lookExtensions(c.Path, c.Dir)
654-
if err != nil {
655-
return err
656-
}
657-
c.Path = lp
626+
lp, err := lookExtensions(c.Path, c.Dir)
627+
if err != nil {
628+
return err
658629
}
630+
c.Path = lp
659631
if c.Cancel != nil && c.ctx == nil {
660632
return errors.New("exec: command with a non-nil Cancel was not created with CommandContext")
661633
}

src/os/exec/lp_plan9.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,9 @@ func LookPath(file string) (string, error) {
6464
}
6565
return "", &Error{file, ErrNotFound}
6666
}
67+
68+
// lookExtensions is a no-op on non-Windows platforms, since
69+
// they do not restrict executables to specific extensions.
70+
func lookExtensions(path, dir string) (string, error) {
71+
return path, nil
72+
}

src/os/exec/lp_unix.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,9 @@ func LookPath(file string) (string, error) {
8080
}
8181
return "", &Error{file, ErrNotFound}
8282
}
83+
84+
// lookExtensions is a no-op on non-Windows platforms, since
85+
// they do not restrict executables to specific extensions.
86+
func lookExtensions(path, dir string) (string, error) {
87+
return path, nil
88+
}

src/os/exec/lp_wasm.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ func LookPath(file string) (string, error) {
2121
// Wasm can not execute processes, so act as if there are no executables at all.
2222
return "", &Error{file, ErrNotFound}
2323
}
24+
25+
// lookExtensions is a no-op on non-Windows platforms, since
26+
// they do not restrict executables to specific extensions.
27+
func lookExtensions(path, dir string) (string, error) {
28+
return path, nil
29+
}

src/os/exec/lp_windows.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,45 @@ func findExecutable(file string, exts []string) (string, error) {
6363
// As of Go 1.19, LookPath will instead return that path along with an error satisfying
6464
// errors.Is(err, ErrDot). See the package documentation for more details.
6565
func LookPath(file string) (string, error) {
66+
return lookPath(file, pathExt())
67+
}
68+
69+
// lookExtensions finds windows executable by its dir and path.
70+
// It uses LookPath to try appropriate extensions.
71+
// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
72+
func lookExtensions(path, dir string) (string, error) {
73+
if filepath.Base(path) == path {
74+
path = "." + string(filepath.Separator) + path
75+
}
76+
exts := pathExt()
77+
if ext := filepath.Ext(path); ext != "" {
78+
for _, e := range exts {
79+
if strings.EqualFold(ext, e) {
80+
// Assume that path has already been resolved.
81+
return path, nil
82+
}
83+
}
84+
}
85+
if dir == "" {
86+
return lookPath(path, exts)
87+
}
88+
if filepath.VolumeName(path) != "" {
89+
return lookPath(path, exts)
90+
}
91+
if len(path) > 1 && os.IsPathSeparator(path[0]) {
92+
return lookPath(path, exts)
93+
}
94+
dirandpath := filepath.Join(dir, path)
95+
// We assume that LookPath will only add file extension.
96+
lp, err := lookPath(dirandpath, exts)
97+
if err != nil {
98+
return "", err
99+
}
100+
ext := strings.TrimPrefix(lp, dirandpath)
101+
return path + ext, nil
102+
}
103+
104+
func pathExt() []string {
66105
var exts []string
67106
x := os.Getenv(`PATHEXT`)
68107
if x != "" {
@@ -78,7 +117,11 @@ func LookPath(file string) (string, error) {
78117
} else {
79118
exts = []string{".com", ".exe", ".bat", ".cmd"}
80119
}
120+
return exts
121+
}
81122

123+
// lookPath implements LookPath for the given PATHEXT list.
124+
func lookPath(file string, exts []string) (string, error) {
82125
if strings.ContainsAny(file, `:\/`) {
83126
f, err := findExecutable(file, exts)
84127
if err == nil {

0 commit comments

Comments
 (0)