]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: prohibit modules from importing vendored golang_org packages
authorBryan C. Mills <bcmills@google.com>
Wed, 25 Jul 2018 19:56:43 +0000 (15:56 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 31 Jul 2018 02:04:53 +0000 (02:04 +0000)
Expand mod_internal tests to cover vendoring, replacements, and failure
messages.

Packages beginning with "golang_org/" resolve to $GOROOT/src/vendor, and should
therefore not be visible within module code.

Fixes #23970.

Change-Id: I706e9c4a1d1e025883e84b897972678d0fa3f2bd
Reviewed-on: https://go-review.googlesource.com/125836
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/go/internal/load/pkg.go
src/cmd/go/testdata/script/mod_internal.txt

index d1cd520245a2662866d7ac6910901f5cfd4105b2..c74ba5f63c6706b072246e0ad3e703c592aed928 100644 (file)
@@ -961,6 +961,8 @@ func disallowInternal(srcDir string, p *Package, stk *ImportStack) *Package {
        if i > 0 {
                i-- // rewind over slash in ".../internal"
        }
+
+       var where string
        if p.Module == nil {
                parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
 
@@ -978,19 +980,18 @@ func disallowInternal(srcDir string, p *Package, stk *ImportStack) *Package {
                // p is in a module, so make it available based on the import path instead
                // of the file path (https://golang.org/issue/23970).
                parent := p.ImportPath[:i]
-               // TODO(bcmills): In case of replacements, use the module path declared by
-               // the replacement module, not the path seen by the user.
-               importerPath := (*stk)[len(*stk)-2]
-               if strings.HasPrefix(importerPath, parent) {
+               importer := (*stk)[len(*stk)-2]
+               if str.HasPathPrefix(importer, parent) {
                        return p
                }
+               where = " in " + importer
        }
 
        // Internal is present, and srcDir is outside parent's tree. Not allowed.
        perr := *p
        perr.Error = &PackageError{
                ImportStack: stk.Copy(),
-               Err:         "use of internal package " + p.ImportPath + " not allowed",
+               Err:         "use of internal package " + p.ImportPath + " not allowed" + where,
        }
        perr.Incomplete = true
        return &perr
@@ -1027,6 +1028,29 @@ func disallowVendor(srcDir, path string, p *Package, stk *ImportStack) *Package
                return p
        }
 
+       if p.Standard && ModPackageModuleInfo != nil {
+               // Modules must not import vendor packages in the standard library,
+               // but the usual vendor visibility check will not catch them
+               // because the module loader presents them with an ImportPath starting
+               // with "golang_org/" instead of "vendor/".
+               importer := (*stk)[len(*stk)-2]
+               if mod := ModPackageModuleInfo(importer); mod != nil {
+                       dir := p.Dir
+                       if relDir, err := filepath.Rel(p.Root, p.Dir); err == nil {
+                               dir = relDir
+                       }
+                       if _, ok := FindVendor(filepath.ToSlash(dir)); ok {
+                               perr := *p
+                               perr.Error = &PackageError{
+                                       ImportStack: stk.Copy(),
+                                       Err:         "use of vendored package " + path + " not allowed",
+                               }
+                               perr.Incomplete = true
+                               return &perr
+                       }
+               }
+       }
+
        if perr := disallowVendorVisibility(srcDir, p, stk); perr != p {
                return perr
        }
index 5ad392c088447e4484d50417d69c5ba87a1c76cf..bbc84b168cdc44dfe700c48797df40f25edbc695 100644 (file)
@@ -1,16 +1,21 @@
 env GO111MODULE=on
 
 # golang.org/x/internal should be importable from other golang.org/x modules.
+rm go.mod
 go mod -init -module golang.org/x/anything
 go build .
 
 # ...but that should not leak into other modules.
 ! go build ./baddep
-stderr 'use of internal package'
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
 
 # Internal packages in the standard library should not leak into modules.
 ! go build ./fromstd
-stderr 'use of internal package'
+stderr 'use of internal package internal/testenv not allowed$'
+
+# Packages found via standard-library vendoring should not leak.
+! go build ./fromstdvendor
+stderr 'use of vendored package golang_org/x/net/http/httpguts not allowed$'
 
 
 # Dependencies should be able to use their own internal modules...
@@ -20,11 +25,27 @@ go build ./throughdep
 
 # ... but other modules should not, even if they have transitive dependencies.
 ! go build .
-stderr 'use of internal package'
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx$'
 
 # And transitive dependencies still should not leak.
 ! go build ./baddep
-stderr 'use of internal package'
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
+
+
+# Replacing an internal module should keep it internal to the same paths.
+rm go.mod
+go mod -init -module golang.org/notx
+go mod -replace golang.org/x/internal=./replace/golang.org/notx/internal
+go build ./throughdep
+
+! go build ./baddep
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
+
+go mod -replace golang.org/x/internal=./vendor/golang.org/x/internal
+go build ./throughdep
+
+! go build ./baddep
+stderr 'use of internal package golang.org/x/.* not allowed in golang.org/notx/useinternal$'
 
 
 -- useinternal.go --
@@ -42,3 +63,21 @@ import _ "golang.org/notx/useinternal"
 -- fromstd/useinternal.go --
 package fromstd
 import _ "internal/testenv"
+
+-- fromstdvendor/useinternal.go --
+package fromstdvendor
+import _ "golang_org/x/net/http/httpguts"
+
+-- replace/golang.org/notx/internal/go.mod --
+module golang.org/x/internal
+
+-- replace/golang.org/notx/internal/subtle/subtle.go --
+package subtle
+// Ha ha! Nothing here!
+
+-- vendor/golang.org/x/internal/go.mod --
+module golang.org/x/internal
+
+-- vendor/golang.org/x/internal/subtle/subtle.go --
+package subtle
+// Ha ha! Nothing here!