src/cmd/go/internal/load/pkg.go | 4 ++++ src/cmd/go/internal/work/exec.go | 6 ++++++ src/cmd/go/script_test.go | 1 + src/cmd/go/testdata/script/build_cwd_newline.txt | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 046f508545499d95bd187001bcb30a0376f47950..2e94929651fcf9460e47a253a0a07e54dee0a4e1 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -1945,6 +1945,10 @@ if name := pathpkg.Base(p.ImportPath); !SafeArg(name) { setError(fmt.Errorf("invalid input directory name %q", name)) return } + if strings.ContainsAny(p.Dir, "\r\n") { + setError(fmt.Errorf("invalid package directory %q", p.Dir)) + return + } // Build list of imported packages and full dependency list. imports := make([]*Package, 0, len(p.Imports)) diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index c24d210711a31fe97bd49c3ab5eb164499d247b6..567f0459222dd0af2efbc4a7d0df21c62ff2671d 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -528,6 +528,12 @@ if cfg.BuildV { b.Print(a.Package.ImportPath + "\n") } + if p.Error != nil { + // Don't try to build anything for packages with errors. There may be a + // problem with the inputs that makes the package unsafe to build. + return p.Error + } + if a.Package.BinaryOnly { p.Stale = true p.StaleReason = "binary-only packages are no longer supported" diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go index 25ce3709b04e26f5364f89ba97422dfea0d58bbe..baf531c2315d9567c0546ae5a9465425ac93e7c5 100644 --- a/src/cmd/go/script_test.go +++ b/src/cmd/go/script_test.go @@ -188,6 +188,7 @@ tempEnvName() + "=" + filepath.Join(ts.workdir, "tmp"), "devnull=" + os.DevNull, "goversion=" + goVersion(ts), "CMDGO_TEST_RUN_MAIN=true", + "newline=\n", } if testenv.Builder() != "" || os.Getenv("GIT_TRACE_CURL") == "1" { // To help diagnose https://go.dev/issue/52545, diff --git a/src/cmd/go/testdata/script/build_cwd_newline.txt b/src/cmd/go/testdata/script/build_cwd_newline.txt new file mode 100644 index 0000000000000000000000000000000000000000..61c6966b02c9feb9c6a0c52ebef0f287a02afaf5 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cwd_newline.txt @@ -0,0 +1,100 @@ +[windows] skip 'filesystem normalizes / to \' +[plan9] skip 'filesystem disallows \n in paths' + +# If the directory path containing a package to be built includes a newline, +# the go command should refuse to even try to build the package. + +env DIR=$WORK${/}${newline}'package main'${newline}'func main() { panic("uh-oh")'${newline}'/*' + +mkdir $DIR +cd $DIR +exec pwd +cp $WORK/go.mod ./go.mod +cp $WORK/main.go ./main.go +cp $WORK/main_test.go ./main_test.go + +! go build -o $devnull . +stderr 'package example: invalid package directory .*uh-oh' + +! go build -o $devnull main.go +stderr 'package command-line-arguments: invalid package directory .*uh-oh' + +! go run . +stderr 'package example: invalid package directory .*uh-oh' + +! go run main.go +stderr 'package command-line-arguments: invalid package directory .*uh-oh' + +! go test . +stderr 'package example: invalid package directory .*uh-oh' + +! go test -v main.go main_test.go +stderr 'package command-line-arguments: invalid package directory .*uh-oh' + + +# Since we do preserve $PWD (or set it appropriately) for commands, and we do +# not resolve symlinks unnecessarily, referring to the contents of the unsafe +# directory via a safe symlink should be ok, and should not inject the data from +# the symlink target path. + +[!symlink] stop 'remainder of test checks symlink behavior' +[short] stop 'links and runs binaries' + +symlink $WORK${/}link -> $DIR + +go run $WORK${/}link${/}main.go +! stdout panic +! stderr panic +stderr '^ok$' + +go test -v $WORK${/}link${/}main.go $WORK${/}link${/}main_test.go +! stdout panic +! stderr panic +stdout '^ok$' # 'go test' combines the test's stdout into stderr + +cd $WORK/link + +! go run $DIR${/}main.go +stderr 'package command-line-arguments: invalid package directory .*uh-oh' + +go run . +! stdout panic +! stderr panic +stderr '^ok$' + +go run main.go +! stdout panic +! stderr panic +stderr '^ok$' + +go test -v +! stdout panic +! stderr panic +stdout '^ok$' # 'go test' combines the test's stdout into stderr + +go test -v . +! stdout panic +! stderr panic +stdout '^ok$' # 'go test' combines the test's stdout into stderr + + +-- $WORK/go.mod -- +module example +go 1.19 +-- $WORK/main.go -- +package main + +import "C" + +func main() { + /* nothing here */ + println("ok") +} +-- $WORK/main_test.go -- +package main + +import "testing" + +func TestMain(*testing.M) { + main() +}