Skip to content

Commit

Permalink
Merge pull request #183 from microsoft-golang-bot/auto-merge/microsof…
Browse files Browse the repository at this point in the history
…t/release-branch.go1.16

Merge upstream `release-branch.go1.16` into `microsoft/release-branch.go1.16`
  • Loading branch information
microsoft-golang-review-bot authored Aug 19, 2021
2 parents 82db1ae + 8a870f5 commit 46aa5b6
Show file tree
Hide file tree
Showing 24 changed files with 411 additions and 138 deletions.
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

0 comments on commit 46aa5b6

Please sign in to comment.