@@ -332,6 +332,10 @@ type Cmd struct {
332
332
// See https://go.dev/blog/path-security
333
333
// and https://go.dev/issue/43724 for more context.
334
334
lookPathErr error
335
+
336
+ // cachedLookExtensions caches the result of calling lookExtensions.
337
+ // This is only used on Windows.
338
+ cachedLookExtensions string
335
339
}
336
340
337
341
// A ctxResult reports the result of watching the Context associated with a
@@ -430,16 +434,13 @@ func Command(name string, arg ...string) *Cmd {
430
434
// We may need to add a filename extension from PATHEXT
431
435
// or verify an extension that is already present.
432
436
// Since the path is absolute, its extension should be unambiguous
433
- // and independent of cmd.Dir, and we can go ahead and update cmd.Path to
434
- // reflect it.
437
+ // and independent of cmd.Dir, and we can go ahead and cache the lookup now.
435
438
//
436
439
// Note that we cannot add an extension here for relative paths, because
437
440
// cmd.Dir may be set after we return from this function and that may cause
438
441
// the command to resolve to a different extension.
439
442
lp , err := lookExtensions (name , "" )
440
- if lp != "" {
441
- cmd .Path = lp
442
- }
443
+ cmd .cachedLookExtensions = lp
443
444
if err != nil {
444
445
cmd .Err = err
445
446
}
@@ -641,7 +642,10 @@ func (c *Cmd) Start() error {
641
642
return c .Err
642
643
}
643
644
lp := c .Path
644
- if runtime .GOOS == "windows" && ! filepath .IsAbs (c .Path ) {
645
+ if c .cachedLookExtensions != "" {
646
+ lp = c .cachedLookExtensions
647
+ }
648
+ if runtime .GOOS == "windows" && c .cachedLookExtensions == "" {
645
649
// If c.Path is relative, we had to wait until now
646
650
// to resolve it in case c.Dir was changed.
647
651
// (If it is absolute, we already resolved its extension in Command
0 commit comments