Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge upstream release-branch.go1.16 into microsoft/release-branch.go1.16 #183

Merged
merged 14 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
go1.16.6
go1.16.7
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func dumpdata() {
if zerosize > 0 {
zero := mappkg.Lookup("zero")
ggloblsym(zero.Linksym(), int32(zerosize), obj.DUPOK|obj.RODATA)
zero.Linksym().Set(obj.AttrContentAddressable, true)
zero.Linksym().Set(obj.AttrStatic, true)
}

addGCLocals()
Expand Down
9 changes: 6 additions & 3 deletions src/cmd/compile/internal/ssa/gen/ARM64Ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,13 +502,14 @@ func init() {
// auxint = offset into duffzero code to start executing
// returns mem
// R20 changed as side effect
// R16 and R17 may be clobbered by linker trampoline.
{
name: "DUFFZERO",
aux: "Int64",
argLength: 2,
reg: regInfo{
inputs: []regMask{buildReg("R20")},
clobbers: buildReg("R20 R30"),
clobbers: buildReg("R16 R17 R20 R30"),
},
faultOnNilArg0: true,
unsafePoint: true, // FP maintenance around DUFFZERO can be clobbered by interrupts
Expand Down Expand Up @@ -542,13 +543,14 @@ func init() {
// auxint = offset into duffcopy code to start executing
// returns mem
// R20, R21 changed as side effect
// R16 and R17 may be clobbered by linker trampoline.
{
name: "DUFFCOPY",
aux: "Int64",
argLength: 3,
reg: regInfo{
inputs: []regMask{buildReg("R21"), buildReg("R20")},
clobbers: buildReg("R20 R21 R26 R30"),
clobbers: buildReg("R16 R17 R20 R21 R26 R30"),
},
faultOnNilArg0: true,
faultOnNilArg1: true,
Expand Down Expand Up @@ -707,7 +709,8 @@ func init() {
// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
// It saves all GP registers if necessary,
// but clobbers R30 (LR) because it's a call.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// R16 and R17 may be clobbered by linker trampoline.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R16 R17 R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},

// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/compile/internal/ssa/opGen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/cmd/go/internal/load/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,11 @@ func reusePackage(p *Package, stk *ImportStack) *Package {
Err: errors.New("import cycle not allowed"),
IsImportCycle: true,
}
} else if !p.Error.IsImportCycle {
// If the error is already set, but it does not indicate that
// we are in an import cycle, set IsImportCycle so that we don't
// end up stuck in a loop down the road.
p.Error.IsImportCycle = true
}
p.Incomplete = true
}
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/go/internal/modcmd/vendor.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"io"
"io/fs"
"os"
"path"
"path/filepath"
"sort"
"strings"
Expand Down Expand Up @@ -281,7 +282,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)
}
Expand Down
10 changes: 6 additions & 4 deletions src/cmd/go/internal/modload/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,13 @@ func (e *ImportMissingSumError) Error() string {
// Importing package is unknown, or the missing package was named on the
// command line. Recommend 'go mod download' for the modules that could
// provide the package, since that shouldn't change go.mod.
args := make([]string, len(e.mods))
for i, mod := range e.mods {
args[i] = mod.Path
if len(e.mods) > 0 {
args := make([]string, len(e.mods))
for i, mod := range e.mods {
args[i] = mod.Path
}
hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
}
hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
} else {
// Importing package is known (common case). Recommend 'go get' on the
// current version of the importing package.
Expand Down
15 changes: 15 additions & 0 deletions src/cmd/go/testdata/script/list_err_cycle.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Check that we don't get infinite recursion when loading a package with
# an import cycle and another error. Verifies #25830.
! go list
stderr 'found packages a \(a.go\) and b \(b.go\)'

-- go.mod --
module errcycle

go 1.16
-- a.go --
package a

import _ "errcycle"
-- b.go --
package b
5 changes: 5 additions & 0 deletions src/cmd/go/testdata/script/mod_install_hint.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Module is replaced but not required. No hint appears as no module is suggested.
go mod init m
go mod edit -replace=github.com/notrequired@v0.5.0=github.com/doesnotexist@v0.5.0
! go install github.com/notrequired
! stderr 'to add it:'
9 changes: 9 additions & 0 deletions src/cmd/link/internal/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,15 @@ func (st *loadState) addSym(name string, ver int, r *oReader, li uint32, kind in
if l.flags&FlagStrictDups != 0 {
l.checkdup(name, r, li, oldi)
}
// Fix for issue #47185 -- given two dupok symbols with
// different sizes, favor symbol with larger size. See
// also issue #46653.
szdup := l.SymSize(oldi)
sz := int64(r.Sym(li).Siz())
if szdup < sz {
// new symbol overwrites old symbol.
l.objSyms[oldi] = objSym{r.objidx, li}
}
return oldi
}
oldr, oldli := l.toLocal(oldi)
Expand Down
2 changes: 1 addition & 1 deletion src/go/internal/gccgoimporter/gccgoinstallation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func TestInstallationImporter(t *testing.T) {
{pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"},
{pkgpath: "math", name: "Pi", want: "const Pi untyped float"},
{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
{pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"},
{pkgpath: "sort", name: "Search", want: "func Search(n int, f func(int) bool) int"},
{pkgpath: "unsafe", name: "Pointer", want: "type Pointer"},
} {
runImporterTest(t, imp, nil, &test)
Expand Down
9 changes: 9 additions & 0 deletions src/net/http/httputil/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,15 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if req.ContentLength == 0 {
outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
}
if outreq.Body != nil {
// Reading from the request body after returning from a handler is not
// allowed, and the RoundTrip goroutine that reads the Body can outlive
// this handler. This can lead to a crash if the handler panics (see
// Issue 46866). Although calling Close doesn't guarantee there isn't
// any Read in flight after the handle returns, in practice it's safe to
// read after closing it.
defer outreq.Body.Close()
}
if outreq.Header == nil {
outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
}
Expand Down
39 changes: 39 additions & 0 deletions src/net/http/httputil/reverseproxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,45 @@ func TestReverseProxy_PanicBodyError(t *testing.T) {
rproxy.ServeHTTP(httptest.NewRecorder(), req)
}

// Issue #46866: panic without closing incoming request body causes a panic
func TestReverseProxy_PanicClosesIncomingBody(t *testing.T) {
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
out := "this call was relayed by the reverse proxy"
// Coerce a wrong content length to induce io.ErrUnexpectedEOF
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out)*2))
fmt.Fprintln(w, out)
}))
defer backend.Close()
backendURL, err := url.Parse(backend.URL)
if err != nil {
t.Fatal(err)
}
proxyHandler := NewSingleHostReverseProxy(backendURL)
proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
frontend := httptest.NewServer(proxyHandler)
defer frontend.Close()
frontendClient := frontend.Client()

var wg sync.WaitGroup
for i := 0; i < 2; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 10; j++ {
const reqLen = 6 * 1024 * 1024
req, _ := http.NewRequest("POST", frontend.URL, &io.LimitedReader{R: neverEnding('x'), N: reqLen})
req.ContentLength = reqLen
resp, _ := frontendClient.Transport.RoundTrip(req)
if resp != nil {
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
}
}
}()
}
wg.Wait()
}

func TestSelectFlushInterval(t *testing.T) {
tests := []struct {
name string
Expand Down
77 changes: 51 additions & 26 deletions src/net/http/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6433,10 +6433,11 @@ func TestErrorWriteLoopRace(t *testing.T) {
// Test that a new request which uses the connection of an active request
// cannot cause it to be canceled as well.
func TestCancelRequestWhenSharingConnection(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
reqc := make(chan chan struct{}, 2)
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
ch := make(chan struct{}, 1)
reqc <- ch
<-ch
w.Header().Add("Content-Length", "0")
}))
defer ts.Close()
Expand All @@ -6448,34 +6449,58 @@ func TestCancelRequestWhenSharingConnection(t *testing.T) {

var wg sync.WaitGroup

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
wg.Add(1)
putidlec := make(chan chan struct{})
go func() {
defer wg.Done()
ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
PutIdleConn: func(error) {
// Signal that the idle conn has been returned to the pool,
// and wait for the order to proceed.
ch := make(chan struct{})
putidlec <- ch
<-ch
},
})
req, _ := NewRequestWithContext(ctx, "GET", ts.URL, nil)
res, err := client.Do(req)
if err == nil {
res.Body.Close()
}
if err != nil {
t.Errorf("request 1: got err %v, want nil", err)
}
}()

for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for ctx.Err() == nil {
reqctx, reqcancel := context.WithCancel(ctx)
go reqcancel()
req, _ := NewRequestWithContext(reqctx, "GET", ts.URL, nil)
res, err := client.Do(req)
if err == nil {
res.Body.Close()
}
}
}()
}
// Wait for the first request to receive a response and return the
// connection to the idle pool.
r1c := <-reqc
close(r1c)
idlec := <-putidlec

for ctx.Err() == nil {
req, _ := NewRequest("GET", ts.URL, nil)
if res, err := client.Do(req); err != nil {
t.Errorf("unexpected: %p %v", req, err)
break
} else {
wg.Add(1)
cancelctx, cancel := context.WithCancel(context.Background())
go func() {
defer wg.Done()
req, _ := NewRequestWithContext(cancelctx, "GET", ts.URL, nil)
res, err := client.Do(req)
if err == nil {
res.Body.Close()
}
}
if !errors.Is(err, context.Canceled) {
t.Errorf("request 2: got err %v, want Canceled", err)
}
}()

// Wait for the second request to arrive at the server, and then cancel
// the request context.
r2c := <-reqc
cancel()

// Give the cancelation a moment to take effect, and then unblock the first request.
time.Sleep(1 * time.Millisecond)
close(idlec)

close(r2c)
wg.Wait()
}
Loading