diff --git a/api/go1.17.txt b/api/go1.17.txt index 8e4c0f5624..3d0a464fec 100644 --- a/api/go1.17.txt +++ b/api/go1.17.txt @@ -181,6 +181,7 @@ pkg syscall (windows-amd64), type SysProcAttr struct, AdditionalInheritedHandles pkg syscall (windows-amd64), type SysProcAttr struct, ParentProcess Handle pkg testing, method (*B) Setenv(string, string) pkg testing, method (*T) Setenv(string, string) +pkg testing, type TB interface, Setenv(string, string) pkg text/template/parse, const SkipFuncCheck = 2 pkg text/template/parse, const SkipFuncCheck Mode pkg time, const Layout = "01/02 03:04:05PM '06 -0700" diff --git a/doc/go_spec.html b/doc/go_spec.html index e0602418e8..ad21ffb1b8 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -6782,7 +6782,8 @@ The rules for valid uses of Pointer The function Slice returns a slice whose underlying array starts at ptr -and whose length and capacity are len: +and whose length and capacity are len. +Slice(ptr, len) is equivalent to

@@ -6790,7 +6791,8 @@ and whose length and capacity are len:
 

-As a special case, if ptr is nil and len is zero, +except that, as a special case, if ptr +is nil and len is zero, Slice returns nil.

diff --git a/src/cmd/compile/abi-internal.md b/src/cmd/compile/abi-internal.md index 7aed7efe97..3619aea4aa 100644 --- a/src/cmd/compile/abi-internal.md +++ b/src/cmd/compile/abi-internal.md @@ -233,7 +233,7 @@ stack frame is laid out in the following sequence: r1.x uintptr r1.y [2]uintptr a1Spill uint8 - a2Spill uint8 + a3Spill uint8 _ [6]uint8 // alignment padding In the stack frame, only the `a2` field is initialized on entry; the diff --git a/src/cmd/compile/internal/escape/utils.go b/src/cmd/compile/internal/escape/utils.go index 1ac4cc6029..6e2f9c424a 100644 --- a/src/cmd/compile/internal/escape/utils.go +++ b/src/cmd/compile/internal/escape/utils.go @@ -186,14 +186,14 @@ func HeapAllocReason(n ir.Node) string { return "too large for stack" } - if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= ir.MaxImplicitStackVarSize { + if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width > ir.MaxImplicitStackVarSize { return "too large for stack" } - if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() >= ir.MaxImplicitStackVarSize { + if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() > ir.MaxImplicitStackVarSize { return "too large for stack" } - if n.Op() == ir.OMETHVALUE && typecheck.PartialCallType(n.(*ir.SelectorExpr)).Size() >= ir.MaxImplicitStackVarSize { + if n.Op() == ir.OMETHVALUE && typecheck.PartialCallType(n.(*ir.SelectorExpr)).Size() > ir.MaxImplicitStackVarSize { return "too large for stack" } @@ -206,7 +206,7 @@ func HeapAllocReason(n ir.Node) string { if !ir.IsSmallIntConst(r) { return "non-constant size" } - if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) >= ir.MaxImplicitStackVarSize/t.Elem().Width { + if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) > ir.MaxImplicitStackVarSize/t.Elem().Width { return "too large for stack" } } diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go index eaa94975ec..8e2872363b 100644 --- a/src/cmd/compile/internal/ssa/debug.go +++ b/src/cmd/compile/internal/ssa/debug.go @@ -1115,8 +1115,14 @@ func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) { continue } + mustBeFirst := func(v *Value) bool { + return v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() || + v.Op == OpArgIntReg || v.Op == OpArgFloatReg + } + zeroWidthPending := false - apcChangedSize := 0 // size of changedVars for leading Args, Phi, ClosurePtr + blockPrologComplete := false // set to true at first non-zero-width op + apcChangedSize := 0 // size of changedVars for leading Args, Phi, ClosurePtr // expect to see values in pattern (apc)* (zerowidth|real)* for _, v := range b.Values { slots := state.valueNames[v.ID] @@ -1125,16 +1131,16 @@ func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) { if opcodeTable[v.Op].zeroWidth { if changed { - if hasAnyArgOp(v) || v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() { + if mustBeFirst(v) || v.Op == OpArg { // These ranges begin at true beginning of block, not after first instruction - if zeroWidthPending { - panic(fmt.Errorf("Unexpected op '%s' mixed with OpArg/OpPhi/OpLoweredGetClosurePtr at beginning of block %s in %s\n%s", v.LongString(), b, b.Func.Name, b.Func)) + if blockPrologComplete && mustBeFirst(v) { + panic(fmt.Errorf("Unexpected placement of op '%s' appearing after non-pseudo-op at beginning of block %s in %s\n%s", v.LongString(), b, b.Func.Name, b.Func)) } apcChangedSize = len(state.changedVars.contents()) + // Other zero-width ops must wait on a "real" op. + zeroWidthPending = true continue } - // Other zero-width ops must wait on a "real" op. - zeroWidthPending = true } continue } @@ -1145,6 +1151,7 @@ func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) { // Not zero-width; i.e., a "real" instruction. zeroWidthPending = false + blockPrologComplete = true for i, varID := range state.changedVars.contents() { if i < apcChangedSize { // buffered true start-of-block changes state.updateVar(VarID(varID), v.Block, BlockStart) diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go index e1a2319e14..af4f8f4822 100644 --- a/src/cmd/compile/internal/walk/builtin.go +++ b/src/cmd/compile/internal/walk/builtin.go @@ -489,7 +489,7 @@ func walkNew(n *ir.UnaryExpr, init *ir.Nodes) ir.Node { base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type().Elem()) } if n.Esc() == ir.EscNone { - if t.Size() >= ir.MaxImplicitStackVarSize { + if t.Size() > ir.MaxImplicitStackVarSize { base.Fatalf("large ONEW with EscNone: %v", n) } return stackTempAddr(init, t) diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 4acd357974..f40fa926df 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -781,7 +781,7 @@ func (t *tester) registerTests() { t.registerTest("testasan", "../misc/cgo/testasan", "go", "run", ".") } if goos == "linux" && goarch != "ppc64le" { - // because syscall.SysProcAttri struct used in misc/cgo/testsanitizers is only built on linux. + // because syscall.SysProcAttr struct used in misc/cgo/testsanitizers is only built on linux. // Some inconsistent failures happen on ppc64le so disable for now. t.registerHostTest("testsanitizers", "../misc/cgo/testsanitizers", "misc/cgo/testsanitizers", ".") } diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go index 8e1c0432f7..713d5f9f3f 100644 --- a/src/cmd/go/internal/modcmd/vendor.go +++ b/src/cmd/go/internal/modcmd/vendor.go @@ -13,6 +13,7 @@ import ( "io" "io/fs" "os" + "path" "path/filepath" "sort" "strings" @@ -299,7 +300,7 @@ func copyMetadata(modPath, pkg, dst, src string, copiedFiles map[string]bool) { if modPath == pkg { break } - pkg = filepath.Dir(pkg) + pkg = path.Dir(pkg) dst = filepath.Dir(dst) src = filepath.Dir(src) } diff --git a/src/cmd/go/testdata/script/mod_vendor_issue46867.txt b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt new file mode 100644 index 0000000000..38ae87b44a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt @@ -0,0 +1,31 @@ +# Regression test for golang.org/issue/46867: +# 'go mod vendor' on Windows attempted to open and copy +# files from directories outside of the module. + +cd subdir +go mod vendor +! exists vendor/example.net/NOTICE +exists vendor/example.net/m/NOTICE + +-- subdir/go.mod -- +module golang.org/issue46867 + +go 1.17 + +replace example.net/m v0.1.0 => ./m + +require example.net/m v0.1.0 +-- subdir/issue.go -- +package issue + +import _ "example.net/m/n" +-- subdir/m/go.mod -- +module example.net/m + +go 1.17 +-- subdir/m/n/n.go -- +package n +-- subdir/m/NOTICE -- +This notice is in module m and SHOULD be vendored. +-- subdir/NOTICE -- +This notice is outside of module m and SHOULD NOT be vendored. diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index d69107a2f2..59cdd2bf3e 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -1957,3 +1957,43 @@ func TestCVE202133195(t *testing.T) { t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected) } } + +func TestNullMX(t *testing.T) { + fake := fakeDNSServer{ + rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + r := dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.Header.ID, + Response: true, + RCode: dnsmessage.RCodeSuccess, + }, + Questions: q.Questions, + Answers: []dnsmessage.Resource{ + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: dnsmessage.TypeMX, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.MXResource{ + MX: dnsmessage.MustNewName("."), + }, + }, + }, + } + return r, nil + }, + } + r := Resolver{PreferGo: true, Dial: fake.DialContext} + rrset, err := r.LookupMX(context.Background(), "golang.org") + if err != nil { + t.Fatalf("LookupMX: %v", err) + } + if want := []*MX{&MX{Host: "."}}; !reflect.DeepEqual(rrset, want) { + records := []string{} + for _, rr := range rrset { + records = append(records, fmt.Sprintf("%v", rr)) + } + t.Errorf("records = [%v]; want [%v]", strings.Join(records, " "), want[0]) + } +} diff --git a/src/net/http/transport.go b/src/net/http/transport.go index 47cb992a50..309194e8e5 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -427,6 +427,7 @@ func (t *Transport) onceSetNextProtoDefaults() { // // The environment values may be either a complete URL or a // "host[:port]", in which case the "http" scheme is assumed. +// The schemes "http", "https", and "socks5" are supported. // An error is returned if the value is a different form. // // A nil URL and nil error are returned if no proxy is defined in the diff --git a/src/net/lookup.go b/src/net/lookup.go index 02a4cdcd1e..b5af3a0f86 100644 --- a/src/net/lookup.go +++ b/src/net/lookup.go @@ -500,7 +500,9 @@ func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) { if mx == nil { continue } - if !isDomainName(mx.Host) { + // 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} } } diff --git a/src/runtime/stack.go b/src/runtime/stack.go index 1fa235bf86..54ad66dca2 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -1061,7 +1061,9 @@ func newstack() { // recheck the bounds on return.) if f := findfunc(gp.sched.pc); f.valid() { max := uintptr(funcMaxSPDelta(f)) - for newsize-gp.sched.sp < max+_StackGuard { + needed := max + _StackGuard + used := gp.stack.hi - gp.sched.sp + for newsize-used < needed { newsize *= 2 } } diff --git a/src/testing/testing.go b/src/testing/testing.go index fdf57a3953..eeee0aac17 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -644,6 +644,7 @@ type TB interface { Log(args ...interface{}) Logf(format string, args ...interface{}) Name() string + Setenv(key, value string) Skip(args ...interface{}) SkipNow() Skipf(format string, args ...interface{}) diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go index eaf72c9618..16e3890d0b 100644 --- a/src/unsafe/unsafe.go +++ b/src/unsafe/unsafe.go @@ -217,11 +217,13 @@ func Alignof(x ArbitraryType) uintptr func Add(ptr Pointer, len IntegerType) Pointer // The function Slice returns a slice whose underlying array starts at ptr -// and whose length and capacity are len: +// and whose length and capacity are len. +// Slice(ptr, len) is equivalent to // // (*[len]ArbitraryType)(unsafe.Pointer(ptr))[:] // -// As a special case, if ptr is nil and len is zero, Slice returns nil. +// except that, as a special case, if ptr is nil and len is zero, +// Slice returns nil. // // The len argument must be of integer type or an untyped constant. // A constant len argument must be non-negative and representable by a value of type int;