[dev.typeparams] all: merge master (296ddf2) into dev.typeparams

Conflicts:

- src/runtime/runtime2.go

  On master, CL 317191 fixed the mentions of gc/reflect.go in comments
  to reflectdata/reflect.go; but on dev.typeparams, CL 325921 fixed
  that the same comment to reflect that deferstruct actually ended up
  in ssagen/ssa.go.

Merge List:

+ 2021-07-08 296ddf2a93 net: filter bad names from Lookup functions instead of hard failing
+ 2021-07-08 ce76298ee7 Update oudated comment
+ 2021-07-08 2ca44fe221 doc/go1.17: linkify time.UnixMilli and time.UnixMicro
+ 2021-07-07 5c59e11f5e cmd/compile: remove special-casing of blank in types.sconv{,2}
+ 2021-07-07 b003a8b1ae cmd/compile: optimize types.sconv
+ 2021-07-07 11f5df2d67 cmd/compile: extract pkgqual from symfmt
+ 2021-07-07 991fd381d5 cmd/go: don't lock .mod and .sum files for read in overlay
+ 2021-07-07 186a3bb4b0 cmd/go/internal/modfetch/codehost: skip hg tests if no hg binary is present
+ 2021-07-07 00c00558e1 cmd/go/internal/modload: remove unused functions
+ 2021-07-07 f264879f74 cmd/go/internal/modload: fix an apparent typo in the AutoRoot comment
+ 2021-07-07 c96833e5ba doc: remove stale comment about arm64 port

Change-Id: I849046b6d8f7421f60323549f3f763ef418bf9e7
This commit is contained in:
Matthew Dempsky 2021-07-08 13:04:25 -07:00
commit 2b1d70a137
25 changed files with 401 additions and 201 deletions

View file

@ -827,10 +827,6 @@ The other codes are <code>-&gt;</code> (arithmetic right shift),
<h3 id="arm64">ARM64</h3>
<p>
The ARM64 port is in an experimental state.
</p>
<p>
<code>R18</code> is the "platform register", reserved on the Apple platform.
To prevent accidental misuse, the register is named <code>R18_PLATFORM</code>.

View file

@ -1132,10 +1132,13 @@ func Foo() bool {
<p><!-- CL 293349 -->
The new <a href="/pkg/time/#Time.UnixMilli"><code>Time.UnixMilli</code></a> and
<a href="/pkg/time/#Time.UnixMicro"><code>Time.UnixMicro</code></a> methods return the number of milliseconds and
microseconds elapsed since January 1, 1970 UTC respectively.<br>
The new <code>UnixMilli</code> and <code>UnixMicro</code> functions return local Time corresponding to given
Unix time.
<a href="/pkg/time/#Time.UnixMicro"><code>Time.UnixMicro</code></a>
methods return the number of milliseconds and microseconds elapsed since
January 1, 1970 UTC respectively.
<br />
The new <a href="/pkg/time/#UnixMilli"><code>UnixMilli</code></a> and
<a href="/pkg/time/#UnixMicro"><code>UnixMicro</code></a> functions
return the local <code>Time</code> corresponding to the given Unix time.
</p>
<p><!-- CL 300996 -->

View file

@ -651,7 +651,7 @@ var kinds = []int{
// tflag is documented in reflect/type.go.
//
// tflag values must be kept in sync with copies in:
// cmd/compile/internal/gc/reflect.go
// cmd/compile/internal/reflectdata/reflect.go
// cmd/link/internal/ld/decodesym.go
// reflect/type.go
// runtime/type.go

View file

@ -109,14 +109,18 @@ func sconv(s *Sym, verb rune, mode fmtMode) string {
return "<S>"
}
if s.Name == "_" {
return "_"
q := pkgqual(s.Pkg, verb, mode)
if q == "" {
return s.Name
}
buf := fmtBufferPool.Get().(*bytes.Buffer)
buf.Reset()
defer fmtBufferPool.Put(buf)
symfmt(buf, s, verb, mode)
buf.WriteString(q)
buf.WriteByte('.')
buf.WriteString(s.Name)
return InternString(buf.Bytes())
}
@ -128,56 +132,49 @@ func sconv2(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
b.WriteString("<S>")
return
}
if s.Name == "_" {
b.WriteString("_")
return
}
symfmt(b, s, verb, mode)
}
func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
if q := pkgqual(s.Pkg, verb, mode); q != "" {
b.WriteString(q)
b.WriteByte('.')
}
b.WriteString(s.Name)
}
// pkgqual returns the qualifier that should be used for printing
// symbols from the given package in the given mode.
// If it returns the empty string, no qualification is needed.
func pkgqual(pkg *Pkg, verb rune, mode fmtMode) string {
if verb != 'S' {
switch mode {
case fmtGo: // This is for the user
if s.Pkg == BuiltinPkg || s.Pkg == LocalPkg {
b.WriteString(s.Name)
return
if pkg == BuiltinPkg || pkg == LocalPkg {
return ""
}
// If the name was used by multiple packages, display the full path,
if s.Pkg.Name != "" && NumImport[s.Pkg.Name] > 1 {
fmt.Fprintf(b, "%q.%s", s.Pkg.Path, s.Name)
return
if pkg.Name != "" && NumImport[pkg.Name] > 1 {
return strconv.Quote(pkg.Path)
}
b.WriteString(s.Pkg.Name)
b.WriteByte('.')
b.WriteString(s.Name)
return
return pkg.Name
case fmtDebug:
b.WriteString(s.Pkg.Name)
b.WriteByte('.')
b.WriteString(s.Name)
return
return pkg.Name
case fmtTypeIDName:
// dcommontype, typehash
b.WriteString(s.Pkg.Name)
b.WriteByte('.')
b.WriteString(s.Name)
return
return pkg.Name
case fmtTypeID:
// (methodsym), typesym, weaksym
b.WriteString(s.Pkg.Prefix)
b.WriteByte('.')
b.WriteString(s.Name)
return
return pkg.Prefix
}
}
b.WriteString(s.Name)
return ""
}
// Type

View file

@ -11,7 +11,6 @@ import (
"io/fs"
"os"
"cmd/go/internal/fsys"
"cmd/go/internal/lockedfile/internal/filelock"
)
@ -21,7 +20,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
// calls for Linux and Windows anyway, so it's simpler to use that approach
// consistently.
f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
if err != nil {
return nil, err
}

View file

@ -13,8 +13,6 @@ import (
"os"
"strings"
"time"
"cmd/go/internal/fsys"
)
// Opening an exclusive-use file returns an error.
@ -59,7 +57,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
// If the file was unpacked or created by some other program, it might not
// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
// can be confident that a successful OpenFile implies exclusive use.
if fi, err := fsys.Stat(name); err == nil {
if fi, err := os.Stat(name); err == nil {
if fi.Mode()&fs.ModeExclusive == 0 {
if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
return nil, err
@ -72,7 +70,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
nextSleep := 1 * time.Millisecond
const maxSleep = 500 * time.Millisecond
for {
f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
if err == nil {
return f, nil
}

View file

@ -8,7 +8,6 @@ import (
"archive/zip"
"bytes"
"flag"
"fmt"
"internal/testenv"
"io"
"io/fs"
@ -47,12 +46,6 @@ var altRepos = []string{
var localGitRepo string
func testMain(m *testing.M) int {
if _, err := exec.LookPath("git"); err != nil {
fmt.Fprintln(os.Stderr, "skipping because git binary not found")
fmt.Println("PASS")
return 0
}
dir, err := os.MkdirTemp("", "gitrepo-test-")
if err != nil {
log.Fatal(err)
@ -60,23 +53,25 @@ func testMain(m *testing.M) int {
defer os.RemoveAll(dir)
if testenv.HasExternalNetwork() && testenv.HasExec() {
// Clone gitrepo1 into a local directory.
// If we use a file:// URL to access the local directory,
// then git starts up all the usual protocol machinery,
// which will let us test remote git archive invocations.
localGitRepo = filepath.Join(dir, "gitrepo2")
if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
log.Fatal(err)
}
if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
log.Fatal(err)
if _, err := exec.LookPath("git"); err == nil {
// Clone gitrepo1 into a local directory.
// If we use a file:// URL to access the local directory,
// then git starts up all the usual protocol machinery,
// which will let us test remote git archive invocations.
localGitRepo = filepath.Join(dir, "gitrepo2")
if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
log.Fatal(err)
}
if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
log.Fatal(err)
}
}
}
return m.Run()
}
func testRepo(remote string) (Repo, error) {
func testRepo(t *testing.T, remote string) (Repo, error) {
if remote == "localGitRepo" {
// Convert absolute path to file URL. LocalGitRepo will not accept
// Windows absolute paths because they look like a host:path remote.
@ -87,15 +82,17 @@ func testRepo(remote string) (Repo, error) {
} else {
url = "file:///" + filepath.ToSlash(localGitRepo)
}
testenv.MustHaveExecPath(t, "git")
return LocalGitRepo(url)
}
kind := "git"
vcs := "git"
for _, k := range []string{"hg"} {
if strings.Contains(remote, "/"+k+"/") {
kind = k
vcs = k
}
}
return NewRepo(kind, remote)
testenv.MustHaveExecPath(t, vcs)
return NewRepo(vcs, remote)
}
var tagsTests = []struct {
@ -116,7 +113,7 @@ func TestTags(t *testing.T) {
for _, tt := range tagsTests {
f := func(t *testing.T) {
r, err := testRepo(tt.repo)
r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@ -168,7 +165,7 @@ func TestLatest(t *testing.T) {
for _, tt := range latestTests {
f := func(t *testing.T) {
r, err := testRepo(tt.repo)
r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@ -221,7 +218,7 @@ func TestReadFile(t *testing.T) {
for _, tt := range readFileTests {
f := func(t *testing.T) {
r, err := testRepo(tt.repo)
r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@ -412,7 +409,7 @@ func TestReadZip(t *testing.T) {
for _, tt := range readZipTests {
f := func(t *testing.T) {
r, err := testRepo(tt.repo)
r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}
@ -581,7 +578,7 @@ func TestStat(t *testing.T) {
for _, tt := range statTests {
f := func(t *testing.T) {
r, err := testRepo(tt.repo)
r, err := testRepo(t, tt.repo)
if err != nil {
t.Fatal(err)
}

View file

@ -22,6 +22,7 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/fsys"
"cmd/go/internal/lockedfile"
"cmd/go/internal/par"
"cmd/go/internal/robustio"
@ -416,7 +417,18 @@ func initGoSum() (bool, error) {
goSum.m = make(map[module.Version][]string)
goSum.status = make(map[modSum]modSumStatus)
data, err := lockedfile.Read(GoSumFile)
var (
data []byte
err error
)
if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok {
// Don't lock go.sum if it's part of the overlay.
// On Plan 9, locking requires chmod, and we don't want to modify any file
// in the overlay. See #44700.
data, err = os.ReadFile(actualSumFile)
} else {
data, err = lockedfile.Read(GoSumFile)
}
if err != nil && !os.IsNotExist(err) {
return false, err
}
@ -716,6 +728,9 @@ Outer:
if cfg.BuildMod == "readonly" {
base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly")
}
if _, ok := fsys.OverlayPath(GoSumFile); ok {
base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
}
// Make a best-effort attempt to acquire the side lock, only to exclude
// previous versions of the 'go' command from making simultaneous edits.

View file

@ -71,7 +71,7 @@ type Root int
const (
// AutoRoot is the default for most commands. modload.Init will look for
// a go.mod file in the current directory or any parent. If none is found,
// modules may be disabled (GO111MODULE=on) or commands may run in a
// modules may be disabled (GO111MODULE=auto) or commands may run in a
// limited module mode.
AutoRoot Root = iota
@ -412,7 +412,16 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
}
gomod := ModFilePath()
data, err := lockedfile.Read(gomod)
var data []byte
var err error
if gomodActual, ok := fsys.OverlayPath(gomod); ok {
// Don't lock go.mod if it's part of the overlay.
// On Plan 9, locking requires chmod, and we don't want to modify any file
// in the overlay. See #44700.
data, err = os.ReadFile(gomodActual)
} else {
data, err = lockedfile.Read(gomodActual)
}
if err != nil {
base.Fatalf("go: %v", err)
}
@ -1026,6 +1035,13 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements)
}
return
}
gomod := ModFilePath()
if _, ok := fsys.OverlayPath(gomod); ok {
if dirty {
base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
}
return
}
new, err := modFile.Format()
if err != nil {

View file

@ -675,20 +675,6 @@ func DirImportPath(ctx context.Context, dir string) string {
return "."
}
// TargetPackages returns the list of packages in the target (top-level) module
// matching pattern, which may be relative to the working directory, under all
// build tag settings.
func TargetPackages(ctx context.Context, pattern string) *search.Match {
// TargetPackages is relative to the main module, so ensure that the main
// module is a thing that can contain packages.
LoadModFile(ctx) // Sets Target.
ModRoot() // Emits an error if Target cannot contain packages.
m := search.NewMatch(pattern)
matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{Target})
return m
}
// ImportMap returns the actual package import path
// for an import path found in source code.
// If the given import path does not appear in the source code
@ -720,29 +706,6 @@ func PackageModule(path string) module.Version {
return pkg.mod
}
// PackageImports returns the imports for the package named by the import path.
// Test imports will be returned as well if tests were loaded for the package
// (i.e., if "all" was loaded or if LoadTests was set and the path was matched
// by a command line argument). PackageImports will return nil for
// unknown package paths.
func PackageImports(path string) (imports, testImports []string) {
pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
if !ok {
return nil, nil
}
imports = make([]string, len(pkg.imports))
for i, p := range pkg.imports {
imports[i] = p.path
}
if pkg.test != nil {
testImports = make([]string, len(pkg.test.imports))
for i, p := range pkg.test.imports {
testImports[i] = p.path
}
}
return imports, testImports
}
// Lookup returns the source directory, import path, and any loading error for
// the package at path as imported from the package in parentDir.
// Lookup requires that one of the Load functions in this package has already

View file

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
@ -15,6 +16,7 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/fsys"
"cmd/go/internal/lockedfile"
"cmd/go/internal/modfetch"
"cmd/go/internal/par"
@ -601,8 +603,16 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
dir = filepath.Join(ModRoot(), dir)
}
gomod := filepath.Join(dir, "go.mod")
data, err := lockedfile.Read(gomod)
var data []byte
var err error
if gomodActual, ok := fsys.OverlayPath(gomod); ok {
// Don't lock go.mod if it's part of the overlay.
// On Plan 9, locking requires chmod, and we don't want to modify any file
// in the overlay. See #44700.
data, err = os.ReadFile(gomodActual)
} else {
data, err = lockedfile.Read(gomodActual)
}
if err != nil {
return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
}

View file

@ -920,8 +920,8 @@ func (e *PackageNotInModuleError) ImportPath() string {
return ""
}
// ModuleHasRootPackage returns whether module m contains a package m.Path.
func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
// moduleHasRootPackage returns whether module m contains a package m.Path.
func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
needSum := false
root, isLocal, err := fetch(ctx, m, needSum)
if err != nil {

View file

@ -21,7 +21,7 @@ go list -deps -overlay overlay.json .
cd $WORK/gopath/src/get-doesnt-add-dep
cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
! go get -d -overlay overlay.json .
stderr 'overlaid files can''t be opened for write'
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
# Content of overlaid go.sum is used.
@ -41,10 +41,10 @@ go mod verify -overlay overlay.json
# attempting to update the file
cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
! go get -d -overlay overlay.json .
stderr 'overlaid files can''t be opened for write'
stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
! go mod tidy -overlay overlay.json
stderr 'overlaid files can''t be opened for write'
stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
# -overlay works with -modfile.
@ -56,7 +56,7 @@ go list -modfile=alternate.mod -overlay overlay.json .
stdout 'found.the/module'
# Even with -modfile, overlaid files can't be opened for write.
! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote
stderr 'overlaid files can''t be opened for write'
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
# Carving out a module by adding an overlaid go.mod file
cd $WORK/gopath/src/carve
@ -78,7 +78,7 @@ go list -overlay overlay.json all
stdout ^carve2/nomod$
# Editing go.mod file fails because overlay is read only
! go get -overlay overlay.json -d rsc.io/quote
stderr 'overlaid files can''t be opened for write'
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod
# Editing go.mod file succeeds because we use -modfile to redirect to same file
go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote

View file

@ -16,12 +16,12 @@ import (
// Decoding the type.* symbols. This has to be in sync with
// ../../runtime/type.go, or more specifically, with what
// cmd/compile/internal/gc/reflect.go stuffs in these.
// cmd/compile/internal/reflectdata/reflect.go stuffs in these.
// tflag is documented in reflect/type.go.
//
// tflag values must be kept in sync with copies in:
// cmd/compile/internal/gc/reflect.go
// cmd/compile/internal/reflectdata/reflect.go
// cmd/link/internal/ld/decodesym.go
// reflect/type.go
// runtime/type.go

View file

@ -68,7 +68,7 @@ type Type interface {
}
/*
* These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
* These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
* A few are known to ../runtime/type.go to convey to debuggers.
* They are also known to ../runtime/type.go.
*/
@ -111,7 +111,7 @@ const (
// available in the memory directly following the rtype value.
//
// tflag values must be kept in sync with copies in:
// cmd/compile/internal/gc/reflect.go
// cmd/compile/internal/reflectdata/reflect.go
// cmd/link/internal/ld/decodesym.go
// runtime/type.go
type tflag uint8

View file

@ -1846,6 +1846,17 @@ func TestCVE202133195(t *testing.T) {
Target: dnsmessage.MustNewName("<html>.golang.org."),
},
},
dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: n,
Type: dnsmessage.TypeSRV,
Class: dnsmessage.ClassINET,
Length: 4,
},
Body: &dnsmessage.SRVResource{
Target: dnsmessage.MustNewName("good.golang.org."),
},
},
)
case dnsmessage.TypeMX:
r.Answers = append(r.Answers,
@ -1860,6 +1871,17 @@ func TestCVE202133195(t *testing.T) {
MX: dnsmessage.MustNewName("<html>.golang.org."),
},
},
dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: dnsmessage.MustNewName("good.golang.org."),
Type: dnsmessage.TypeMX,
Class: dnsmessage.ClassINET,
Length: 4,
},
Body: &dnsmessage.MXResource{
MX: dnsmessage.MustNewName("good.golang.org."),
},
},
)
case dnsmessage.TypeNS:
r.Answers = append(r.Answers,
@ -1874,6 +1896,17 @@ func TestCVE202133195(t *testing.T) {
NS: dnsmessage.MustNewName("<html>.golang.org."),
},
},
dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: dnsmessage.MustNewName("good.golang.org."),
Type: dnsmessage.TypeNS,
Class: dnsmessage.ClassINET,
Length: 4,
},
Body: &dnsmessage.NSResource{
NS: dnsmessage.MustNewName("good.golang.org."),
},
},
)
case dnsmessage.TypePTR:
r.Answers = append(r.Answers,
@ -1888,6 +1921,17 @@ func TestCVE202133195(t *testing.T) {
PTR: dnsmessage.MustNewName("<html>.golang.org."),
},
},
dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: dnsmessage.MustNewName("good.golang.org."),
Type: dnsmessage.TypePTR,
Class: dnsmessage.ClassINET,
Length: 4,
},
Body: &dnsmessage.PTRResource{
PTR: dnsmessage.MustNewName("good.golang.org."),
},
},
)
}
return r, nil
@ -1903,59 +1947,139 @@ func TestCVE202133195(t *testing.T) {
defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
testHookHostsPath = "testdata/hosts"
_, err := r.LookupCNAME(context.Background(), "golang.org")
if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err, expected)
}
_, err = LookupCNAME("golang.org")
if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err, expected)
tests := []struct {
name string
f func(*testing.T)
}{
{
name: "CNAME",
f: func(t *testing.T) {
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
_, err := r.LookupCNAME(context.Background(), "golang.org")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
_, err = LookupCNAME("golang.org")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
},
},
{
name: "SRV (bad record)",
f: func(t *testing.T) {
expected := []*SRV{
{
Target: "good.golang.org.",
},
}
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
_, records, err := r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
_, records, err = LookupSRV("target", "tcp", "golang.org")
if err.Error() != expectedErr.Error() {
t.Errorf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
},
},
{
name: "SRV (bad header)",
f: func(t *testing.T) {
_, _, err := r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.")
if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
}
_, _, err = LookupSRV("hdr", "tcp", "golang.org.")
if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
}
},
},
{
name: "MX",
f: func(t *testing.T) {
expected := []*MX{
{
Host: "good.golang.org.",
},
}
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
records, err := r.LookupMX(context.Background(), "golang.org")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
records, err = LookupMX("golang.org")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
},
},
{
name: "NS",
f: func(t *testing.T) {
expected := []*NS{
{
Host: "good.golang.org.",
},
}
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
records, err := r.LookupNS(context.Background(), "golang.org")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
records, err = LookupNS("golang.org")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
},
},
{
name: "Addr",
f: func(t *testing.T) {
expected := []string{"good.golang.org."}
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "192.0.2.42"}
records, err := r.LookupAddr(context.Background(), "192.0.2.42")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
records, err = LookupAddr("192.0.2.42")
if err.Error() != expectedErr.Error() {
t.Fatalf("unexpected error: %s", err)
}
if !reflect.DeepEqual(records, expected) {
t.Error("Unexpected record set")
}
},
},
}
_, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
}
_, _, err = LookupSRV("target", "tcp", "golang.org")
if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
for _, tc := range tests {
t.Run(tc.name, tc.f)
}
_, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.")
if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
}
_, _, err = LookupSRV("hdr", "tcp", "golang.org.")
if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
}
_, err = r.LookupMX(context.Background(), "golang.org")
if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err, expected)
}
_, err = LookupMX("golang.org")
if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
t.Errorf("LookupMX returned unexpected error, got %q, want %q", err, expected)
}
_, err = r.LookupNS(context.Background(), "golang.org")
if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err, expected)
}
_, err = LookupNS("golang.org")
if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
t.Errorf("LookupNS returned unexpected error, got %q, want %q", err, expected)
}
_, err = r.LookupAddr(context.Background(), "192.0.2.42")
if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err, expected)
}
_, err = LookupAddr("192.0.2.42")
if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected)
}
}
func TestNullMX(t *testing.T) {

View file

@ -424,7 +424,7 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error)
return "", err
}
if !isDomainName(cname) {
return "", &DNSError{Err: "CNAME target is invalid", Name: host}
return "", &DNSError{Err: errMalformedDNSRecordsDetail, Name: host}
}
return cname, nil
}
@ -440,7 +440,9 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error)
// and proto are empty strings, LookupSRV looks up name directly.
//
// The returned service names are validated to be properly
// formatted presentation-format domain names.
// formatted presentation-format domain names. If the response contains
// invalid names, those records are filtered out and an error
// will be returned alongside the the remaining results, if any.
func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
}
@ -456,7 +458,9 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err err
// and proto are empty strings, LookupSRV looks up name directly.
//
// The returned service names are validated to be properly
// formatted presentation-format domain names.
// formatted presentation-format domain names. If the response contains
// invalid names, those records are filtered out and an error
// will be returned alongside the the remaining results, if any.
func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
if err != nil {
@ -465,21 +469,28 @@ func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (
if cname != "" && !isDomainName(cname) {
return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
}
filteredAddrs := make([]*SRV, 0, len(addrs))
for _, addr := range addrs {
if addr == nil {
continue
}
if !isDomainName(addr.Target) {
return "", nil, &DNSError{Err: "SRV target is invalid", Name: name}
continue
}
filteredAddrs = append(filteredAddrs, addr)
}
return cname, addrs, nil
if len(addrs) != len(filteredAddrs) {
return cname, filteredAddrs, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
}
return cname, filteredAddrs, nil
}
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
//
// The returned mail server names are validated to be properly
// formatted presentation-format domain names.
// formatted presentation-format domain names. If the response contains
// invalid names, those records are filtered out and an error
// will be returned alongside the the remaining results, if any.
//
// LookupMX uses context.Background internally; to specify the context, use
// Resolver.LookupMX.
@ -490,12 +501,15 @@ func LookupMX(name string) ([]*MX, error) {
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
//
// The returned mail server names are validated to be properly
// formatted presentation-format domain names.
// formatted presentation-format domain names. If the response contains
// invalid names, those records are filtered out and an error
// will be returned alongside the the remaining results, if any.
func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
records, err := r.lookupMX(ctx, name)
if err != nil {
return nil, err
}
filteredMX := make([]*MX, 0, len(records))
for _, mx := range records {
if mx == nil {
continue
@ -503,16 +517,22 @@ func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
// Bypass the hostname validity check for targets which contain only a dot,
// as this is used to represent a 'Null' MX record.
if mx.Host != "." && !isDomainName(mx.Host) {
return nil, &DNSError{Err: "MX target is invalid", Name: name}
continue
}
filteredMX = append(filteredMX, mx)
}
return records, nil
if len(records) != len(filteredMX) {
return filteredMX, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
}
return filteredMX, nil
}
// LookupNS returns the DNS NS records for the given domain name.
//
// The returned name server names are validated to be properly
// formatted presentation-format domain names.
// formatted presentation-format domain names. If the response contains
// invalid names, those records are filtered out and an error
// will be returned alongside the the remaining results, if any.
//
// LookupNS uses context.Background internally; to specify the context, use
// Resolver.LookupNS.
@ -523,21 +543,28 @@ func LookupNS(name string) ([]*NS, error) {
// LookupNS returns the DNS NS records for the given domain name.
//
// The returned name server names are validated to be properly
// formatted presentation-format domain names.
// formatted presentation-format domain names. If the response contains
// invalid names, those records are filtered out and an error
// will be returned alongside the the remaining results, if any.
func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
records, err := r.lookupNS(ctx, name)
if err != nil {
return nil, err
}
filteredNS := make([]*NS, 0, len(records))
for _, ns := range records {
if ns == nil {
continue
}
if !isDomainName(ns.Host) {
return nil, &DNSError{Err: "NS target is invalid", Name: name}
continue
}
filteredNS = append(filteredNS, ns)
}
return records, nil
if len(records) != len(filteredNS) {
return filteredNS, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
}
return filteredNS, nil
}
// LookupTXT returns the DNS TXT records for the given domain name.
@ -557,7 +584,8 @@ func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error)
// of names mapping to that address.
//
// The returned names are validated to be properly formatted presentation-format
// domain names.
// domain names. If the response contains invalid names, those records are filtered
// out and an error will be returned alongside the the remaining results, if any.
//
// When using the host C library resolver, at most one result will be
// returned. To bypass the host resolver, use a custom Resolver.
@ -572,16 +600,26 @@ func LookupAddr(addr string) (names []string, err error) {
// of names mapping to that address.
//
// The returned names are validated to be properly formatted presentation-format
// domain names.
// domain names. If the response contains invalid names, those records are filtered
// out and an error will be returned alongside the the remaining results, if any.
func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
names, err := r.lookupAddr(ctx, addr)
if err != nil {
return nil, err
}
filteredNames := make([]string, 0, len(names))
for _, name := range names {
if !isDomainName(name) {
return nil, &DNSError{Err: "PTR target is invalid", Name: addr}
if isDomainName(name) {
filteredNames = append(filteredNames, name)
}
}
return names, nil
if len(names) != len(filteredNames) {
return filteredNames, &DNSError{Err: errMalformedDNSRecordsDetail, Name: addr}
}
return filteredNames, nil
}
// errMalformedDNSRecordsDetail is the DNSError detail which is returned when a Resolver.Lookup...
// method recieves DNS records which contain invalid DNS names. This may be returned alongside
// results which have had the malformed records filtered out.
var errMalformedDNSRecordsDetail = "DNS response contained records which contain invalid names"

View file

@ -229,7 +229,7 @@ type Type interface {
// See https://golang.org/issue/4876 for more details.
/*
* These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
* These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
* A few are known to ../runtime/type.go to convey to debuggers.
* They are also known to ../runtime/type.go.
*/
@ -272,7 +272,7 @@ const (
// available in the memory directly following the rtype value.
//
// tflag values must be kept in sync with copies in:
// cmd/compile/internal/gc/reflect.go
// cmd/compile/internal/reflectdata/reflect.go
// cmd/link/internal/ld/decodesym.go
// runtime/type.go
type tflag uint8
@ -1911,7 +1911,7 @@ func MapOf(key, elem Type) Type {
// Make a map type.
// Note: flag values must match those used in the TMAP case
// in ../cmd/compile/internal/gc/reflect.go:writeType.
// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
mt := **(**mapType)(unsafe.Pointer(&imap))
mt.str = resolveReflectName(newName(s, "", false))
@ -2842,7 +2842,7 @@ func runtimeStructField(field StructField) (structField, string) {
// typeptrdata returns the length in bytes of the prefix of t
// containing pointer data. Anything after this offset is scalar data.
// keep in sync with ../cmd/compile/internal/gc/reflect.go
// keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
func typeptrdata(t *rtype) uintptr {
switch t.Kind() {
case Struct:
@ -2866,7 +2866,7 @@ func typeptrdata(t *rtype) uintptr {
}
}
// See cmd/compile/internal/gc/reflect.go for derivation of constant.
// See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
const maxPtrmaskBytes = 2048
// ArrayOf returns the array type with the given length and element type.

View file

@ -895,7 +895,7 @@ type funcinl struct {
// layout of Itab known to compilers
// allocated in non-garbage-collected memory
// Needs to be in sync with
// ../cmd/compile/internal/gc/reflect.go:/^func.WriteTabs.
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
type itab struct {
inter *interfacetype
_type *_type

View file

@ -16,7 +16,7 @@ const debugSelect = false
// Select case descriptor.
// Known to compiler.
// Changes here must also be made in src/cmd/internal/gc/select.go's scasetype.
// Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype.
type scase struct {
c *hchan // chan
elem unsafe.Pointer // data element

View file

@ -14,7 +14,7 @@ import (
// tflag is documented in reflect/type.go.
//
// tflag values must be kept in sync with copies in:
// cmd/compile/internal/gc/reflect.go
// cmd/compile/internal/reflectdata/reflect.go
// cmd/link/internal/ld/decodesym.go
// reflect/type.go
// internal/reflectlite/type.go
@ -28,7 +28,7 @@ const (
)
// Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
// ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
// ../reflect/type.go:/^type.rtype.
// ../internal/reflectlite/type.go:/^type.rtype.
type _type struct {
@ -386,7 +386,7 @@ type maptype struct {
}
// Note: flag values must match those used in the TMAP case
// in ../cmd/compile/internal/gc/reflect.go:writeType.
// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
func (mt *maptype) indirectkey() bool { // store ptr to key instead of key itself
return mt.flags&1 != 0
}

View file

@ -0,0 +1,9 @@
// Copyright 2021 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.
package a
func F() interface{} { return struct{ _ []int }{} }
var X = F()

View file

@ -0,0 +1,9 @@
// Copyright 2021 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.
package b
func F() interface{} { return struct{ _ []int }{} }
var X = F()

View file

@ -0,0 +1,19 @@
// Copyright 2021 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.
package main
import (
"a"
"b"
)
func main() {
if a.F() == b.F() {
panic("FAIL")
}
if a.X == b.X {
panic("FAIL")
}
}

View file

@ -0,0 +1,7 @@
// rundir
// Copyright 2021 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.
package ignored