[dev.boringcrypto.go1.15] all: merge go1.15.13 into dev.boringcrypto.go1.15

Change-Id: I90b28aa5938fe0bddf11201c6bdb851de5c654c3
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index 13ff9dd..2d5151a 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -84,7 +84,15 @@
 		return err
 	}
 	z.r = r
-	z.File = make([]*File, 0, end.directoryRecords)
+	// Since the number of directory records is not validated, it is not
+	// safe to preallocate z.File without first checking that the specified
+	// number of files is reasonable, since a malformed archive may
+	// indicate it contains up to 1 << 128 - 1 files. Since each file has a
+	// header which will be _at least_ 30 bytes we can safely preallocate
+	// if (data size / 30) >= end.directoryRecords.
+	if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
+		z.File = make([]*File, 0, end.directoryRecords)
+	}
 	z.Comment = end.comment
 	rs := io.NewSectionReader(r, 0, size)
 	if _, err = rs.Seek(int64(end.directoryOffset), io.SeekStart); err != nil {
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
index adca87a..6f67d2e 100644
--- a/src/archive/zip/reader_test.go
+++ b/src/archive/zip/reader_test.go
@@ -1070,3 +1070,62 @@
 		t.Errorf("Error reading the archive: %v", err)
 	}
 }
+
+func TestCVE202133196(t *testing.T) {
+	// Archive that indicates it has 1 << 128 -1 files,
+	// this would previously cause a panic due to attempting
+	// to allocate a slice with 1 << 128 -1 elements.
+	data := []byte{
+		0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08,
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
+		0x03, 0x62, 0x61, 0x65, 0x03, 0x04, 0x00, 0x00,
+		0xff, 0xff, 0x50, 0x4b, 0x07, 0x08, 0xbe, 0x20,
+		0x5c, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00,
+		0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00,
+		0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0xbe, 0x20, 0x5c, 0x6c, 0x09, 0x00,
+		0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x02, 0x03, 0x50, 0x4b, 0x06, 0x06, 0x2c,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+		0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00,
+		0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50,
+		0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0x00, 0x00,
+	}
+	_, err := NewReader(bytes.NewReader(data), int64(len(data)))
+	if err != ErrFormat {
+		t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
+	}
+
+	// Also check that an archive containing a handful of empty
+	// files doesn't cause an issue
+	b := bytes.NewBuffer(nil)
+	w := NewWriter(b)
+	for i := 0; i < 5; i++ {
+		_, err := w.Create("")
+		if err != nil {
+			t.Fatalf("Writer.Create failed: %s", err)
+		}
+	}
+	if err := w.Close(); err != nil {
+		t.Fatalf("Writer.Close failed: %s", err)
+	}
+	r, err := NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
+	if err != nil {
+		t.Fatalf("NewReader failed: %s", err)
+	}
+	if len(r.File) != 5 {
+		t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
+	}
+}
diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go
index 5ff8474..71e1eda 100644
--- a/src/cmd/go/internal/modcmd/tidy.go
+++ b/src/cmd/go/internal/modcmd/tidy.go
@@ -43,6 +43,7 @@
 	}
 
 	modload.SilenceMissingStdImports = true
+	modload.CheckTidyVersion()
 	modload.LoadALL()
 	modload.TidyBuildList()
 	modTidyGoSum() // updates memory copy; WriteGoMod on next line flushes it out
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index e5ea1a6..0dea6ee 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -24,7 +24,9 @@
 	"sort"
 	"strings"
 
+	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/module"
+	"golang.org/x/mod/semver"
 )
 
 // buildList is the list of modules to use for building packages.
@@ -478,6 +480,31 @@
 	buildList = append([]module.Version{}, list...)
 }
 
+// CheckTidyVersion reports an error to stderr if the Go version indicated by
+// the go.mod file is not supported by this version of the 'go' command.
+//
+// If allowError is false, such an error terminates the program.
+func CheckTidyVersion() {
+	InitMod()
+	mf := ModFile()
+	if mf.Go == nil || mf.Go.Version == "" {
+		return
+	}
+	goVersionV := "v" + mf.Go.Version
+
+	tags := build.Default.ReleaseTags
+	maxGo := tags[len(tags)-1]
+	if !strings.HasPrefix(maxGo, "go") || !modfile.GoVersionRE.MatchString(maxGo[2:]) {
+		base.Fatalf("go: unrecognized go version %q", maxGo)
+	}
+	max := maxGo[2:]
+
+	if semver.Compare(goVersionV, "v"+max) > 0 {
+		have := goVersionV[1:]
+		base.Fatalf("go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", have, max)
+	}
+}
+
 // TidyBuildList trims the build list to the minimal requirements needed to
 // retain the same versions of all packages from the preceding Load* or
 // ImportPaths* call.
diff --git a/src/cmd/go/testdata/script/mod_readonly.txt b/src/cmd/go/testdata/script/mod_readonly.txt
index ac58126..a5d49bc 100644
--- a/src/cmd/go/testdata/script/mod_readonly.txt
+++ b/src/cmd/go/testdata/script/mod_readonly.txt
@@ -64,7 +64,7 @@
 -- go.mod --
 module m
 
-go 1.20
+go 1.15
 
 -- x.go --
 package x
@@ -79,7 +79,7 @@
 -- go.mod.redundant --
 module m
 
-go 1.20
+go 1.15
 
 require (
 	rsc.io/quote v1.5.2
@@ -89,7 +89,7 @@
 -- go.mod.indirect --
 module m
 
-go 1.20
+go 1.15
 
 require (
 	rsc.io/quote v1.5.2 // indirect
diff --git a/src/cmd/go/testdata/script/mod_tidy_too_new.txt b/src/cmd/go/testdata/script/mod_tidy_too_new.txt
new file mode 100644
index 0000000..8a73c28
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_too_new.txt
@@ -0,0 +1,31 @@
+# https://golang.org/issue/46142: 'go mod tidy' should error out if the version
+# in the go.mod file is newer than the most recent supported version.
+
+cp go.mod go.mod.orig
+
+
+# If the go.mod file specifies an unsupported Go version, 'go mod tidy' should
+# refuse to edit it: we don't know what a tidy go.mod file for that version
+# would look like.
+
+! go mod tidy
+stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$'
+cmp go.mod go.mod.orig
+
+
+-- go.mod --
+module example.net/from/the/future
+
+go 2000.0
+
+replace example.net/m v0.0.0 => ./m
+-- x.go --
+package x
+
+import "example.net/m"
+-- m/go.mod --
+module example.net/m
+
+go 1.17
+-- m/m.go --
+package m
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 78298be..36ec403 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -1400,7 +1400,7 @@
 	}
 
 	ldr := ctxt.loader
-	eaddr := int32(sect.Vaddr + sect.Length)
+	eaddr := sect.Vaddr + sect.Length
 	for _, s := range syms {
 		if !s.Attr.Reachable() {
 			continue
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index 5548b8c..df016f3 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -1044,7 +1044,7 @@
 		}
 	}
 
-	eaddr := int32(sect.Vaddr + sect.Length)
+	eaddr := sect.Vaddr + sect.Length
 	for _, s := range syms {
 		if !s.Attr.Reachable() {
 			continue
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
index a3ecd43..8b0f151 100644
--- a/src/cmd/link/internal/ppc64/asm.go
+++ b/src/cmd/link/internal/ppc64/asm.go
@@ -658,6 +658,16 @@
 	return int64(o2)<<32 | int64(o1)
 }
 
+// Determine if the code was compiled so that the TOC register R2 is initialized and maintained
+func r2Valid(ctxt *ld.Link) bool {
+	switch ctxt.BuildMode {
+	case ld.BuildModeCArchive, ld.BuildModeCShared, ld.BuildModePIE, ld.BuildModeShared, ld.BuildModePlugin:
+		return true
+	}
+	// -linkshared option
+	return ctxt.IsSharedGoLink()
+}
+
 // resolve direct jump relocation r in s, and add trampoline if necessary
 func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
 
@@ -665,7 +675,7 @@
 	// For internal linking, trampolines are always created for long calls.
 	// For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in
 	// r2.  For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created.
-	if ctxt.IsExternal() && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) {
+	if ctxt.IsExternal() && r2Valid(ctxt) {
 		// No trampolines needed since r2 contains the TOC
 		return
 	}
@@ -719,7 +729,7 @@
 				}
 			}
 			if ldr.SymType(tramp) == 0 {
-				if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
+				if r2Valid(ctxt) {
 					// Should have returned for above cases
 					ctxt.Errorf(s, "unexpected trampoline for shared or dynamic linking")
 				} else {
diff --git a/src/math/big/arith_s390x.s b/src/math/big/arith_s390x.s
index 4891768..153c426 100644
--- a/src/math/big/arith_s390x.s
+++ b/src/math/big/arith_s390x.s
@@ -702,199 +702,11 @@
 
 // func shlVU(z, x []Word, s uint) (c Word)
 TEXT ·shlVU(SB), NOSPLIT, $0
-	MOVD z_len+8(FP), R5
-	MOVD $0, R0
-	SUB  $1, R5          // n--
-	BLT  X8b             // n < 0        (n <= 0)
+	BR ·shlVU_g(SB)
 
-	// n > 0
-	MOVD   s+48(FP), R4
-	CMPBEQ R0, R4, Z80     // handle 0 case beq
-	MOVD   $64, R6
-	CMPBEQ R6, R4, Z864    // handle 64 case beq
-	MOVD   z+0(FP), R2
-	MOVD   x+24(FP), R8
-	SLD    $3, R5          // n = n*8
-	SUB    R4, R6, R7
-	MOVD   (R8)(R5*1), R10 // w1 = x[i-1]
-	SRD    R7, R10, R3
-	MOVD   R3, c+56(FP)
-
-	MOVD $0, R1 // i = 0
-	BR   E8
-
-	// i < n-1
-L8:
-	MOVD R10, R3           // w = w1
-	MOVD -8(R8)(R5*1), R10 // w1 = x[i+1]
-
-	SLD  R4, R3         // w<<s | w1>>ŝ
-	SRD  R7, R10, R6
-	OR   R6, R3
-	MOVD R3, (R2)(R5*1) // z[i] = w<<s | w1>>ŝ
-	SUB  $8, R5         // i--
-
-E8:
-	CMPBGT R5, R0, L8 // i < n-1
-
-	// i >= n-1
-X8a:
-	SLD  R4, R10   // w1<<s
-	MOVD R10, (R2) // z[0] = w1<<s
-	RET
-
-X8b:
-	MOVD R0, c+56(FP)
-	RET
-
-Z80:
-	MOVD z+0(FP), R2
-	MOVD x+24(FP), R8
-	SLD  $3, R5       // n = n*8
-
-	MOVD (R8), R10
-	MOVD $0, R3
-	MOVD R3, c+56(FP)
-
-	MOVD $0, R1 // i = 0
-	BR   E8Z
-
-	// i < n-1
-L8Z:
-	MOVD R10, R3
-	MOVD 8(R8)(R1*1), R10
-
-	MOVD R3, (R2)(R1*1)
-	ADD  $8, R1
-
-E8Z:
-	CMPBLT R1, R5, L8Z
-
-	// i >= n-1
-	MOVD R10, (R2)(R5*1)
-	RET
-
-Z864:
-	MOVD z+0(FP), R2
-	MOVD x+24(FP), R8
-	SLD  $3, R5         // n = n*8
-	MOVD (R8)(R5*1), R3 // w1 = x[n-1]
-	MOVD R3, c+56(FP)   // z[i] = x[n-1]
-
-	BR E864
-
-	// i < n-1
-L864:
-	MOVD -8(R8)(R5*1), R3
-
-	MOVD R3, (R2)(R5*1) // z[i] = x[n-1]
-	SUB  $8, R5         // i--
-
-E864:
-	CMPBGT R5, R0, L864 // i < n-1
-
-	MOVD R0, (R2) // z[n-1] = 0
-	RET
-
-// CX = R4, r8 = r8, r10 = r2 , r11 = r5, DX = r3, AX = r10 , BX = R1 , 64-count = r7 (R0 set to 0) temp = R6
 // func shrVU(z, x []Word, s uint) (c Word)
 TEXT ·shrVU(SB), NOSPLIT, $0
-	MOVD z_len+8(FP), R5
-	MOVD $0, R0
-	SUB  $1, R5          // n--
-	BLT  X9b             // n < 0        (n <= 0)
-
-	// n > 0
-	MOVD   s+48(FP), R4
-	CMPBEQ R0, R4, ZB0  // handle 0 case beq
-	MOVD   $64, R6
-	CMPBEQ R6, R4, ZB64 // handle 64 case beq
-	MOVD   z+0(FP), R2
-	MOVD   x+24(FP), R8
-	SLD    $3, R5       // n = n*8
-	SUB    R4, R6, R7
-	MOVD   (R8), R10    // w1 = x[0]
-	SLD    R7, R10, R3
-	MOVD   R3, c+56(FP)
-
-	MOVD $0, R1 // i = 0
-	BR   E9
-
-	// i < n-1
-L9:
-	MOVD R10, R3          // w = w1
-	MOVD 8(R8)(R1*1), R10 // w1 = x[i+1]
-
-	SRD  R4, R3         // w>>s | w1<<s
-	SLD  R7, R10, R6
-	OR   R6, R3
-	MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<<s
-	ADD  $8, R1         // i++
-
-E9:
-	CMPBLT R1, R5, L9 // i < n-1
-
-	// i >= n-1
-X9a:
-	SRD  R4, R10         // w1>>s
-	MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s
-	RET
-
-X9b:
-	MOVD R0, c+56(FP)
-	RET
-
-ZB0:
-	MOVD z+0(FP), R2
-	MOVD x+24(FP), R8
-	SLD  $3, R5       // n = n*8
-
-	MOVD (R8), R10    // w1 = x[0]
-	MOVD $0, R3       // R10 << 64
-	MOVD R3, c+56(FP)
-
-	MOVD $0, R1 // i = 0
-	BR   E9Z
-
-	// i < n-1
-L9Z:
-	MOVD R10, R3          // w = w1
-	MOVD 8(R8)(R1*1), R10 // w1 = x[i+1]
-
-	MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<<s
-	ADD  $8, R1         // i++
-
-E9Z:
-	CMPBLT R1, R5, L9Z // i < n-1
-
-	// i >= n-1
-	MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s
-	RET
-
-ZB64:
-	MOVD z+0(FP), R2
-	MOVD x+24(FP), R8
-	SLD  $3, R5       // n = n*8
-	MOVD (R8), R3     // w1 = x[0]
-	MOVD R3, c+56(FP)
-
-	MOVD $0, R1 // i = 0
-	BR   E964
-
-	// i < n-1
-L964:
-	MOVD 8(R8)(R1*1), R3 // w1 = x[i+1]
-
-	MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<<s
-	ADD  $8, R1         // i++
-
-E964:
-	CMPBLT R1, R5, L964 // i < n-1
-
-	// i >= n-1
-	MOVD $0, R10         // w1>>s
-	MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s
-	RET
+	BR ·shrVU_g(SB)
 
 // CX = R4, r8 = r8, r9=r9, r10 = r2 , r11 = r5, DX = r3, AX = r6 , BX = R1 , (R0 set to 0) + use R11 + use R7 for i
 // func mulAddVWW(z, x []Word, y, r Word) (c Word)
diff --git a/src/math/big/arith_test.go b/src/math/big/arith_test.go
index 05136f1..fbbaa0e 100644
--- a/src/math/big/arith_test.go
+++ b/src/math/big/arith_test.go
@@ -224,37 +224,73 @@
 	m  string // message.
 }
 
+var argshlVUIn = []Word{1, 2, 4, 8, 16, 32, 64, 0, 0, 0}
+var argshlVUr0 = []Word{1, 2, 4, 8, 16, 32, 64}
+var argshlVUr1 = []Word{2, 4, 8, 16, 32, 64, 128}
+var argshlVUrWm1 = []Word{1 << (_W - 1), 0, 1, 2, 4, 8, 16}
+
 var argshlVU = []argVU{
 	// test cases for shlVU
 	{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0}, 7, 0, 0, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "complete overlap of shlVU"},
 	{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0}, 7, 0, 3, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by half of shlVU"},
 	{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0}, 7, 0, 6, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by 1 Word of shlVU"},
 	{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0, 0}, 7, 0, 7, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "no overlap of shlVU"},
+	// additional test cases with shift values of 0, 1 and (_W-1)
+	{argshlVUIn, 7, 0, 0, 0, argshlVUr0, 0, "complete overlap of shlVU and shift of 0"},
+	{argshlVUIn, 7, 0, 0, 1, argshlVUr1, 0, "complete overlap of shlVU and shift of 1"},
+	{argshlVUIn, 7, 0, 0, _W - 1, argshlVUrWm1, 32, "complete overlap of shlVU and shift of _W - 1"},
+	{argshlVUIn, 7, 0, 1, 0, argshlVUr0, 0, "partial overlap by 6 Words of shlVU and shift of 0"},
+	{argshlVUIn, 7, 0, 1, 1, argshlVUr1, 0, "partial overlap by 6 Words of shlVU and shift of 1"},
+	{argshlVUIn, 7, 0, 1, _W - 1, argshlVUrWm1, 32, "partial overlap by 6 Words of shlVU and shift of _W - 1"},
+	{argshlVUIn, 7, 0, 2, 0, argshlVUr0, 0, "partial overlap by 5 Words of shlVU and shift of 0"},
+	{argshlVUIn, 7, 0, 2, 1, argshlVUr1, 0, "partial overlap by 5 Words of shlVU and shift of 1"},
+	{argshlVUIn, 7, 0, 2, _W - 1, argshlVUrWm1, 32, "partial overlap by 5 Words of shlVU abd shift of _W - 1"},
+	{argshlVUIn, 7, 0, 3, 0, argshlVUr0, 0, "partial overlap by 4 Words of shlVU and shift of 0"},
+	{argshlVUIn, 7, 0, 3, 1, argshlVUr1, 0, "partial overlap by 4 Words of shlVU and shift of 1"},
+	{argshlVUIn, 7, 0, 3, _W - 1, argshlVUrWm1, 32, "partial overlap by 4 Words of shlVU and shift of _W - 1"},
 }
 
+var argshrVUIn = []Word{0, 0, 0, 1, 2, 4, 8, 16, 32, 64}
+var argshrVUr0 = []Word{1, 2, 4, 8, 16, 32, 64}
+var argshrVUr1 = []Word{0, 1, 2, 4, 8, 16, 32}
+var argshrVUrWm1 = []Word{4, 8, 16, 32, 64, 128, 0}
+
 var argshrVU = []argVU{
 	// test cases for shrVU
 	{[]Word{0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 1, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "complete overlap of shrVU"},
 	{[]Word{0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 4, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by half of shrVU"},
 	{[]Word{0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 7, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by 1 Word of shrVU"},
 	{[]Word{0, 0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 8, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "no overlap of shrVU"},
+	// additional test cases with shift values of 0, 1 and (_W-1)
+	{argshrVUIn, 7, 3, 3, 0, argshrVUr0, 0, "complete overlap of shrVU and shift of 0"},
+	{argshrVUIn, 7, 3, 3, 1, argshrVUr1, 1 << (_W - 1), "complete overlap of shrVU and shift of 1"},
+	{argshrVUIn, 7, 3, 3, _W - 1, argshrVUrWm1, 2, "complete overlap of shrVU and shift of _W - 1"},
+	{argshrVUIn, 7, 3, 2, 0, argshrVUr0, 0, "partial overlap by 6 Words of shrVU and shift of 0"},
+	{argshrVUIn, 7, 3, 2, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 6 Words of shrVU and shift of 1"},
+	{argshrVUIn, 7, 3, 2, _W - 1, argshrVUrWm1, 2, "partial overlap by 6 Words of shrVU and shift of _W - 1"},
+	{argshrVUIn, 7, 3, 1, 0, argshrVUr0, 0, "partial overlap by 5 Words of shrVU and shift of 0"},
+	{argshrVUIn, 7, 3, 1, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 5 Words of shrVU and shift of 1"},
+	{argshrVUIn, 7, 3, 1, _W - 1, argshrVUrWm1, 2, "partial overlap by 5 Words of shrVU and shift of _W - 1"},
+	{argshrVUIn, 7, 3, 0, 0, argshrVUr0, 0, "partial overlap by 4 Words of shrVU and shift of 0"},
+	{argshrVUIn, 7, 3, 0, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 4 Words of shrVU and shift of 1"},
+	{argshrVUIn, 7, 3, 0, _W - 1, argshrVUrWm1, 2, "partial overlap by 4 Words of shrVU and shift of _W - 1"},
 }
 
 func testShiftFunc(t *testing.T, f func(z, x []Word, s uint) Word, a argVU) {
-	// save a.d for error message, or it will be overwritten.
+	// work on copy of a.d to preserve the original data.
 	b := make([]Word, len(a.d))
 	copy(b, a.d)
-	z := a.d[a.zp : a.zp+a.l]
-	x := a.d[a.xp : a.xp+a.l]
+	z := b[a.zp : a.zp+a.l]
+	x := b[a.xp : a.xp+a.l]
 	c := f(z, x, a.s)
 	for i, zi := range z {
 		if zi != a.r[i] {
-			t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i])
+			t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i])
 			break
 		}
 	}
 	if c != a.c {
-		t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c)
+		t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c)
 	}
 }
 
@@ -274,11 +310,24 @@
 	// compute 10^n via 5^n << n.
 	const n = 165
 	p := nat(nil).expNN(nat{5}, nat{n}, nil)
-	p = p.shl(p, uint(n))
+	p = p.shl(p, n)
 	got := string(p.utoa(10))
 	want := "1" + strings.Repeat("0", n)
 	if got != want {
-		t.Errorf("shl(%v, %v)\n\tgot %s; want %s\n", p, uint(n), got, want)
+		t.Errorf("shl(%v, %v)\n\tgot  %s\n\twant %s", p, n, got, want)
+	}
+}
+
+const issue42838Value = "159309191113245227702888039776771180559110455519261878607388585338616290151305816094308987472018268594098344692611135542392730712890625"
+
+func TestIssue42838(t *testing.T) {
+	const s = 192
+	z, _, _, _ := nat(nil).scan(strings.NewReader(issue42838Value), 0, false)
+	z = z.shl(z, s)
+	got := string(z.utoa(10))
+	want := "1" + strings.Repeat("0", s)
+	if got != want {
+		t.Errorf("shl(%v, %v)\n\tgot  %s\n\twant %s", z, s, got, want)
 	}
 }
 
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
index 941139e..ac3c8bd 100644
--- a/src/math/big/ratconv.go
+++ b/src/math/big/ratconv.go
@@ -51,7 +51,8 @@
 // An optional base-10 ``e'' or base-2 ``p'' (or their upper-case variants)
 // exponent may be provided as well, except for hexadecimal floats which
 // only accept an (optional) ``p'' exponent (because an ``e'' or ``E'' cannot
-// be distinguished from a mantissa digit).
+// be distinguished from a mantissa digit). If the exponent's absolute value
+// is too large, the operation may fail.
 // The entire string, not just a prefix, must be valid for success. If the
 // operation failed, the value of z is undefined but the returned value is nil.
 func (z *Rat) SetString(s string) (*Rat, bool) {
@@ -169,6 +170,9 @@
 		if n < 0 {
 			n = -n
 		}
+		if n > 1e6 {
+			return nil, false // avoid excessively large exponents
+		}
 		pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs
 		if exp5 > 0 {
 			z.a.abs = z.a.abs.mul(z.a.abs, pow5)
@@ -181,15 +185,12 @@
 	}
 
 	// apply exp2 contributions
+	if exp2 < -1e7 || exp2 > 1e7 {
+		return nil, false // avoid excessively large exponents
+	}
 	if exp2 > 0 {
-		if int64(uint(exp2)) != exp2 {
-			panic("exponent too large")
-		}
 		z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2))
 	} else if exp2 < 0 {
-		if int64(uint(-exp2)) != -exp2 {
-			panic("exponent too large")
-		}
 		z.b.abs = z.b.abs.shl(z.b.abs, uint(-exp2))
 	}
 
diff --git a/src/math/big/ratconv_test.go b/src/math/big/ratconv_test.go
index ba0d1ba..15d206c 100644
--- a/src/math/big/ratconv_test.go
+++ b/src/math/big/ratconv_test.go
@@ -589,3 +589,28 @@
 		}
 	}
 }
+
+func TestIssue45910(t *testing.T) {
+	var x Rat
+	for _, test := range []struct {
+		input string
+		want  bool
+	}{
+		{"1e-1000001", false},
+		{"1e-1000000", true},
+		{"1e+1000000", true},
+		{"1e+1000001", false},
+
+		{"0p1000000000000", true},
+		{"1p-10000001", false},
+		{"1p-10000000", true},
+		{"1p+10000000", true},
+		{"1p+10000001", false},
+		{"1.770p02041010010011001001", false}, // test case from issue
+	} {
+		_, got := x.SetString(test.input)
+		if got != test.want {
+			t.Errorf("SetString(%s) got ok = %v; want %v", test.input, got, test.want)
+		}
+	}
+}
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 0655363..f646629 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -1799,3 +1799,161 @@
 		t.Errorf("names = %q; want %q", names, want)
 	}
 }
+
+func TestCVE202133195(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,
+					RecursionAvailable: true,
+				},
+				Questions: q.Questions,
+			}
+			switch q.Questions[0].Type {
+			case dnsmessage.TypeCNAME:
+				r.Answers = []dnsmessage.Resource{}
+			case dnsmessage.TypeA: // CNAME lookup uses a A/AAAA as a proxy
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypeA,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.AResource{
+							A: TestAddr,
+						},
+					},
+				)
+			case dnsmessage.TypeSRV:
+				n := q.Questions[0].Name
+				if n.String() == "_hdr._tcp.golang.org." {
+					n = dnsmessage.MustNewName("<html>.golang.org.")
+				}
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   n,
+							Type:   dnsmessage.TypeSRV,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.SRVResource{
+							Target: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+				)
+			case dnsmessage.TypeMX:
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypeMX,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.MXResource{
+							MX: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+				)
+			case dnsmessage.TypeNS:
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypeNS,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.NSResource{
+							NS: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+				)
+			case dnsmessage.TypePTR:
+				r.Answers = append(r.Answers,
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("<html>.golang.org."),
+							Type:   dnsmessage.TypePTR,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.PTRResource{
+							PTR: dnsmessage.MustNewName("<html>.golang.org."),
+						},
+					},
+				)
+			}
+			return r, nil
+		},
+	}
+
+	r := Resolver{PreferGo: true, Dial: fake.DialContext}
+	// Change the default resolver to match our manipulated resolver
+	originalDefault := DefaultResolver
+	DefaultResolver = &r
+	defer func() { DefaultResolver = originalDefault }()
+	// Redirect host file lookups.
+	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)
+	}
+
+	_, _, 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)
+	}
+
+	_, _, 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)
+	}
+}
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 3f48fab..f49cefb 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -248,22 +248,18 @@
 	// important is "Connection" because we want a persistent
 	// connection, regardless of what the client sent to us.
 	for _, h := range hopHeaders {
-		hv := outreq.Header.Get(h)
-		if hv == "" {
-			continue
-		}
-		if h == "Te" && hv == "trailers" {
-			// Issue 21096: tell backend applications that
-			// care about trailer support that we support
-			// trailers. (We do, but we don't go out of
-			// our way to advertise that unless the
-			// incoming client request thought it was
-			// worth mentioning)
-			continue
-		}
 		outreq.Header.Del(h)
 	}
 
+	// Issue 21096: tell backend applications that care about trailer support
+	// that we support trailers. (We do, but we don't go out of our way to
+	// advertise that unless the incoming client request thought it was worth
+	// mentioning.) Note that we look at req.Header, not outreq.Header, since
+	// the latter has passed through removeConnectionHeaders.
+	if httpguts.HeaderValuesContainsToken(req.Header["Te"], "trailers") {
+		outreq.Header.Set("Te", "trailers")
+	}
+
 	// After stripping all the hop-by-hop connection headers above, add back any
 	// necessary for protocol upgrades, such as for websockets.
 	if reqUpType != "" {
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 764939f..1f2dfb9 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -91,8 +91,9 @@
 
 	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
 	getReq.Host = "some-name"
-	getReq.Header.Set("Connection", "close")
-	getReq.Header.Set("Te", "trailers")
+	getReq.Header.Set("Connection", "close, TE")
+	getReq.Header.Add("Te", "foo")
+	getReq.Header.Add("Te", "bar, trailers")
 	getReq.Header.Set("Proxy-Connection", "should be deleted")
 	getReq.Header.Set("Upgrade", "foo")
 	getReq.Close = true
@@ -236,6 +237,64 @@
 	}
 }
 
+func TestReverseProxyStripEmptyConnection(t *testing.T) {
+	// See Issue 46313.
+	const backendResponse = "I am the backend"
+
+	// someConnHeader is some arbitrary header to be declared as a hop-by-hop header
+	// in the Request's Connection header.
+	const someConnHeader = "X-Some-Conn-Header"
+
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if c := r.Header.Values("Connection"); len(c) != 0 {
+			t.Errorf("handler got header %q = %v; want empty", "Connection", c)
+		}
+		if c := r.Header.Get(someConnHeader); c != "" {
+			t.Errorf("handler got header %q = %q; want empty", someConnHeader, c)
+		}
+		w.Header().Add("Connection", "")
+		w.Header().Add("Connection", someConnHeader)
+		w.Header().Set(someConnHeader, "should be deleted")
+		io.WriteString(w, backendResponse)
+	}))
+	defer backend.Close()
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	proxyHandler := NewSingleHostReverseProxy(backendURL)
+	frontend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		proxyHandler.ServeHTTP(w, r)
+		if c := r.Header.Get(someConnHeader); c != "should be deleted" {
+			t.Errorf("handler modified header %q = %q; want %q", someConnHeader, c, "should be deleted")
+		}
+	}))
+	defer frontend.Close()
+
+	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
+	getReq.Header.Add("Connection", "")
+	getReq.Header.Add("Connection", someConnHeader)
+	getReq.Header.Set(someConnHeader, "should be deleted")
+	res, err := frontend.Client().Do(getReq)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+	defer res.Body.Close()
+	bodyBytes, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatalf("reading body: %v", err)
+	}
+	if got, want := string(bodyBytes), backendResponse; got != want {
+		t.Errorf("got body %q; want %q", got, want)
+	}
+	if c := res.Header.Get("Connection"); c != "" {
+		t.Errorf("handler got header %q = %q; want empty", "Connection", c)
+	}
+	if c := res.Header.Get(someConnHeader); c != "" {
+		t.Errorf("handler got header %q = %q; want empty", someConnHeader, c)
+	}
+}
+
 func TestXForwardedFor(t *testing.T) {
 	const prevForwardedFor = "client ip"
 	const backendResponse = "I am the backend"
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 3c7b9eb..faa77e9 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -5270,7 +5270,6 @@
 
 	ln := newLocalListener(t)
 	addr := ln.Addr().String()
-	shutdown := make(chan bool, 1)
 	done := make(chan bool)
 	fullAddrURL := fmt.Sprintf("http://%s", addr)
 	raw := "HTTP/1.1 400\r\n" +
@@ -5282,10 +5281,7 @@
 		"Aloha Olaa"
 
 	go func() {
-		defer func() {
-			ln.Close()
-			close(done)
-		}()
+		defer close(done)
 
 		conn, _ := ln.Accept()
 		if conn != nil {
@@ -5316,7 +5312,7 @@
 		t.Errorf("got=%v want=%q", err, want)
 	}
 
-	close(shutdown)
+	ln.Close()
 	<-done
 }
 
diff --git a/src/net/lookup.go b/src/net/lookup.go
index 5f71198..0660268 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -389,8 +389,11 @@
 // LookupCNAME does not return an error if host does not
 // contain DNS "CNAME" records, as long as host resolves to
 // address records.
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
 func LookupCNAME(host string) (cname string, err error) {
-	return DefaultResolver.lookupCNAME(context.Background(), host)
+	return DefaultResolver.LookupCNAME(context.Background(), host)
 }
 
 // LookupCNAME returns the canonical name for the given host.
@@ -403,8 +406,18 @@
 // LookupCNAME does not return an error if host does not
 // contain DNS "CNAME" records, as long as host resolves to
 // address records.
-func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string, err error) {
-	return r.lookupCNAME(ctx, host)
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
+func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) {
+	cname, err := r.lookupCNAME(ctx, host)
+	if err != nil {
+		return "", err
+	}
+	if !isDomainName(cname) {
+		return "", &DNSError{Err: "CNAME target is invalid", Name: host}
+	}
+	return cname, nil
 }
 
 // LookupSRV tries to resolve an SRV query of the given service,
@@ -416,8 +429,11 @@
 // That is, it looks up _service._proto.name. To accommodate services
 // publishing SRV records under non-standard names, if both service
 // and proto are empty strings, LookupSRV looks up name directly.
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names.
 func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
-	return DefaultResolver.lookupSRV(context.Background(), service, proto, name)
+	return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
 }
 
 // LookupSRV tries to resolve an SRV query of the given service,
@@ -429,28 +445,82 @@
 // That is, it looks up _service._proto.name. To accommodate services
 // publishing SRV records under non-standard names, if both service
 // and proto are empty strings, LookupSRV looks up name directly.
-func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*SRV, err error) {
-	return r.lookupSRV(ctx, service, proto, name)
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names.
+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 {
+		return "", nil, err
+	}
+	if cname != "" && !isDomainName(cname) {
+		return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
+	}
+	for _, addr := range addrs {
+		if addr == nil {
+			continue
+		}
+		if !isDomainName(addr.Target) {
+			return "", nil, &DNSError{Err: "SRV target is invalid", Name: name}
+		}
+	}
+	return cname, addrs, 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.
 func LookupMX(name string) ([]*MX, error) {
-	return DefaultResolver.lookupMX(context.Background(), name)
+	return DefaultResolver.LookupMX(context.Background(), name)
 }
 
 // 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.
 func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
-	return r.lookupMX(ctx, name)
+	records, err := r.lookupMX(ctx, name)
+	if err != nil {
+		return nil, err
+	}
+	for _, mx := range records {
+		if mx == nil {
+			continue
+		}
+		if !isDomainName(mx.Host) {
+			return nil, &DNSError{Err: "MX target is invalid", Name: name}
+		}
+	}
+	return records, 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.
 func LookupNS(name string) ([]*NS, error) {
-	return DefaultResolver.lookupNS(context.Background(), name)
+	return DefaultResolver.LookupNS(context.Background(), name)
 }
 
 // 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.
 func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
-	return r.lookupNS(ctx, name)
+	records, err := r.lookupNS(ctx, name)
+	if err != nil {
+		return nil, err
+	}
+	for _, ns := range records {
+		if ns == nil {
+			continue
+		}
+		if !isDomainName(ns.Host) {
+			return nil, &DNSError{Err: "NS target is invalid", Name: name}
+		}
+	}
+	return records, nil
 }
 
 // LookupTXT returns the DNS TXT records for the given domain name.
@@ -466,14 +536,29 @@
 // LookupAddr performs a reverse lookup for the given address, returning a list
 // of names mapping to that address.
 //
+// The returned names are validated to be properly formatted presentation-format
+// domain names.
+//
 // When using the host C library resolver, at most one result will be
 // returned. To bypass the host resolver, use a custom Resolver.
 func LookupAddr(addr string) (names []string, err error) {
-	return DefaultResolver.lookupAddr(context.Background(), addr)
+	return DefaultResolver.LookupAddr(context.Background(), addr)
 }
 
 // LookupAddr performs a reverse lookup for the given address, returning a list
 // of names mapping to that address.
-func (r *Resolver) LookupAddr(ctx context.Context, addr string) (names []string, err error) {
-	return r.lookupAddr(ctx, addr)
+//
+// The returned names are validated to be properly formatted presentation-format
+// domain names.
+func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
+	names, err := r.lookupAddr(ctx, addr)
+	if err != nil {
+		return nil, err
+	}
+	for _, name := range names {
+		if !isDomainName(name) {
+			return nil, &DNSError{Err: "PTR target is invalid", Name: addr}
+		}
+	}
+	return names, nil
 }