Skip to content

os/exec: modifications to Path ignored when *Cmd is created using Command with an absolute path on Windows #68314

@dmitshur

Description

@dmitshur

This can be reproduced at tip, go1.23rc1, and go1.22.5 on Windows (but not other OSes).
go1.22.4 and go1.21.12 are unaffected.

What did you do?

Create an *exec.Cmd using exec.Command, giving it an absolute path.
Modify its Path field (and, optionally, Args[0]) to point to another command.
Run it.

What did you see happen?

The modified value of Cmd.Path is ignored. The command that's actually invoked is from the original Command call.

What did you expect to see?

The command whose path is specified in Cmd.Path is the one that's executed.


Here's a small reproducer. For brevity, it uses the go and gofmt binaries.

package main

import (
	"fmt"
	"os/exec"
)

func main() {
	const exe1 = `C:\Program Files\Go\bin\go.exe`
	const exe2 = `C:\Program Files\Go\bin\gofmt.exe`

	cmd := exec.Command(exe1)
	cmd.Path = exe2
	cmd.Args = []string{cmd.Path}

	if err := cmd.Run(); err == nil {
		fmt.Println("OK: gofmt was executed")
	} else {
		fmt.Printf("fail: go was executed despite cmd.Path = %s\n", cmd.Path)
	}
}
$ GOTOOLCHAIN=go1.22.4  go run ./p.go
OK: gofmt was executed
$ GOTOOLCHAIN=go1.21.12 go run ./p.go
OK: gofmt was executed
$ GOTOOLCHAIN=go1.23rc1 go run ./p.go
fail: go was executed despite cmd.Path = C:\Program Files\Go\bin\gofmt.exe
$ GOTOOLCHAIN=go1.22.5  go run ./p.go
fail: go was executed despite cmd.Path = C:\Program Files\Go\bin\gofmt.exe

CC @golang/windows, @ianlancetaylor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CriticalA critical problem that affects the availability or correctness of production systems built using GoFrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.OS-Windowsrelease-blocker

    Type

    No type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions