From db2f680fdfc9118013cb3996e3ea8664c196e6ba Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" <bcmills@google.com> Date: Tue, 24 Jul 2018 19:10:08 -0400 Subject: [PATCH] cmd/go: allow internal imports based on module paths Updates #23970. Change-Id: I2e69ad15b9d1097bfeef9947f03cfa6834a6a049 Reviewed-on: https://go-review.googlesource.com/125676 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 | 31 +++++++++---- .../golang.org_notx_useinternal_v0.1.0.txt | 13 ++++++ .../mod/golang.org_x_internal_v0.1.0.txt | 43 ++++++++++++++++++ .../mod/golang.org_x_useinternal_v0.1.0.txt | 13 ++++++ src/cmd/go/testdata/script/mod_internal.txt | 44 +++++++++++++++++++ 5 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 src/cmd/go/testdata/mod/golang.org_notx_useinternal_v0.1.0.txt create mode 100644 src/cmd/go/testdata/mod/golang.org_x_internal_v0.1.0.txt create mode 100644 src/cmd/go/testdata/mod/golang.org_x_useinternal_v0.1.0.txt create mode 100644 src/cmd/go/testdata/script/mod_internal.txt diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 50cd01f8c4..d1cd520245 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -961,16 +961,29 @@ func disallowInternal(srcDir string, p *Package, stk *ImportStack) *Package { if i > 0 { i-- // rewind over slash in ".../internal" } - parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] - if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { - return p - } + if p.Module == nil { + parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] - // Look for symlinks before reporting error. - srcDir = expandPath(srcDir) - parent = expandPath(parent) - if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { - return p + if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { + return p + } + + // Look for symlinks before reporting error. + srcDir = expandPath(srcDir) + parent = expandPath(parent) + if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { + return p + } + } else { + // 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) { + return p + } } // Internal is present, and srcDir is outside parent's tree. Not allowed. diff --git a/src/cmd/go/testdata/mod/golang.org_notx_useinternal_v0.1.0.txt b/src/cmd/go/testdata/mod/golang.org_notx_useinternal_v0.1.0.txt new file mode 100644 index 0000000000..0420a1a4a0 --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_notx_useinternal_v0.1.0.txt @@ -0,0 +1,13 @@ +written by hand — attempts to use a prohibited internal package +(https://golang.org/s/go14internal) + +-- .mod -- +module golang.org/notx/useinternal +-- .info -- +{"Version":"v0.1.0","Name":"","Short":"","Time":"2018-07-25T17:24:00Z"} +-- go.mod -- +module golang.org/notx/useinternal +-- useinternal.go -- +package useinternal + +import _ "golang.org/x/internal/subtle" diff --git a/src/cmd/go/testdata/mod/golang.org_x_internal_v0.1.0.txt b/src/cmd/go/testdata/mod/golang.org_x_internal_v0.1.0.txt new file mode 100644 index 0000000000..5737e95cf4 --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_x_internal_v0.1.0.txt @@ -0,0 +1,43 @@ +written by hand — loosely derived from golang.org/x/crypto/internal/subtle, +but splitting the internal package across a module boundary + +-- .mod -- +module golang.org/x/internal +-- .info -- +{"Version":"v0.1.0","Name":"","Short":"","Time":"2018-07-25T17:24:00Z"} +-- go.mod -- +module golang.org/x/internal +-- subtle/aliasing.go -- +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !appengine + +// This is a tiny version of golang.org/x/crypto/internal/subtle. + +package subtle + +import "unsafe" + +func AnyOverlap(x, y []byte) bool { + return len(x) > 0 && len(y) > 0 && + uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && + uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) +} +-- subtle/aliasing_appengine.go -- +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build appengine + +package subtle + +import "reflect" + +func AnyOverlap(x, y []byte) bool { + return len(x) > 0 && len(y) > 0 && + reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() && + reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer() +} diff --git a/src/cmd/go/testdata/mod/golang.org_x_useinternal_v0.1.0.txt b/src/cmd/go/testdata/mod/golang.org_x_useinternal_v0.1.0.txt new file mode 100644 index 0000000000..3fcba447be --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_x_useinternal_v0.1.0.txt @@ -0,0 +1,13 @@ +written by hand — uses an internal package from another module +(https://golang.org/s/go14internal) + +-- .mod -- +module golang.org/x/useinternal +-- .info -- +{"Version":"v0.1.0","Name":"","Short":"","Time":"2018-07-25T17:24:00Z"} +-- go.mod -- +module golang.org/x/useinternal +-- useinternal.go -- +package useinternal + +import _ "golang.org/x/internal/subtle" diff --git a/src/cmd/go/testdata/script/mod_internal.txt b/src/cmd/go/testdata/script/mod_internal.txt new file mode 100644 index 0000000000..5ad392c088 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_internal.txt @@ -0,0 +1,44 @@ +env GO111MODULE=on + +# golang.org/x/internal should be importable from other golang.org/x modules. +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' + +# Internal packages in the standard library should not leak into modules. +! go build ./fromstd +stderr 'use of internal package' + + +# Dependencies should be able to use their own internal modules... +rm go.mod +go mod -init -module golang.org/notx +go build ./throughdep + +# ... but other modules should not, even if they have transitive dependencies. +! go build . +stderr 'use of internal package' + +# And transitive dependencies still should not leak. +! go build ./baddep +stderr 'use of internal package' + + +-- useinternal.go -- +package useinternal +import _ "golang.org/x/internal/subtle" + +-- throughdep/useinternal.go -- +package throughdep +import _ "golang.org/x/useinternal" + +-- baddep/useinternal.go -- +package baddep +import _ "golang.org/notx/useinternal" + +-- fromstd/useinternal.go -- +package fromstd +import _ "internal/testenv" -- 2.30.9