aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/load/pkg.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2018-02-09 11:06:38 -0500
committerRuss Cox <rsc@golang.org>2018-02-09 11:06:38 -0500
commit3959ce667657defe1c99984adde93ca496953765 (patch)
treeaf968ed3ce81db796e82585384d13c38caac7960 /src/cmd/go/internal/load/pkg.go
parentf4e5ebdf35c8252329dc4d43d4e77ab05f1c41b9 (diff)
parent6732fcc06df713fc737cee5c5860bad87599bc6d (diff)
downloadgo-3959ce667657defe1c99984adde93ca496953765.tar.gz
go-3959ce667657defe1c99984adde93ca496953765.zip
[dev.boringcrypto.go1.9] all: merge go1.9.4 into dev.boringcrypto
Change-Id: Ieff4c038bdd8babc9db764bd088d981f4a0805d5
Diffstat (limited to 'src/cmd/go/internal/load/pkg.go')
-rw-r--r--src/cmd/go/internal/load/pkg.go94
1 files changed, 78 insertions, 16 deletions
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 4fbde1de8c..f5f21dfd35 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -18,6 +18,7 @@ import (
"sort"
"strings"
"unicode"
+ "unicode/utf8"
"cmd/go/internal/base"
"cmd/go/internal/buildid"
@@ -53,6 +54,8 @@ type PackagePublic struct {
BinaryOnly bool `json:",omitempty"` // package cannot be recompiled
// Source files
+ // If you add to this list you MUST add to p.AllFiles (below) too.
+ // Otherwise file name security lists will not apply to any new additions.
GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
CgoFiles []string `json:",omitempty"` // .go sources files that import "C"
IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
@@ -84,12 +87,38 @@ type PackagePublic struct {
DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
// Test information
+ // If you add to this list you MUST add to p.AllFiles (below) too.
+ // Otherwise file name security lists will not apply to any new additions.
TestGoFiles []string `json:",omitempty"` // _test.go files in package
TestImports []string `json:",omitempty"` // imports from TestGoFiles
XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
}
+// AllFiles returns the names of all the files considered for the package.
+// This is used for sanity and security checks, so we include all files,
+// even IgnoredGoFiles, because some subcommands consider them.
+// The go/build package filtered others out (like foo_wrongGOARCH.s)
+// and that's OK.
+func (p *Package) AllFiles() []string {
+ return str.StringList(
+ p.GoFiles,
+ p.CgoFiles,
+ p.IgnoredGoFiles,
+ p.CFiles,
+ p.CXXFiles,
+ p.MFiles,
+ p.HFiles,
+ p.FFiles,
+ p.SFiles,
+ p.SwigFiles,
+ p.SwigCXXFiles,
+ p.SysoFiles,
+ p.TestGoFiles,
+ p.XTestGoFiles,
+ )
+}
+
type PackageInternal struct {
// Unexported fields are not part of the public API.
Build *build.Package
@@ -1031,22 +1060,8 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) *Package
// To avoid problems on case-insensitive files, we reject any package
// where two different input files have equal names under a case-insensitive
// comparison.
- f1, f2 := str.FoldDup(str.StringList(
- p.GoFiles,
- p.CgoFiles,
- p.IgnoredGoFiles,
- p.CFiles,
- p.CXXFiles,
- p.MFiles,
- p.HFiles,
- p.FFiles,
- p.SFiles,
- p.SysoFiles,
- p.SwigFiles,
- p.SwigCXXFiles,
- p.TestGoFiles,
- p.XTestGoFiles,
- ))
+ inputs := p.AllFiles()
+ f1, f2 := str.FoldDup(inputs)
if f1 != "" {
p.Error = &PackageError{
ImportStack: stk.Copy(),
@@ -1055,6 +1070,37 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) *Package
return p
}
+ // If first letter of input file is ASCII, it must be alphanumeric.
+ // This avoids files turning into flags when invoking commands,
+ // and other problems we haven't thought of yet.
+ // Also, _cgo_ files must be generated by us, not supplied.
+ // They are allowed to have //go:cgo_ldflag directives.
+ // The directory scan ignores files beginning with _,
+ // so we shouldn't see any _cgo_ files anyway, but just be safe.
+ for _, file := range inputs {
+ if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
+ p.Error = &PackageError{
+ ImportStack: stk.Copy(),
+ Err: fmt.Sprintf("invalid input file name %q", file),
+ }
+ return p
+ }
+ }
+ if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
+ p.Error = &PackageError{
+ ImportStack: stk.Copy(),
+ Err: fmt.Sprintf("invalid input directory name %q", name),
+ }
+ return p
+ }
+ if !SafeArg(p.ImportPath) {
+ p.Error = &PackageError{
+ ImportStack: stk.Copy(),
+ Err: fmt.Sprintf("invalid import path %q", p.ImportPath),
+ }
+ return p
+ }
+
// Build list of imported packages and full dependency list.
imports := make([]*Package, 0, len(p.Imports))
deps := make(map[string]*Package)
@@ -1170,6 +1216,22 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) *Package
return p
}
+// SafeArg reports whether arg is a "safe" command-line argument,
+// meaning that when it appears in a command-line, it probably
+// doesn't have some special meaning other than its own name.
+// Obviously args beginning with - are not safe (they look like flags).
+// Less obviously, args beginning with @ are not safe (they look like
+// GNU binutils flagfile specifiers, sometimes called "response files").
+// To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
+// We accept leading . _ and / as likely in file system paths.
+func SafeArg(name string) bool {
+ if name == "" {
+ return false
+ }
+ c := name[0]
+ return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
+}
+
// usesSwig reports whether the package needs to run SWIG.
func (p *Package) UsesSwig() bool {
return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0