aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/go/internal/load/pkg.go4
-rw-r--r--src/cmd/go/internal/work/exec.go6
-rw-r--r--src/cmd/go/script_test.go1
-rw-r--r--src/cmd/go/testdata/script/build_cwd_newline.txt100
4 files changed, 111 insertions, 0 deletions
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 046f508545..2e94929651 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -1945,6 +1945,10 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
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 c24d210711..567f045922 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -528,6 +528,12 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
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 25ce3709b0..baf531c231 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -188,6 +188,7 @@ func (ts *testScript) setup() {
"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 0000000000..61c6966b02
--- /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()
+}