From f0ff6d4a67ec9a956aa655d487543da034cf576b Mon Sep 17 00:00:00 2001
From: Robert Griesemer
Date: Wed, 25 Nov 2020 13:47:42 -0800
Subject: [PATCH 01/50] reflect: fix Value.Convert for int-to-string
conversions (regression)
The bug was introduced by https://golang.org/cl/220844.
Updates #42792.
Fixes #42835.
Change-Id: I03065c7526488aded35ef2f800b7162e1606877a
Reviewed-on: https://go-review.googlesource.com/c/go/+/273326
Trust: Robert Griesemer
Run-TryBot: Robert Griesemer
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
---
src/reflect/all_test.go | 3 +++
src/reflect/value.go | 12 ++++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index a12712d254..b01158635f 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -4007,9 +4007,12 @@ var convertTests = []struct {
{V(int16(-3)), V(string("\uFFFD"))},
{V(int32(-4)), V(string("\uFFFD"))},
{V(int64(-5)), V(string("\uFFFD"))},
+ {V(int64(-1 << 32)), V(string("\uFFFD"))},
+ {V(int64(1 << 32)), V(string("\uFFFD"))},
{V(uint(0x110001)), V(string("\uFFFD"))},
{V(uint32(0x110002)), V(string("\uFFFD"))},
{V(uint64(0x110003)), V(string("\uFFFD"))},
+ {V(uint64(1 << 32)), V(string("\uFFFD"))},
{V(uintptr(0x110004)), V(string("\uFFFD"))},
// named string
diff --git a/src/reflect/value.go b/src/reflect/value.go
index bf926a7453..1f185b52e4 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -2681,12 +2681,20 @@ func cvtComplex(v Value, t Type) Value {
// convertOp: intXX -> string
func cvtIntString(v Value, t Type) Value {
- return makeString(v.flag.ro(), string(rune(v.Int())), t)
+ s := "\uFFFD"
+ if x := v.Int(); int64(rune(x)) == x {
+ s = string(rune(x))
+ }
+ return makeString(v.flag.ro(), s, t)
}
// convertOp: uintXX -> string
func cvtUintString(v Value, t Type) Value {
- return makeString(v.flag.ro(), string(rune(v.Uint())), t)
+ s := "\uFFFD"
+ if x := v.Uint(); uint64(rune(x)) == x {
+ s = string(rune(x))
+ }
+ return makeString(v.flag.ro(), s, t)
}
// convertOp: []byte -> string
From 926994fd7cf65b2703552686965fb05569699897 Mon Sep 17 00:00:00 2001
From: Rodolfo Carvalho
Date: Thu, 26 Nov 2020 17:01:35 +0100
Subject: [PATCH 02/50] log: make Default doc comment consistent with package
doc
None of the other, older, doc comments use the '*Logger' form, and while
'Logger' and 'logger' are both used in the package doc comment, the
common term used with the intended meaning is 'standard logger', which
appears another eleven times in doc comments.
Change-Id: I089103198fc82390517615eb27bbe7ef77107d34
Reviewed-on: https://go-review.googlesource.com/c/go/+/273486
Reviewed-by: Rob Pike
Reviewed-by: Ian Lance Taylor
Trust: Ian Lance Taylor
---
src/log/log.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/log/log.go b/src/log/log.go
index 8c0f83f0d1..b77af29032 100644
--- a/src/log/log.go
+++ b/src/log/log.go
@@ -75,7 +75,7 @@ func (l *Logger) SetOutput(w io.Writer) {
var std = New(os.Stderr, "", LstdFlags)
-// Default returns the *Logger used by the package-level output functions.
+// Default returns the standard logger used by the package-level output functions.
func Default() *Logger { return std }
// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
From 91f77ca2f8590ed2051ee9a62d52676cf1bff98d Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Fri, 27 Nov 2020 20:45:15 +0100
Subject: [PATCH 03/50] runtime: return 0 from C function in test
This function's prototype includes a return value, so return a value.
Otherwise clang gets upset:
--- FAIL: TestDLLPreloadMitigation (1.40s)
syscall_windows_test.go:986: failed to build dll: exit status 1 - nojack.c:7:1: error: non-void function does not return a value [-Werror,-Wreturn-type]
}
^
1 error generated.
Fixes #42860.
Change-Id: I65b8eb9ccb502692c5b65bd34829f331cd86eef0
Reviewed-on: https://go-review.googlesource.com/c/go/+/273726
Trust: Jason A. Donenfeld
Trust: Brad Fitzpatrick
Reviewed-by: Brad Fitzpatrick
---
src/runtime/syscall_windows_test.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
index 3827c6ed83..a20573eb6a 100644
--- a/src/runtime/syscall_windows_test.go
+++ b/src/runtime/syscall_windows_test.go
@@ -969,8 +969,9 @@ func TestDLLPreloadMitigation(t *testing.T) {
#include
#include
-uintptr_t cfunc() {
+uintptr_t cfunc(void) {
SetLastError(123);
+ return 0;
}
`
srcname := "nojack.c"
From 0252cfd84d6268985199f96239e65a0b0d32363c Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Fri, 27 Nov 2020 22:07:23 +0100
Subject: [PATCH 04/50] runtime: adjust address calculation in identifying
abort on windows/arm
Apparently we're being called on arm 1 byte off, just like on 386 and
amd64, so unify the handler for isAbortPC.
Fixes #42859.
Updates #29050.
Change-Id: I97fffeb4a33d93ca3397ce1c9ba2b05137f391ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/273727
Run-TryBot: Jason A. Donenfeld
Reviewed-by: Alex Brainman
Trust: Alex Brainman
Trust: Jason A. Donenfeld
---
src/runtime/signal_windows.go | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/src/runtime/signal_windows.go b/src/runtime/signal_windows.go
index 6d98d02598..3af2e39b08 100644
--- a/src/runtime/signal_windows.go
+++ b/src/runtime/signal_windows.go
@@ -43,16 +43,9 @@ func initExceptionHandler() {
//
//go:nosplit
func isAbort(r *context) bool {
- switch GOARCH {
- case "386", "amd64":
- // In the case of an abort, the exception IP is one byte after
- // the INT3 (this differs from UNIX OSes).
- return isAbortPC(r.ip() - 1)
- case "arm":
- return isAbortPC(r.ip())
- default:
- return false
- }
+ // In the case of an abort, the exception IP is one byte after
+ // the INT3 (this differs from UNIX OSes).
+ return isAbortPC(r.ip() - 1)
}
// isgoexception reports whether this exception should be translated
From cb84d831c956026f477b52c9f8a7c1ed2b2724ad Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Thu, 26 Nov 2020 22:38:45 +0100
Subject: [PATCH 05/50] cmd/link: mark windows/arm as all PIE
If the linker thinks that it's in exe mode instead of pie mode, it
won't emit relocations when generating the pcln table, and we wind
up with crashes like this on windows/arm, where all binaries are
in fact relocated:
Building Go toolchain2 using go_bootstrap and Go toolchain1.
fatal error: minpc or maxpc invalid
runtime: panic before malloc heap initialized
This problem was already solved by darwin/arm64, so solve it the same
way here for windows/arm.
Fixes CL 228478.
Fixes #42786.
Change-Id: I6d1db6907c131183649fc263ccca06783188f344
Reviewed-on: https://go-review.googlesource.com/c/go/+/273566
Run-TryBot: Jason A. Donenfeld
Reviewed-by: Alex Brainman
Trust: Alex Brainman
Trust: Jason A. Donenfeld
---
src/cmd/link/internal/ld/config.go | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
index 0cb3cc25c0..d1e06239a5 100644
--- a/src/cmd/link/internal/ld/config.go
+++ b/src/cmd/link/internal/ld/config.go
@@ -35,11 +35,12 @@ func (mode *BuildMode) Set(s string) error {
default:
return fmt.Errorf("invalid buildmode: %q", s)
case "exe":
- if objabi.GOOS == "darwin" && objabi.GOARCH == "arm64" {
- *mode = BuildModePIE // On darwin/arm64 everything is PIE.
- break
+ switch objabi.GOOS + "/" + objabi.GOARCH {
+ case "darwin/arm64", "windows/arm": // On these platforms, everything is PIE
+ *mode = BuildModePIE
+ default:
+ *mode = BuildModeExe
}
- *mode = BuildModeExe
case "pie":
switch objabi.GOOS {
case "aix", "android", "linux", "windows", "darwin", "ios":
From b94346e69bb01e1cd522ddfa9d09f41d9d4d3e98 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Thu, 26 Nov 2020 12:26:02 -0800
Subject: [PATCH 06/50] test: match gofrontend error messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These changes match the following gofrontend error messages:
blank1.go:16:1: error: may not define methods on non-local type
chan/perm.go:28:9: error: expected channel
chan/perm.go:29:11: error: left operand of ‘<-’ must be channel
chan/perm.go:69:9: error: argument must be channel
complit1.go:25:16: error: attempt to slice object that is not array, slice, or string
complit1.go:26:16: error: attempt to slice object that is not array, slice, or string
complit1.go:27:17: error: attempt to slice object that is not array, slice, or string
complit1.go:49:41: error: may only omit types within composite literals of slice, array, or map type
complit1.go:50:14: error: expected struct, slice, array, or map type for composite literal
convlit.go:24:9: error: invalid type conversion (cannot use type unsafe.Pointer as type string)
convlit.go:25:9: error: invalid type conversion (cannot use type unsafe.Pointer as type float64)
convlit.go:26:9: error: invalid type conversion (cannot use type unsafe.Pointer as type int)
ddd1.go:63:9: error: invalid use of ‘...’ calling non-variadic function
fixedbugs/bug176.go:12:18: error: index expression is not integer constant
fixedbugs/bug332.go:17:10: error: use of undefined type ‘T’
fixedbugs/issue4232.go:22:16: error: integer constant overflow
fixedbugs/issue4232.go:33:16: error: integer constant overflow
fixedbugs/issue4232.go:44:25: error: integer constant overflow
fixedbugs/issue4232.go:55:16: error: integer constant overflow
fixedbugs/issue4458.go:19:14: error: type has no method ‘foo’
fixedbugs/issue5172.go:24:14: error: too many expressions for struct
init.go:17:9: error: reference to undefined name ‘runtime’
initializerr.go:26:29: error: duplicate value for index 1
interface/explicit.go:60:14: error: type assertion only valid for interface types
label.go:64:9: error: reference to undefined label ‘go2’
label1.go:18:97: error: continue statement not within for
label1.go:22:97: error: continue statement not within for
label1.go:106:89: error: continue statement not within for
label1.go:108:26: error: invalid continue label ‘on’
label1.go:111:118: error: break statement not within for or switch or select
label1.go:113:23: error: invalid break label ‘dance’
map1.go:64:9: error: not enough arguments
map1.go:65:9: error: not enough arguments
map1.go:67:9: error: argument 1 must be a map
method2.go:36:11: error: reference to undefined field or method ‘val’
method2.go:37:11: error: reference to undefined field or method ‘val’
method2.go:41:12: error: method requires pointer (use ‘(*T).g’)
syntax/chan1.go:13:19: error: send statement used as value; use select for non-blocking send
syntax/chan1.go:17:11: error: send statement used as value; use select for non-blocking send
Change-Id: I98047b60a376e3d2788836300f7fcac3f2c285cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/273527
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Cherry Zhang
---
test/blank1.go | 2 +-
test/chan/perm.go | 6 +++---
test/complit1.go | 10 +++++-----
test/convlit.go | 6 +++---
test/ddd1.go | 2 +-
test/fixedbugs/bug176.go | 2 +-
test/fixedbugs/bug332.go | 2 +-
test/fixedbugs/issue4232.go | 8 ++++----
test/fixedbugs/issue4458.go | 2 +-
test/fixedbugs/issue5172.go | 2 +-
test/init.go | 2 +-
test/initializerr.go | 2 +-
test/interface/explicit.go | 2 +-
test/label.go | 2 +-
test/label1.go | 12 ++++++------
test/map1.go | 8 ++++----
test/method2.go | 6 +++---
test/syntax/chan1.go | 4 ++--
18 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/test/blank1.go b/test/blank1.go
index c9a8e6a290..70e01b1a30 100644
--- a/test/blank1.go
+++ b/test/blank1.go
@@ -13,7 +13,7 @@ var t struct {
_ int
}
-func (x int) _() { // ERROR "cannot define new methods on non-local type"
+func (x int) _() { // ERROR "methods on non-local type"
println(x)
}
diff --git a/test/chan/perm.go b/test/chan/perm.go
index 7da88bdae8..0c96d921d1 100644
--- a/test/chan/perm.go
+++ b/test/chan/perm.go
@@ -25,8 +25,8 @@ func main() {
cs = cr // ERROR "illegal types|incompatible|cannot"
var n int
- <-n // ERROR "receive from non-chan"
- n <- 2 // ERROR "send to non-chan"
+ <-n // ERROR "receive from non-chan|expected channel"
+ n <- 2 // ERROR "send to non-chan|must be channel"
c <- 0 // ok
<-c // ok
@@ -66,5 +66,5 @@ func main() {
close(c)
close(cs)
close(cr) // ERROR "receive"
- close(n) // ERROR "invalid operation.*non-chan type"
+ close(n) // ERROR "invalid operation.*non-chan type|must be channel"
}
diff --git a/test/complit1.go b/test/complit1.go
index eb0f920fcb..7c2a4e2996 100644
--- a/test/complit1.go
+++ b/test/complit1.go
@@ -22,9 +22,9 @@ var (
_ = m[0][:] // ERROR "slice of unaddressable value"
_ = f()[:] // ERROR "slice of unaddressable value"
- _ = 301[:] // ERROR "cannot slice"
- _ = 3.1[:] // ERROR "cannot slice"
- _ = true[:] // ERROR "cannot slice"
+ _ = 301[:] // ERROR "cannot slice|attempt to slice object that is not"
+ _ = 3.1[:] // ERROR "cannot slice|attempt to slice object that is not"
+ _ = true[:] // ERROR "cannot slice|attempt to slice object that is not"
// these are okay because they are slicing a pointer to an array
_ = (&[3]int{1, 2, 3})[:]
@@ -46,8 +46,8 @@ var (
_ = &T{0, 0, "", nil} // ok
_ = &T{i: 0, f: 0, s: "", next: {}} // ERROR "missing type in composite literal|omit types within composite literal"
_ = &T{0, 0, "", {}} // ERROR "missing type in composite literal|omit types within composite literal"
- _ = TP{i: 0, f: 0, s: "", next: {}} // ERROR "invalid composite literal type TP"
- _ = &Ti{} // ERROR "invalid composite literal type Ti"
+ _ = TP{i: 0, f: 0, s: "", next: {}} // ERROR "invalid composite literal type TP|omit types within composite literal"
+ _ = &Ti{} // ERROR "invalid composite literal type Ti|expected.*type for composite literal"
)
type M map[T]T
diff --git a/test/convlit.go b/test/convlit.go
index de760542da..1c66c89e88 100644
--- a/test/convlit.go
+++ b/test/convlit.go
@@ -21,9 +21,9 @@ var x6 = int(1e100) // ERROR "overflow"
var x7 = float32(1e1000) // ERROR "overflow"
// unsafe.Pointer can only convert to/from uintptr
-var _ = string(unsafe.Pointer(uintptr(65))) // ERROR "convert"
-var _ = float64(unsafe.Pointer(uintptr(65))) // ERROR "convert"
-var _ = int(unsafe.Pointer(uintptr(65))) // ERROR "convert"
+var _ = string(unsafe.Pointer(uintptr(65))) // ERROR "convert|conversion"
+var _ = float64(unsafe.Pointer(uintptr(65))) // ERROR "convert|conversion"
+var _ = int(unsafe.Pointer(uintptr(65))) // ERROR "convert|conversion"
// implicit conversions merit scrutiny
var s string
diff --git a/test/ddd1.go b/test/ddd1.go
index 9857814648..01b9c0eadb 100644
--- a/test/ddd1.go
+++ b/test/ddd1.go
@@ -60,5 +60,5 @@ func bad(args ...int) {
_ = [...]byte("foo") // ERROR "[.][.][.]"
_ = [...][...]int{{1,2,3},{4,5,6}} // ERROR "[.][.][.]"
- Foo(x...) // ERROR "invalid use of [.][.][.] in call"
+ Foo(x...) // ERROR "invalid use of .*[.][.][.]"
}
diff --git a/test/fixedbugs/bug176.go b/test/fixedbugs/bug176.go
index ea3a909747..7001dd081e 100644
--- a/test/fixedbugs/bug176.go
+++ b/test/fixedbugs/bug176.go
@@ -9,6 +9,6 @@ package main
var x int
var a = []int{ x: 1} // ERROR "constant"
-var b = [...]int{x: 1}
+var b = [...]int{x: 1} // GCCGO_ERROR "constant"
var c = map[int]int{ x: 1}
diff --git a/test/fixedbugs/bug332.go b/test/fixedbugs/bug332.go
index d43c2ddcff..159c8b4e68 100644
--- a/test/fixedbugs/bug332.go
+++ b/test/fixedbugs/bug332.go
@@ -14,4 +14,4 @@ func main() {}
// important: no newline on end of next line.
// 6g used to print instead of bug332.go:111
-func (t *T) F() {} // ERROR "undefined: T"
\ No newline at end of file
+func (t *T) F() {} // ERROR "undefined.*T"
\ No newline at end of file
diff --git a/test/fixedbugs/issue4232.go b/test/fixedbugs/issue4232.go
index 935f3820c6..30d132683a 100644
--- a/test/fixedbugs/issue4232.go
+++ b/test/fixedbugs/issue4232.go
@@ -19,7 +19,7 @@ func f() {
_ = a[10:10]
_ = a[9:12] // ERROR "invalid slice index 12|index out of bounds"
_ = a[11:12] // ERROR "invalid slice index 11|index out of bounds"
- _ = a[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
+ _ = a[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
var s []int
_ = s[-1] // ERROR "invalid slice index -1|index out of bounds"
@@ -30,7 +30,7 @@ func f() {
_ = s[10:10]
_ = s[9:12]
_ = s[11:12]
- _ = s[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
+ _ = s[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
const c = "foofoofoof"
_ = c[-1] // ERROR "invalid string index -1|index out of bounds"
@@ -41,7 +41,7 @@ func f() {
_ = c[10:10]
_ = c[9:12] // ERROR "invalid slice index 12|index out of bounds"
_ = c[11:12] // ERROR "invalid slice index 11|index out of bounds"
- _ = c[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
+ _ = c[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
var t string
_ = t[-1] // ERROR "invalid string index -1|index out of bounds"
@@ -52,5 +52,5 @@ func f() {
_ = t[10:10]
_ = t[9:12]
_ = t[11:12]
- _ = t[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
+ _ = t[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
}
diff --git a/test/fixedbugs/issue4458.go b/test/fixedbugs/issue4458.go
index 98ffea79dc..59cfa9fcee 100644
--- a/test/fixedbugs/issue4458.go
+++ b/test/fixedbugs/issue4458.go
@@ -16,5 +16,5 @@ func (T) foo() {}
func main() {
av := T{}
pav := &av
- (**T).foo(&pav) // ERROR "no method foo|requires named type or pointer to named"
+ (**T).foo(&pav) // ERROR "no method .*foo|requires named type or pointer to named"
}
diff --git a/test/fixedbugs/issue5172.go b/test/fixedbugs/issue5172.go
index 0339935b64..ed92ac6ff2 100644
--- a/test/fixedbugs/issue5172.go
+++ b/test/fixedbugs/issue5172.go
@@ -21,6 +21,6 @@ func main() {
go f.bar() // ERROR "undefined"
defer f.bar() // ERROR "undefined"
- t := T{1} // ERROR "too many values"
+ t := T{1} // ERROR "too many"
go t.Bar()
}
diff --git a/test/init.go b/test/init.go
index 317f2472cb..5e182281da 100644
--- a/test/init.go
+++ b/test/init.go
@@ -14,6 +14,6 @@ func init() {
func main() {
init() // ERROR "undefined.*init"
- runtime.init() // ERROR "undefined.*runtime\.init"
+ runtime.init() // ERROR "undefined.*runtime\.init|reference to undefined name"
var _ = init // ERROR "undefined.*init"
}
diff --git a/test/initializerr.go b/test/initializerr.go
index 990ab60f96..5e2e9a91a0 100644
--- a/test/initializerr.go
+++ b/test/initializerr.go
@@ -23,7 +23,7 @@ var a2 = S { Y: 3, Z: 2, Y: 3 } // ERROR "duplicate"
var a3 = T { S{}, 2, 3, 4, 5, 6 } // ERROR "convert|too many"
var a4 = [5]byte{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } // ERROR "index|too many"
var a5 = []byte { x: 2 } // ERROR "index"
-var a6 = []byte{1: 1, 2: 2, 1: 3} // ERROR "duplicate index"
+var a6 = []byte{1: 1, 2: 2, 1: 3} // ERROR "duplicate"
var ok1 = S { } // should be ok
var ok2 = T { S: ok1 } // should be ok
diff --git a/test/interface/explicit.go b/test/interface/explicit.go
index 1fb3b6a05a..3f9451e8d2 100644
--- a/test/interface/explicit.go
+++ b/test/interface/explicit.go
@@ -57,7 +57,7 @@ func main() {
// cannot type-assert non-interfaces
f := 2.0
- _ = f.(int) // ERROR "non-interface type"
+ _ = f.(int) // ERROR "non-interface type|only valid for interface types"
}
diff --git a/test/label.go b/test/label.go
index 11716cc2c5..7deead6fba 100644
--- a/test/label.go
+++ b/test/label.go
@@ -61,5 +61,5 @@ L10:
goto L10
- goto go2 // ERROR "label go2 not defined"
+ goto go2 // ERROR "label go2 not defined|reference to undefined label .*go2"
}
diff --git a/test/label1.go b/test/label1.go
index b2e0ef09b8..a8eaecbff2 100644
--- a/test/label1.go
+++ b/test/label1.go
@@ -15,11 +15,11 @@ var x int
func f1() {
switch x {
case 1:
- continue // ERROR "continue is not in a loop$"
+ continue // ERROR "continue is not in a loop$|continue statement not within for"
}
select {
default:
- continue // ERROR "continue is not in a loop$"
+ continue // ERROR "continue is not in a loop$|continue statement not within for"
}
}
@@ -103,14 +103,14 @@ L5:
}
}
- continue // ERROR "continue is not in a loop$"
+ continue // ERROR "continue is not in a loop$|continue statement not within for"
for {
- continue on // ERROR "continue label not defined: on"
+ continue on // ERROR "continue label not defined: on|invalid continue label .*on"
}
- break // ERROR "break is not in a loop, switch, or select"
+ break // ERROR "break is not in a loop, switch, or select|break statement not within for or switch or select"
for {
- break dance // ERROR "break label not defined: dance"
+ break dance // ERROR "break label not defined: dance|invalid break label .*dance"
}
for {
diff --git a/test/map1.go b/test/map1.go
index 498c2ec45b..b4aa70755f 100644
--- a/test/map1.go
+++ b/test/map1.go
@@ -61,8 +61,8 @@ type T8 struct { F *T7 }
func main() {
m := make(map[int]int)
- delete() // ERROR "missing arguments"
- delete(m) // ERROR "missing second \(key\) argument"
+ delete() // ERROR "missing arguments|not enough arguments"
+ delete(m) // ERROR "missing second \(key\) argument|not enough arguments"
delete(m, 2, 3) // ERROR "too many arguments"
- delete(1, m) // ERROR "first argument to delete must be map"
-}
\ No newline at end of file
+ delete(1, m) // ERROR "first argument to delete must be map|argument 1 must be a map"
+}
diff --git a/test/method2.go b/test/method2.go
index a45a943156..7feb675055 100644
--- a/test/method2.go
+++ b/test/method2.go
@@ -33,9 +33,9 @@ var _ = (*Val).val // ERROR "method"
var v Val
var pv = &v
-var _ = pv.val() // ERROR "pv.val undefined"
-var _ = pv.val // ERROR "pv.val undefined"
+var _ = pv.val() // ERROR "undefined"
+var _ = pv.val // ERROR "undefined"
func (t *T) g() int { return t.a }
-var _ = (T).g() // ERROR "needs pointer receiver|undefined"
+var _ = (T).g() // ERROR "needs pointer receiver|undefined|method requires pointer"
diff --git a/test/syntax/chan1.go b/test/syntax/chan1.go
index 56103d1d79..88a5b4777b 100644
--- a/test/syntax/chan1.go
+++ b/test/syntax/chan1.go
@@ -10,8 +10,8 @@ var c chan int
var v int
func main() {
- if c <- v { // ERROR "cannot use c <- v as value"
+ if c <- v { // ERROR "cannot use c <- v as value|send statement used as value"
}
}
-var _ = c <- v // ERROR "unexpected <-"
+var _ = c <- v // ERROR "unexpected <-|send statement used as value"
From 358d35455d06b1ebee948efff123842490dcb797 Mon Sep 17 00:00:00 2001
From: smasher164
Date: Thu, 26 Nov 2020 14:16:33 -0500
Subject: [PATCH 07/50] bufio: make string(int) conversion safer
Updates #42792.
Change-Id: I7e53426c41e5609d9dadceb300f7983ba7ad6577
Reviewed-on: https://go-review.googlesource.com/c/go/+/273526
Run-TryBot: Akhil Indurti
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
Reviewed-by: Robert Griesemer
---
src/bufio/bufio_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go
index 75086f1f24..d7b34bd0d8 100644
--- a/src/bufio/bufio_test.go
+++ b/src/bufio/bufio_test.go
@@ -146,7 +146,7 @@ func TestReader(t *testing.T) {
for i := 0; i < len(texts)-1; i++ {
texts[i] = str + "\n"
all += texts[i]
- str += string(rune(i)%26 + 'a')
+ str += string(rune(i%26 + 'a'))
}
texts[len(texts)-1] = all
From 4ce0a7cea6805277c3bfecbaab2170e5c2543cba Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Sat, 28 Nov 2020 14:38:29 +0100
Subject: [PATCH 08/50] runtime/pprof: ignore test failures on windows/arm
This is blocking forward progress of the de-bitrotting work, and I don't
know off hand how to fix this. Seeing as its disabled on other
platforms, I suspect pprof might not be a very reliable feature, so just
allow for the tests to fail for now, until somebody more motivated comes
along to fix it.
Updates #42862.
Change-Id: Ibc5cd1d82d97b9c2f887d7f3565f2fa70207c8b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/273826
Run-TryBot: Jason A. Donenfeld
TryBot-Result: Go Bot
Reviewed-by: Brad Fitzpatrick
Trust: Jason A. Donenfeld
---
src/runtime/pprof/pprof_test.go | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 43307aeab9..b807072485 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -286,6 +286,10 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
broken = true
}
+ case "windows":
+ if runtime.GOARCH == "arm" {
+ broken = true // See https://golang.org/issues/42862
+ }
}
maxDuration := 5 * time.Second
From e5da18df52e3f81534d7cdb6920cf993b5f079d2 Mon Sep 17 00:00:00 2001
From: "Joshua M. Clulow"
Date: Sun, 29 Nov 2020 17:18:51 -0800
Subject: [PATCH 09/50] os/exec: constrain thread usage in leaked descriptor
test on illumos
On illumos systems, libc can under some conditions make use of files
from /proc. In the case of this test, the creation of new threads was
(in the target thread) causing libc to open and close
"/proc/self/lwp/5/lwpname" to set the thread name, which raced with the
leaking descriptor check (see detailed analysis in #42431).
This change requests that the Go runtime use less threads in the child
process used to check for leaked descriptors, without just disabling the
test. After a thousand repeated trials, the test no longer fails on
illumos.
Fixes #42431.
Change-Id: Iefda26134fc91f7cb205754676e9845d9b7205cc
Reviewed-on: https://go-review.googlesource.com/c/go/+/273966
Reviewed-by: Brad Fitzpatrick
Reviewed-by: Ian Lance Taylor
Trust: Brad Fitzpatrick
Run-TryBot: Brad Fitzpatrick
TryBot-Result: Go Bot
---
src/os/exec/exec_test.go | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index cd3d759ebc..fc49b8a332 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -691,6 +691,18 @@ func TestExtraFiles(t *testing.T) {
c.Stdout = &stdout
c.Stderr = &stderr
c.ExtraFiles = []*os.File{tf}
+ if runtime.GOOS == "illumos" {
+ // Some facilities in illumos are implemented via access
+ // to /proc by libc; such accesses can briefly occupy a
+ // low-numbered fd. If this occurs concurrently with the
+ // test that checks for leaked descriptors, the check can
+ // become confused and report a spurious leaked descriptor.
+ // (See issue #42431 for more detailed analysis.)
+ //
+ // Attempt to constrain the use of additional threads in the
+ // child process to make this test less flaky:
+ c.Env = append(os.Environ(), "GOMAXPROCS=1")
+ }
err = c.Run()
if err != nil {
t.Fatalf("Run: %v\n--- stdout:\n%s--- stderr:\n%s", err, stdout.Bytes(), stderr.Bytes())
From 294c214ccac877be8d8ce16b0302434a15a2476b Mon Sep 17 00:00:00 2001
From: KimMachineGun
Date: Fri, 20 Nov 2020 08:32:06 +0000
Subject: [PATCH 10/50] runtime: gofmt
CL 268578 was not formatted properly.
Change-Id: I08d2fc691e4f90a38d8165344c135b7b4f73b339
GitHub-Last-Rev: 6183bb063962ef4bf5a6050c1f5108976108ff42
GitHub-Pull-Request: golang/go#42736
Reviewed-on: https://go-review.googlesource.com/c/go/+/271807
Reviewed-by: Alberto Donizetti
Reviewed-by: Michael Pratt
Trust: Michael Pratt
Trust: Alberto Donizetti
Run-TryBot: Michael Pratt
---
src/runtime/crash_unix_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runtime/crash_unix_test.go b/src/runtime/crash_unix_test.go
index c50d62d552..ebbdbfe5b9 100644
--- a/src/runtime/crash_unix_test.go
+++ b/src/runtime/crash_unix_test.go
@@ -244,7 +244,7 @@ func TestPanicSystemstack(t *testing.T) {
// we don't have a way to know when it is fully blocked, sleep a bit to
// make us less likely to lose the race and signal before the child
// blocks.
- time.Sleep(100*time.Millisecond)
+ time.Sleep(100 * time.Millisecond)
// Send SIGQUIT.
if err := cmd.Process.Signal(syscall.SIGQUIT); err != nil {
From c193279e2c9e62e8ddc0893484251b4411461d62 Mon Sep 17 00:00:00 2001
From: Chris Waldon
Date: Sun, 29 Nov 2020 23:58:29 +0000
Subject: [PATCH 11/50] os: return proper user directories on iOS
Separating iOS into its own runtime constant broke the logic
here to derive the correct home, cache, and config directories
on iOS devices.
Fixes #42878
Change-Id: Ie4ff57895fcc34b0a9af45554ea3a346447d2e7a
GitHub-Last-Rev: 5e74e64917fa46e9c6e0d963cab5194ab89e2f64
GitHub-Pull-Request: golang/go#42879
Reviewed-on: https://go-review.googlesource.com/c/go/+/273947
Reviewed-by: Cherry Zhang
Trust: Emmanuel Odeke
---
src/os/file.go | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/os/file.go b/src/os/file.go
index 835d44ab8c..420e62ef2c 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -406,7 +406,7 @@ func UserCacheDir() (string, error) {
return "", errors.New("%LocalAppData% is not defined")
}
- case "darwin":
+ case "darwin", "ios":
dir = Getenv("HOME")
if dir == "" {
return "", errors.New("$HOME is not defined")
@@ -457,7 +457,7 @@ func UserConfigDir() (string, error) {
return "", errors.New("%AppData% is not defined")
}
- case "darwin":
+ case "darwin", "ios":
dir = Getenv("HOME")
if dir == "" {
return "", errors.New("$HOME is not defined")
@@ -505,10 +505,8 @@ func UserHomeDir() (string, error) {
switch runtime.GOOS {
case "android":
return "/sdcard", nil
- case "darwin":
- if runtime.GOARCH == "arm64" {
- return "/", nil
- }
+ case "ios":
+ return "/", nil
}
return "", errors.New(enverr + " is not defined")
}
From d6abf298cf1ef56dc8cbec2ee9a18c071bb6eb3c Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Sat, 28 Nov 2020 17:51:18 -0800
Subject: [PATCH 12/50] test: recognize new gofrontend error message
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As of https://golang.org/cl/273886:
fixedbugs/bug340.go:15:18: error: reference to method ‘x’ in interface with no methods
For golang/go#10700
Change-Id: Id29eb0e34bbb524117614229c4c27cfd17dae286
Reviewed-on: https://go-review.googlesource.com/c/go/+/273887
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Cherry Zhang
---
test/fixedbugs/bug340.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/fixedbugs/bug340.go b/test/fixedbugs/bug340.go
index 118bbacc22..8c543c98d9 100644
--- a/test/fixedbugs/bug340.go
+++ b/test/fixedbugs/bug340.go
@@ -12,6 +12,6 @@ func main() {
var x interface{}
switch t := x.(type) {
case 0: // ERROR "type"
- t.x = 1 // ERROR "type interface \{\}|reference to undefined field or method"
+ t.x = 1 // ERROR "type interface \{\}|reference to undefined field or method|interface with no methods"
}
}
From a45e12fd4bd2cc4d5970f374499b603bfb793891 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Sat, 28 Nov 2020 18:14:38 -0800
Subject: [PATCH 13/50] test: recognize gofrontend error messages
shift1.go:76:16: error: shift of non-integer operand
shift1.go:77:16: error: shift of non-integer operand
Change-Id: I48584c0b01f9f6912a93b5f9bba55b5803fbeced
Reviewed-on: https://go-review.googlesource.com/c/go/+/273888
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Cherry Zhang
---
test/shift1.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/shift1.go b/test/shift1.go
index df0c032cd5..d6a6c38839 100644
--- a/test/shift1.go
+++ b/test/shift1.go
@@ -73,8 +73,8 @@ func _() {
// non constants arguments trigger a different path
f2 := 1.2
s2 := "hi"
- _ = f2 << 2 // ERROR "shift of type float64"
- _ = s2 << 2 // ERROR "shift of type string"
+ _ = f2 << 2 // ERROR "shift of type float64|non-integer"
+ _ = s2 << 2 // ERROR "shift of type string|non-integer"
}
// shifts in comparisons w/ untyped operands
From 848dff6dda4d38d3d2e9ab128954f50d085d9313 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Sat, 28 Nov 2020 19:10:57 -0800
Subject: [PATCH 14/50] test: update gofrontend expected errors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This matches the error messages after CL 273890.
syntax/semi4.go:11:9: error: unexpected semicolon or newline, expecting ‘{’ after for clause
syntax/semi4.go:10:13: error: reference to undefined name ‘x’
syntax/semi4.go:12:17: error: reference to undefined name ‘z’
Change-Id: Ic88ff6e27d50bf70f5b2114383b84c42c0682f39
Reviewed-on: https://go-review.googlesource.com/c/go/+/273891
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Cherry Zhang
---
test/syntax/semi4.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/syntax/semi4.go b/test/syntax/semi4.go
index f21431b3f5..08c354751b 100644
--- a/test/syntax/semi4.go
+++ b/test/syntax/semi4.go
@@ -8,5 +8,5 @@ package main
func main() {
for x // GCCGO_ERROR "undefined"
- { // ERROR "unexpected {, expecting for loop condition"
- z
+ { // ERROR "unexpected {, expecting for loop condition|expecting .*{.* after for clause"
+ z // GCCGO_ERROR "undefined"
From 7b192f33cf8e1391769353687e5b698d9f677109 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Mart=C3=AD?=
Date: Mon, 23 Nov 2020 05:47:51 +0000
Subject: [PATCH 15/50] cmd/go: remove trailing whitespace from test script
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Noticed while skimming through recent master commits.
Change-Id: I42a99ea7d71c05fc5b6107627105375a21920f5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/271990
Trust: Daniel Martí
Reviewed-by: Jay Conrod
Reviewed-by: Bryan C. Mills
Run-TryBot: Bryan C. Mills
TryBot-Result: Go Bot
---
src/cmd/go/testdata/script/mod_gonoproxy.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cmd/go/testdata/script/mod_gonoproxy.txt b/src/cmd/go/testdata/script/mod_gonoproxy.txt
index 546605da21..204786969f 100644
--- a/src/cmd/go/testdata/script/mod_gonoproxy.txt
+++ b/src/cmd/go/testdata/script/mod_gonoproxy.txt
@@ -21,7 +21,7 @@ go get -d rsc.io/quote
# Download .info files needed for 'go list -m all' later.
# TODO(#42723): either 'go list -m' should not read these files,
# or 'go get' and 'go mod tidy' should download them.
-go list -m all
+go list -m all
stdout '^golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c$'
# When GOPROXY is not empty but contains no entries, an error should be reported.
From 4f42a9b76b2ca2c261a4afec986b9518a61626ee Mon Sep 17 00:00:00 2001
From: Andy Pan
Date: Sat, 21 Nov 2020 14:48:26 +0800
Subject: [PATCH 16/50] net: add note about disabling loopback in
ListenMulticastUDP()
Fixes #41752
Change-Id: I83520d2303e5fd2e5f6329f092b40e73c13771a1
Reviewed-on: https://go-review.googlesource.com/c/go/+/271908
Reviewed-by: Ian Lance Taylor
Trust: Dmitri Shuralyov
---
src/net/udpsock.go | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/net/udpsock.go b/src/net/udpsock.go
index ec2bcfa607..571e099abd 100644
--- a/src/net/udpsock.go
+++ b/src/net/udpsock.go
@@ -259,6 +259,9 @@ func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
// ListenMulticastUDP is just for convenience of simple, small
// applications. There are golang.org/x/net/ipv4 and
// golang.org/x/net/ipv6 packages for general purpose uses.
+//
+// Note that ListenMulticastUDP will set the IP_MULTICAST_LOOP socket option
+// to 0 under IPPROTO_IP, to disable loopback of multicast packets.
func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
switch network {
case "udp", "udp4", "udp6":
From d2b436d95d99cb3ff587bf0d2e893a8d027f8292 Mon Sep 17 00:00:00 2001
From: Jay Conrod
Date: Mon, 30 Nov 2020 15:46:33 -0500
Subject: [PATCH 17/50] cmd/go: fix infinite loop in modload.keepSums
Fixes #42891
Change-Id: I0cce4204a1c4959b896188a2ab3719c0507f95e6
Reviewed-on: https://go-review.googlesource.com/c/go/+/274172
Run-TryBot: Jay Conrod
TryBot-Result: Go Bot
Reviewed-by: Michael Matloob
Reviewed-by: Bryan C. Mills
Trust: Jay Conrod
---
src/cmd/go/internal/modload/init.go | 2 +-
.../go/testdata/script/mod_import_issue42891.txt | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
create mode 100644 src/cmd/go/testdata/script/mod_import_issue42891.txt
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index a9b77c82b3..1c31a5f90a 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -1018,7 +1018,7 @@ func keepSums(addDirect bool) map[module.Version]bool {
}
}
for _, pkg := range loaded.pkgs {
- if pkg.testOf != nil || pkg.inStd {
+ if pkg.testOf != nil || pkg.inStd || module.CheckImportPath(pkg.path) != nil {
continue
}
for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) {
diff --git a/src/cmd/go/testdata/script/mod_import_issue42891.txt b/src/cmd/go/testdata/script/mod_import_issue42891.txt
new file mode 100644
index 0000000000..a78cab29ba
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_import_issue42891.txt
@@ -0,0 +1,14 @@
+# If an import declaration is an absolute path, most commands should report
+# an error instead of going into an infinite loop.
+# Verifies golang.org/issue/42891.
+go list .
+stdout '^m$'
+
+-- go.mod --
+module m
+
+go 1.16
+-- m.go --
+package m
+
+import "/"
From 7f688d18c0ae6df3e895d21799b8ece7d5941293 Mon Sep 17 00:00:00 2001
From: Cherry Zhang
Date: Fri, 27 Nov 2020 00:42:41 -0500
Subject: [PATCH 18/50] runtime: mlock signal stack on macOS/ARM64
Apparently, the macOS ARM64 kernel has a bug where when a signal
arrives and the signal stack is not currently faulted in, it may
kill the program with a SIGILL. Work around it by mlock the
signal stacks.
Fixes #42774.
Change-Id: I99a4b3fdb6d8af1c945725ddc2c25568d81c510a
Reviewed-on: https://go-review.googlesource.com/c/go/+/273686
Trust: Cherry Zhang
Reviewed-by: Austin Clements
Run-TryBot: Austin Clements
TryBot-Result: Go Bot
---
src/runtime/os_darwin.go | 6 ++++++
src/runtime/sys_darwin.go | 8 ++++++++
src/runtime/sys_darwin_amd64.s | 3 +++
src/runtime/sys_darwin_arm64.s | 6 ++++++
4 files changed, 23 insertions(+)
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index 3f5bb7cf96..52f3cd1fef 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -283,6 +283,12 @@ func libpreinit() {
func mpreinit(mp *m) {
mp.gsignal = malg(32 * 1024) // OS X wants >= 8K
mp.gsignal.m = mp
+ if GOOS == "darwin" && GOARCH == "arm64" {
+ // mlock the signal stack to work around a kernel bug where it may
+ // SIGILL when the signal stack is not faulted in while a signal
+ // arrives. See issue 42774.
+ mlock(unsafe.Pointer(mp.gsignal.stack.hi-physPageSize), physPageSize)
+ }
}
// Called to initialize a new m (including the bootstrap m).
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index a7983be2ef..c63ba8c6cd 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -226,6 +226,13 @@ func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
}
func madvise_trampoline()
+//go:nosplit
+//go:cgo_unsafe_args
+func mlock(addr unsafe.Pointer, n uintptr) {
+ libcCall(unsafe.Pointer(funcPC(mlock_trampoline)), unsafe.Pointer(&addr))
+}
+func mlock_trampoline()
+
//go:nosplit
//go:cgo_unsafe_args
func read(fd int32, p unsafe.Pointer, n int32) int32 {
@@ -465,6 +472,7 @@ func setNonblock(fd int32) {
//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_error __error "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
index 129e1e1a96..9b5b23901d 100644
--- a/src/runtime/sys_darwin_amd64.s
+++ b/src/runtime/sys_darwin_amd64.s
@@ -105,6 +105,9 @@ TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
POPQ BP
RET
+TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0
+ UNDEF // unimplemented
+
GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
index 88cdb281d4..9d4d116c50 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -120,6 +120,12 @@ TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0
BL libc_madvise(SB)
RET
+TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0
+ MOVD 8(R0), R1 // arg 2 len
+ MOVD 0(R0), R0 // arg 1 addr
+ BL libc_mlock(SB)
+ RET
+
TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
MOVD 8(R0), R1 // arg 2 new
MOVD 16(R0), R2 // arg 3 old
From 0ecf7696335a3aade9e41843acfd5ab188d2511f Mon Sep 17 00:00:00 2001
From: Cuong Manh Le
Date: Thu, 26 Nov 2020 23:28:11 +0700
Subject: [PATCH 19/50] cmd/compile: do not mark OpSP, OpSB pos for debugging
Fixes #42801
Change-Id: I2080ecacc109479f5820035401ce2b26d72e2ef2
Reviewed-on: https://go-review.googlesource.com/c/go/+/273506
Trust: Cuong Manh Le
Run-TryBot: Cuong Manh Le
TryBot-Result: Go Bot
Reviewed-by: Cherry Zhang
Reviewed-by: David Chase
---
src/cmd/compile/internal/ssa/func.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go
index ec2c67c1fa..e6f899a2c7 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -790,10 +790,10 @@ func (f *Func) spSb() (sp, sb *Value) {
}
}
if sb == nil {
- sb = f.Entry.NewValue0(initpos, OpSB, f.Config.Types.Uintptr)
+ sb = f.Entry.NewValue0(initpos.WithNotStmt(), OpSB, f.Config.Types.Uintptr)
}
if sp == nil {
- sp = f.Entry.NewValue0(initpos, OpSP, f.Config.Types.Uintptr)
+ sp = f.Entry.NewValue0(initpos.WithNotStmt(), OpSP, f.Config.Types.Uintptr)
}
return
}
From f3741bdf7cab5fc8254bebce00479c0168ace86c Mon Sep 17 00:00:00 2001
From: Roland Shoemaker
Date: Mon, 30 Nov 2020 16:32:41 -0800
Subject: [PATCH 20/50] doc/go1.16: add crypto/x509 note about Verify on
Windows
Updates #42897
Change-Id: Ice25922475405aca3cf2cb1c163462f223ede736
Reviewed-on: https://go-review.googlesource.com/c/go/+/274239
Trust: Roland Shoemaker
Reviewed-by: Dmitri Shuralyov
---
doc/go1.16.html | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 6e371b9617..71cd7e259e 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -416,7 +416,9 @@ Do not send CLs removing the interior tags from such phrases.
- TODO: https://golang.org/cl/257257: return additional chains from Verify on Windows
+ On Windows, Certificate.Verify
+ will now return all certificate chains that are built by the platform
+ certificate verifier, instead of just the highest ranked chain.
From a36ba090fd647e741668629527e25c657c40f8f3 Mon Sep 17 00:00:00 2001
From: Joel Sing
Date: Fri, 27 Nov 2020 02:06:08 +1100
Subject: [PATCH 21/50] cmd/link/internal/amd64: always generate R_X86_64_PLT32
for SDYNIMPORT calls
Currently, in the non-DynlinkingGo case with external linking, we generate a
R_X86_64_GOTPCREL relocation for the imported symbol. This results in the
external linker turning this into a R_X86_64_GLOB_DAT relocation, rather
than a R_X86_64_JUMP_SLOT. Always generate R_X86_64_PLT32 for SDYNIMPORT
calls so that these calls work correctly.
Update #36435
Fixes #42671
Change-Id: I8a28884b7853cb4135053ed817bedc919482f4ad
Reviewed-on: https://go-review.googlesource.com/c/go/+/270377
Trust: Joel Sing
Run-TryBot: Cherry Zhang
Reviewed-by: Cherry Zhang
---
src/cmd/link/internal/amd64/asm.go | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index 360c5338ba..2d09a6160a 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -413,11 +413,7 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
case objabi.R_CALL:
if siz == 4 {
if ldr.SymType(r.Xsym) == sym.SDYNIMPORT {
- if ctxt.DynlinkingGo() {
- out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
- } else {
- out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
- }
+ out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
} else {
out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
}
From f5978a09589badb927d3aa96998fc785524cae02 Mon Sep 17 00:00:00 2001
From: Joel Sing
Date: Sun, 22 Nov 2020 11:52:55 +1100
Subject: [PATCH 22/50] cmd/internal/obj/riscv: add tests for BGE/BGEU/BLT/BLTU
Add tests for BGE/BGEU/BLT/BLTU branch instructions. Also add pure Go variants
of these to ensure that the test data, Go and assembly all match up.
Change-Id: I84c68605e116a4e57f6c5c765bf0aaecab84b675
Reviewed-on: https://go-review.googlesource.com/c/go/+/271913
Trust: Joel Sing
Reviewed-by: Quey-Liang Kao
Reviewed-by: Cherry Zhang
Run-TryBot: Cherry Zhang
TryBot-Result: Go Bot
---
.../riscv/testdata/testbranch/branch_test.go | 54 ++++++++++++++++++-
.../riscv/testdata/testbranch/branch_test.s | 44 +++++++++++++++
2 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go
index 803ba8c77c..5412577a05 100644
--- a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go
+++ b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go
@@ -11,6 +11,8 @@ import (
)
func testBEQZ(a int64) (r bool)
+func testBGE(a, b int64) (r bool)
+func testBGEU(a, b int64) (r bool)
func testBGEZ(a int64) (r bool)
func testBGT(a, b int64) (r bool)
func testBGTU(a, b int64) (r bool)
@@ -18,6 +20,8 @@ func testBGTZ(a int64) (r bool)
func testBLE(a, b int64) (r bool)
func testBLEU(a, b int64) (r bool)
func testBLEZ(a int64) (r bool)
+func testBLT(a, b int64) (r bool)
+func testBLTU(a, b int64) (r bool)
func testBLTZ(a int64) (r bool)
func testBNEZ(a int64) (r bool)
@@ -29,6 +33,16 @@ func TestBranchCondition(t *testing.T) {
fn func(a, b int64) bool
want bool
}{
+ {"BGE", 0, 1, testBGE, false},
+ {"BGE", 0, 0, testBGE, true},
+ {"BGE", 0, -1, testBGE, true},
+ {"BGE", -1, 0, testBGE, false},
+ {"BGE", 1, 0, testBGE, true},
+ {"BGEU", 0, 1, testBGEU, false},
+ {"BGEU", 0, 0, testBGEU, true},
+ {"BGEU", 0, -1, testBGEU, false},
+ {"BGEU", -1, 0, testBGEU, true},
+ {"BGEU", 1, 0, testBGEU, true},
{"BGT", 0, 1, testBGT, true},
{"BGT", 0, 0, testBGT, false},
{"BGT", 0, -1, testBGT, false},
@@ -48,11 +62,49 @@ func TestBranchCondition(t *testing.T) {
{"BLEU", 0, 0, testBLEU, true},
{"BLEU", -1, 0, testBLEU, true},
{"BLEU", 1, 0, testBLEU, true},
+ {"BLT", 0, 1, testBLT, true},
+ {"BLT", 0, -1, testBLT, false},
+ {"BLT", 0, 0, testBLT, false},
+ {"BLT", -1, 0, testBLT, true},
+ {"BLT", 1, 0, testBLT, false},
+ {"BLTU", 0, 1, testBLTU, true},
+ {"BLTU", 0, -1, testBLTU, true},
+ {"BLTU", 0, 0, testBLTU, false},
+ {"BLTU", -1, 0, testBLTU, false},
+ {"BLTU", 1, 0, testBLTU, false},
}
for _, test := range tests {
t.Run(test.ins, func(t *testing.T) {
+ var fn func(a, b int64) bool
+ switch test.ins {
+ case "BGE":
+ fn = func(a, b int64) bool { return a >= b }
+ case "BGEU":
+ fn = func(a, b int64) bool { return uint64(a) >= uint64(b) }
+ case "BGT":
+ // TODO: Currently reversed.
+ fn = func(a, b int64) bool { return b > a }
+ case "BGTU":
+ // TODO: Currently reversed.
+ fn = func(a, b int64) bool { return uint64(b) > uint64(a) }
+ case "BLE":
+ // TODO: Currently reversed.
+ fn = func(a, b int64) bool { return b <= a }
+ case "BLEU":
+ // TODO: Currently reversed.
+ fn = func(a, b int64) bool { return uint64(b) <= uint64(a) }
+ case "BLT":
+ fn = func(a, b int64) bool { return a < b }
+ case "BLTU":
+ fn = func(a, b int64) bool { return uint64(a) < uint64(b) }
+ default:
+ t.Fatalf("Unknown instruction %q", test.ins)
+ }
+ if got := fn(test.a, test.b); got != test.want {
+ t.Errorf("Go %v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want)
+ }
if got := test.fn(test.a, test.b); got != test.want {
- t.Errorf("%v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want)
+ t.Errorf("Assembly %v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want)
}
})
}
diff --git a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s
index 6cff235848..8dd6f563af 100644
--- a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s
+++ b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s
@@ -16,6 +16,28 @@ b:
MOV X6, r+8(FP)
RET
+// func testBGE(a, b int64) (r bool)
+TEXT ·testBGE(SB),NOSPLIT,$0-0
+ MOV a+0(FP), X5
+ MOV b+8(FP), X6
+ MOV $1, X7
+ BGE X5, X6, b
+ MOV $0, X7
+b:
+ MOV X7, r+16(FP)
+ RET
+
+// func testBGEU(a, b int64) (r bool)
+TEXT ·testBGEU(SB),NOSPLIT,$0-0
+ MOV a+0(FP), X5
+ MOV b+8(FP), X6
+ MOV $1, X7
+ BGEU X5, X6, b
+ MOV $0, X7
+b:
+ MOV X7, r+16(FP)
+ RET
+
// func testBGEZ(a int64) (r bool)
TEXT ·testBGEZ(SB),NOSPLIT,$0-0
MOV a+0(FP), X5
@@ -90,6 +112,28 @@ b:
MOV X6, r+8(FP)
RET
+// func testBLT(a, b int64) (r bool)
+TEXT ·testBLT(SB),NOSPLIT,$0-0
+ MOV a+0(FP), X5
+ MOV b+8(FP), X6
+ MOV $1, X7
+ BLT X5, X6, b
+ MOV $0, X7
+b:
+ MOV X7, r+16(FP)
+ RET
+
+// func testBLTU(a, b int64) (r bool)
+TEXT ·testBLTU(SB),NOSPLIT,$0-0
+ MOV a+0(FP), X5
+ MOV b+8(FP), X6
+ MOV $1, X7
+ BLTU X5, X6, b
+ MOV $0, X7
+b:
+ MOV X7, r+16(FP)
+ RET
+
// func testBLTZ(a int64) (r bool)
TEXT ·testBLTZ(SB),NOSPLIT,$0-0
MOV a+0(FP), X5
From dd4a52c2a588c57edc76cb0a414ae6f2e5bf5d52 Mon Sep 17 00:00:00 2001
From: Jay Conrod
Date: Tue, 1 Dec 2020 11:10:40 -0500
Subject: [PATCH 23/50] doc/go1.16: add multiple release notes for the go
command
Added notes for:
* go test -c and -i flags used with unknown flags
* GO111MODULE=on by default
* GOVCS
* Dropped requirements on excluded versions
Removed TODOs for documentation on the retract directive and
'go install pkg@version'. These pages will be written after the beta.
Change-Id: Ic9877a62f908be177a6035a039b72e969e7b7f22
Reviewed-on: https://go-review.googlesource.com/c/go/+/274438
Trust: Jay Conrod
Reviewed-by: Bryan C. Mills
Run-TryBot: Bryan C. Mills
TryBot-Result: Go Bot
---
doc/go1.16.html | 57 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 41 insertions(+), 16 deletions(-)
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 71cd7e259e..145f920aab 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -80,17 +80,16 @@ Do not send CLs removing the interior tags from such phrases.
Go command
-
- TODO
-
-
-
-
-
-
-
Modules
+
+ Module-aware mode is enabled by default, regardless of whether a
+ go.mod file is present in the current working directory or a
+ parent directory. Specifically, the GO111MODULE environment
+ variable now defaults to on. To switch to the previous behavior,
+ set GO111MODULE to auto.
+
+
Build commands like gobuild and gotest no longer modify go.mod and go.sum
@@ -107,9 +106,7 @@ Do not send CLs removing the interior tags from such phrases.
install to build and install packages in module-aware mode,
ignoring the go.mod file in the current directory or any parent
directory, if there is one. This is useful for installing executables without
- affecting the dependencies of the main module.
- TODO: write and link to section in golang.org/ref/mod
- TODO: write and link to blog post
+ affecting the dependencies of the main module.
@@ -127,8 +124,6 @@ Do not send CLs removing the interior tags from such phrases.
to indicate that certain published versions of the module should not be used
by other modules. A module author may retract a version after a severe problem
is discovered or if the version was published unintentionally.
- TODO: write and link to section in golang.org/ref/mod
- TODO: write and link to tutorial or blog post
@@ -138,6 +133,14 @@ Do not send CLs removing the interior tags from such phrases.
resolving missing packages.
+
+ The go command now ignores requirements on module versions
+ excluded by exclude directives in the main module. Previously,
+ the go command used the next version higher than an excluded
+ version, but that version could change over time, resulting in
+ non-reproducible builds.
+
+
gotest
@@ -150,6 +153,15 @@ Do not send CLs removing the interior tags from such phrases.
that is still considered to be a passing test.
+
+ gotest reports an error when the -c
+ or -i flags are used together with unknown flags. Normally,
+ unknown flags are passed to tests, but when -c or -i
+ are used, tests are not run.
+
+
+
goget
+
The goget-insecure flag is
deprecated and will be removed in a future version. This flag permits
@@ -161,8 +173,6 @@ Do not send CLs removing the interior tags from such phrases.
See gohelpenvironment for details.
-
goget
-
gogetexample.com/mod@patch now
requires that some version of example.com/mod already be
@@ -171,6 +181,21 @@ Do not send CLs removing the interior tags from such phrases.
to patch even newly-added dependencies.)
+
GOVCS environment variable
+
+
+ GOVCS is a new environment variable that limits which version
+ control tools the go command may use to download source code.
+ This mitigates security issues with tools that are typically used in trusted,
+ authenticated environments. By default, git and hg
+ may be used to download code from any repository. svn,
+ bzr, and fossil may only be used to download code
+ from repositories with module paths or package paths matching patterns in
+ the GOPRIVATE environment variable. See
+ go
+ helpvcs for details.
+
+
The all pattern
From ae3bfba6269fcc75aced2418b870ba2706b0d35f Mon Sep 17 00:00:00 2001
From: Alberto Donizetti
Date: Tue, 1 Dec 2020 13:54:53 +0100
Subject: [PATCH 24/50] doc/go1.16: add text/template changes to release notes
For #40700
Fixes #42914
Change-Id: I673d86a946c362e28bfbf35fab2c60ebfbd8bda2
Reviewed-on: https://go-review.googlesource.com/c/go/+/274472
Trust: Alberto Donizetti
Reviewed-by: Dmitri Shuralyov
---
doc/go1.16.html | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 145f920aab..3545632ea4 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -699,8 +699,9 @@ Do not send CLs removing the interior tags from such phrases.
From 212d385a2f723a8dd5e7d2e83efb478ddd139349 Mon Sep 17 00:00:00 2001
From: Michael Fraenkel
Date: Sat, 26 Sep 2020 09:20:16 -0600
Subject: [PATCH 26/50] net/http: ignore connection closes once done with the
connection
Once the connection is put back into the idle pool, the request should
not take any action if the connection is closed.
Fixes #41600
Change-Id: I5e4ddcdc03cd44f5197ecfbe324638604961de84
Reviewed-on: https://go-review.googlesource.com/c/go/+/257818
Reviewed-by: Brad Fitzpatrick
Trust: Damien Neil
---
src/net/http/transport.go | 13 ++++++---
src/net/http/transport_test.go | 51 ++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 79b1fc7681..8de0f3a6a0 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -2599,6 +2599,7 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
var respHeaderTimer <-chan time.Time
cancelChan := req.Request.Cancel
ctxDoneChan := req.Context().Done()
+ pcClosed := pc.closech
for {
testHookWaitResLoop()
select {
@@ -2618,11 +2619,15 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
defer timer.Stop() // prevent leaks
respHeaderTimer = timer.C
}
- case <-pc.closech:
- if debugRoundTrip {
- req.logf("closech recv: %T %#v", pc.closed, pc.closed)
+ case <-pcClosed:
+ pcClosed = nil
+ // check if we are still using the connection
+ if pc.t.replaceReqCanceler(req.cancelKey, nil) {
+ if debugRoundTrip {
+ req.logf("closech recv: %T %#v", pc.closed, pc.closed)
+ }
+ return nil, pc.mapRoundTripError(req, startBytesWritten, pc.closed)
}
- return nil, pc.mapRoundTripError(req, startBytesWritten, pc.closed)
case <-respHeaderTimer:
if debugRoundTrip {
req.logf("timeout waiting for response headers.")
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 9086507d57..f22b798035 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -6433,3 +6433,54 @@ func TestErrorWriteLoopRace(t *testing.T) {
testTransportRace(req)
}
}
+
+// Issue 41600
+// 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")
+ }
+ ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
+ w.Header().Add("Content-Length", "0")
+ }))
+ defer ts.Close()
+
+ client := ts.Client()
+ transport := client.Transport.(*Transport)
+ transport.MaxIdleConns = 1
+ transport.MaxConnsPerHost = 1
+
+ var wg sync.WaitGroup
+
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+
+ 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()
+ }
+ }
+ }()
+ }
+
+ 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 {
+ res.Body.Close()
+ }
+ }
+
+ cancel()
+ wg.Wait()
+}
From 50b16f9de590822a04ec8d6cbac476366c1bde32 Mon Sep 17 00:00:00 2001
From: Anmol Sethi
Date: Sat, 24 Oct 2020 00:40:41 +0000
Subject: [PATCH 27/50] net/http: allow upgrading non keepalive connections
If one was using http.Transport with DisableKeepAlives and trying
to upgrade a connection against net/http's Server, the Server
would not allow a "Connection: Upgrade" header to be written
and instead override it to "Connection: Close" which would
break the handshake.
This change ensures net/http's Server does not override the
connection header for successful protocol switch responses.
Fixes #36381.
Change-Id: I882aad8539e6c87ff5f37c20e20b3a7fa1a30357
GitHub-Last-Rev: dc0de83201dc26236527b68bd49dffc53dd0389b
GitHub-Pull-Request: golang/go#36382
Reviewed-on: https://go-review.googlesource.com/c/go/+/213277
Trust: Emmanuel Odeke
Trust: Brad Fitzpatrick
Reviewed-by: Brad Fitzpatrick
---
src/net/http/response.go | 16 ++++++++----
src/net/http/serve_test.go | 53 ++++++++++++++++++++++++++++++++++++++
src/net/http/server.go | 8 +++++-
3 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/src/net/http/response.go b/src/net/http/response.go
index 72812f0642..b95abae646 100644
--- a/src/net/http/response.go
+++ b/src/net/http/response.go
@@ -352,10 +352,16 @@ func (r *Response) bodyIsWritable() bool {
return ok
}
-// isProtocolSwitch reports whether r is a response to a successful
-// protocol upgrade.
+// isProtocolSwitch reports whether the response code and header
+// indicate a successful protocol upgrade response.
func (r *Response) isProtocolSwitch() bool {
- return r.StatusCode == StatusSwitchingProtocols &&
- r.Header.Get("Upgrade") != "" &&
- httpguts.HeaderValuesContainsToken(r.Header["Connection"], "Upgrade")
+ return isProtocolSwitchResponse(r.StatusCode, r.Header)
+}
+
+// isProtocolSwitchResponse reports whether the response code and
+// response header indicate a successful protocol upgrade response.
+func isProtocolSwitchResponse(code int, h Header) bool {
+ return code == StatusSwitchingProtocols &&
+ h.Get("Upgrade") != "" &&
+ httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade")
}
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index ba54b31a29..b1bf8e6c5e 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -6448,3 +6448,56 @@ func BenchmarkResponseStatusLine(b *testing.B) {
}
})
}
+func TestDisableKeepAliveUpgrade(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in short mode")
+ }
+
+ setParallel(t)
+ defer afterTest(t)
+
+ s := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ w.Header().Set("Connection", "Upgrade")
+ w.Header().Set("Upgrade", "someProto")
+ w.WriteHeader(StatusSwitchingProtocols)
+ c, _, err := w.(Hijacker).Hijack()
+ if err != nil {
+ return
+ }
+ defer c.Close()
+
+ io.Copy(c, c)
+ }))
+ s.Config.SetKeepAlivesEnabled(false)
+ s.Start()
+ defer s.Close()
+
+ cl := s.Client()
+ cl.Transport.(*Transport).DisableKeepAlives = true
+
+ resp, err := cl.Get(s.URL)
+ if err != nil {
+ t.Fatalf("failed to perform request: %v", err)
+ }
+ defer resp.Body.Close()
+
+ rwc, ok := resp.Body.(io.ReadWriteCloser)
+ if !ok {
+ t.Fatalf("Response.Body is not a io.ReadWriteCloser: %T", resp.Body)
+ }
+
+ _, err = rwc.Write([]byte("hello"))
+ if err != nil {
+ t.Fatalf("failed to write to body: %v", err)
+ }
+
+ b := make([]byte, 5)
+ _, err = io.ReadFull(rwc, b)
+ if err != nil {
+ t.Fatalf("failed to read from body: %v", err)
+ }
+
+ if string(b) != "hello" {
+ t.Fatalf("unexpected value read from body:\ngot: %q\nwant: %q", b, "hello")
+ }
+}
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 6c7d281705..102e893d5f 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -1468,7 +1468,13 @@ func (cw *chunkWriter) writeHeader(p []byte) {
return
}
- if w.closeAfterReply && (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) {
+ // Only override the Connection header if it is not a successful
+ // protocol switch response and if KeepAlives are not enabled.
+ // See https://golang.org/issue/36381.
+ delConnectionHeader := w.closeAfterReply &&
+ (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) &&
+ !isProtocolSwitchResponse(w.status, header)
+ if delConnectionHeader {
delHeader("Connection")
if w.req.ProtoAtLeast(1, 1) {
setHeader.connection = "close"
From 933ce97bbae311b299d342c38df81165334cea37 Mon Sep 17 00:00:00 2001
From: Jay Conrod
Date: Tue, 1 Dec 2020 13:51:17 -0500
Subject: [PATCH 28/50] cmd/go: don't print deprecation notice for 'go get exe'
It's difficult for module authors to provide installation instructions
that work in both Go 1.15 and 1.16. We'll wait until 1.17 to print a
deprecation warning for installing executables with 'go get'.
Fixes #42885
Change-Id: I835b447e83e760f48fd664e8a117749e0cb59f83
Reviewed-on: https://go-review.googlesource.com/c/go/+/274552
Trust: Jay Conrod
Run-TryBot: Bryan C. Mills
Reviewed-by: Bryan C. Mills
TryBot-Result: Go Bot
---
src/cmd/go/internal/modget/get.go | 29 ++-----------------
.../script/mod_get_deprecate_install.txt | 22 --------------
2 files changed, 3 insertions(+), 48 deletions(-)
delete mode 100644 src/cmd/go/testdata/script/mod_get_deprecate_install.txt
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index ecb0142524..e5f55879ee 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -436,32 +436,9 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
work.BuildInit()
pkgs := load.PackagesForBuild(ctx, pkgPatterns)
work.InstallPackages(ctx, pkgPatterns, pkgs)
-
- haveExe := false
- for _, pkg := range pkgs {
- if pkg.Name == "main" {
- haveExe = true
- break
- }
- }
- if haveExe {
- fmt.Fprint(os.Stderr, "go get: installing executables with 'go get' in module mode is deprecated.")
- var altMsg string
- if modload.HasModRoot() {
- altMsg = `
- To adjust dependencies of the current module, use 'go get -d'.
- To install using requirements of the current module, use 'go install'.
- To install ignoring the current module, use 'go install' with a version,
- like 'go install example.com/cmd@latest'.
-`
- } else {
- altMsg = "\n\tUse 'go install pkg@version' instead.\n"
- }
- fmt.Fprint(os.Stderr, altMsg)
- fmt.Fprint(os.Stderr, "\tSee 'go help get' and 'go help install' for more information.\n")
- }
- // TODO(golang.org/issue/40276): link to HTML documentation explaining
- // what's changing and gives more examples.
+ // TODO(#40276): After Go 1.16, print a deprecation notice when building
+ // and installing main packages. 'go install pkg' or
+ // 'go install pkg@version' should be used instead.
}
if !modload.HasModRoot() {
diff --git a/src/cmd/go/testdata/script/mod_get_deprecate_install.txt b/src/cmd/go/testdata/script/mod_get_deprecate_install.txt
deleted file mode 100644
index 7f5bcad410..0000000000
--- a/src/cmd/go/testdata/script/mod_get_deprecate_install.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-[short] skip
-
-env GO111MODULE=on
-
-# 'go get' outside a module with an executable prints a deprecation message.
-go get example.com/cmd/a
-stderr '^go get: installing executables with ''go get'' in module mode is deprecated.$'
-stderr 'Use ''go install pkg@version'' instead.'
-
-
-go mod init m
-
-# 'go get' inside a module with a non-main package does not print a message.
-# This will stop building in the future, but it's the command we want to use.
-go get rsc.io/quote
-! stderr deprecated
-
-# 'go get' inside a module with an executable prints a different
-# deprecation message.
-go get example.com/cmd/a
-stderr '^go get: installing executables with ''go get'' in module mode is deprecated.$'
-stderr 'To adjust dependencies of the current module, use ''go get -d'''
From 20e251864b7caa1b863814fdf6c26280e1b669b3 Mon Sep 17 00:00:00 2001
From: Jay Conrod
Date: Tue, 1 Dec 2020 15:10:03 -0500
Subject: [PATCH 29/50] cmd: update golang.org/x/mod to v0.4.0
CL 269357 is the only difference between the pseudo-version we were
using and v0.4.0.
Change-Id: If15326bda51e04b47130429b818bfe2facaee03d
Reviewed-on: https://go-review.googlesource.com/c/go/+/274593
Trust: Jay Conrod
Run-TryBot: Jay Conrod
Reviewed-by: Bryan C. Mills
TryBot-Result: Go Bot
---
src/cmd/go.mod | 2 +-
src/cmd/go.sum | 4 ++--
src/cmd/vendor/golang.org/x/mod/semver/semver.go | 3 +++
src/cmd/vendor/modules.txt | 2 +-
4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index 6f55b2d1c8..bfee2c7f06 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -7,7 +7,7 @@ require (
github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 // indirect
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
- golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449
+ golang.org/x/mod v0.4.0
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 // indirect
golang.org/x/tools v0.0.0-20201110201400-7099162a900a
)
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index 8775b754d8..7a743d9f73 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -15,8 +15,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ=
-golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
diff --git a/src/cmd/vendor/golang.org/x/mod/semver/semver.go b/src/cmd/vendor/golang.org/x/mod/semver/semver.go
index 2988e3cf9c..4338f35177 100644
--- a/src/cmd/vendor/golang.org/x/mod/semver/semver.go
+++ b/src/cmd/vendor/golang.org/x/mod/semver/semver.go
@@ -138,6 +138,9 @@ func Compare(v, w string) int {
// Max canonicalizes its arguments and then returns the version string
// that compares greater.
+//
+// Deprecated: use Compare instead. In most cases, returning a canonicalized
+// version is not expected or desired.
func Max(v, w string) string {
v = Canonical(v)
w = Canonical(w)
diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt
index f20b6b2be1..21bd6bfe48 100644
--- a/src/cmd/vendor/modules.txt
+++ b/src/cmd/vendor/modules.txt
@@ -29,7 +29,7 @@ golang.org/x/arch/x86/x86asm
golang.org/x/crypto/ed25519
golang.org/x/crypto/ed25519/internal/edwards25519
golang.org/x/crypto/ssh/terminal
-# golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449
+# golang.org/x/mod v0.4.0
## explicit
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile
From 7430266af4f951df3c113f2c817bc600650e2295 Mon Sep 17 00:00:00 2001
From: Cherry Zhang
Date: Sat, 21 Nov 2020 21:33:18 -0500
Subject: [PATCH 30/50] cmd/internal/codesign: new package
On macOS/ARM64, the kernel requires that binaries must have a
valid code signature to run. The C toolchain code-signs the
binary at link time. We do the same.
It is more subtle for Go because we stamp the buildid after
linking. As the signature contains hashes of the entire file
(except the signature itself), we must (re)generate the signature
after stamping the buildid.
This CL adds a new codesign package, which provides
functionality to generate the code signature. It is a separate
internal package so it can be used both in the linker and by the
go command. The next CLs will add code-signing to the linker and
the go command.
Updates #38485, #42684.
Change-Id: Id46801a6665beebaab0eb413ff2e64c5b9467059
Reviewed-on: https://go-review.googlesource.com/c/go/+/272254
Trust: Cherry Zhang
Run-TryBot: Cherry Zhang
TryBot-Result: Go Bot
Reviewed-by: Austin Clements
Reviewed-by: Than McIntosh
---
src/cmd/dist/buildtool.go | 1 +
src/cmd/internal/codesign/codesign.go | 268 ++++++++++++++++++++++++++
2 files changed, 269 insertions(+)
create mode 100644 src/cmd/internal/codesign/codesign.go
diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
index 37b3d45977..e7bedfb84e 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -53,6 +53,7 @@ var bootstrapDirs = []string{
"cmd/compile/internal/x86",
"cmd/compile/internal/wasm",
"cmd/internal/bio",
+ "cmd/internal/codesign",
"cmd/internal/gcprog",
"cmd/internal/dwarf",
"cmd/internal/edit",
diff --git a/src/cmd/internal/codesign/codesign.go b/src/cmd/internal/codesign/codesign.go
new file mode 100644
index 0000000000..0517a10640
--- /dev/null
+++ b/src/cmd/internal/codesign/codesign.go
@@ -0,0 +1,268 @@
+// Copyright 2020 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 codesign provides basic functionalities for
+// ad-hoc code signing of Mach-O files.
+//
+// This is not a general tool for code-signing. It is made
+// specifically for the Go toolchain. It uses the same
+// ad-hoc signing algorithm as the Darwin linker.
+package codesign
+
+import (
+ "crypto/sha256"
+ "debug/macho"
+ "encoding/binary"
+ "io"
+)
+
+// Code signature layout.
+//
+// The code signature is a block of bytes that contains
+// a SuperBlob, which contains one or more Blobs. For ad-hoc
+// signing, a single CodeDirectory Blob suffices.
+//
+// A SuperBlob starts with its header (the binary representation
+// of the SuperBlob struct), followed by a list of (in our case,
+// one) Blobs (offset and size). A CodeDirectory Blob starts
+// with its head (the binary representation of CodeDirectory struct),
+// followed by the identifier (as a C string) and the hashes, at
+// the corresponding offsets.
+//
+// The signature data must be included in the __LINKEDIT segment.
+// In the Mach-O file header, an LC_CODE_SIGNATURE load command
+// points to the data.
+
+const (
+ pageSizeBits = 12
+ pageSize = 1 << pageSizeBits
+)
+
+const LC_CODE_SIGNATURE = 0x1d
+
+// Constants and struct layouts are from
+// https://opensource.apple.com/source/xnu/xnu-4903.270.47/osfmk/kern/cs_blobs.h
+
+const (
+ CSMAGIC_REQUIREMENT = 0xfade0c00 // single Requirement blob
+ CSMAGIC_REQUIREMENTS = 0xfade0c01 // Requirements vector (internal requirements)
+ CSMAGIC_CODEDIRECTORY = 0xfade0c02 // CodeDirectory blob
+ CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0 // embedded form of signature data
+ CSMAGIC_DETACHED_SIGNATURE = 0xfade0cc1 // multi-arch collection of embedded signatures
+
+ CSSLOT_CODEDIRECTORY = 0 // slot index for CodeDirectory
+)
+
+const (
+ CS_HASHTYPE_SHA1 = 1
+ CS_HASHTYPE_SHA256 = 2
+ CS_HASHTYPE_SHA256_TRUNCATED = 3
+ CS_HASHTYPE_SHA384 = 4
+)
+
+const (
+ CS_EXECSEG_MAIN_BINARY = 0x1 // executable segment denotes main binary
+ CS_EXECSEG_ALLOW_UNSIGNED = 0x10 // allow unsigned pages (for debugging)
+ CS_EXECSEG_DEBUGGER = 0x20 // main binary is debugger
+ CS_EXECSEG_JIT = 0x40 // JIT enabled
+ CS_EXECSEG_SKIP_LV = 0x80 // skip library validation
+ CS_EXECSEG_CAN_LOAD_CDHASH = 0x100 // can bless cdhash for execution
+ CS_EXECSEG_CAN_EXEC_CDHASH = 0x200 // can execute blessed cdhash
+)
+
+type Blob struct {
+ typ uint32 // type of entry
+ offset uint32 // offset of entry
+ // data follows
+}
+
+func (b *Blob) put(out []byte) []byte {
+ out = put32be(out, b.typ)
+ out = put32be(out, b.offset)
+ return out
+}
+
+const blobSize = 2 * 4
+
+type SuperBlob struct {
+ magic uint32 // magic number
+ length uint32 // total length of SuperBlob
+ count uint32 // number of index entries following
+ // blobs []Blob
+}
+
+func (s *SuperBlob) put(out []byte) []byte {
+ out = put32be(out, s.magic)
+ out = put32be(out, s.length)
+ out = put32be(out, s.count)
+ return out
+}
+
+const superBlobSize = 3 * 4
+
+type CodeDirectory struct {
+ magic uint32 // magic number (CSMAGIC_CODEDIRECTORY)
+ length uint32 // total length of CodeDirectory blob
+ version uint32 // compatibility version
+ flags uint32 // setup and mode flags
+ hashOffset uint32 // offset of hash slot element at index zero
+ identOffset uint32 // offset of identifier string
+ nSpecialSlots uint32 // number of special hash slots
+ nCodeSlots uint32 // number of ordinary (code) hash slots
+ codeLimit uint32 // limit to main image signature range
+ hashSize uint8 // size of each hash in bytes
+ hashType uint8 // type of hash (cdHashType* constants)
+ _pad1 uint8 // unused (must be zero)
+ pageSize uint8 // log2(page size in bytes); 0 => infinite
+ _pad2 uint32 // unused (must be zero)
+ scatterOffset uint32
+ teamOffset uint32
+ _pad3 uint32
+ codeLimit64 uint64
+ execSegBase uint64
+ execSegLimit uint64
+ execSegFlags uint64
+ // data follows
+}
+
+func (c *CodeDirectory) put(out []byte) []byte {
+ out = put32be(out, c.magic)
+ out = put32be(out, c.length)
+ out = put32be(out, c.version)
+ out = put32be(out, c.flags)
+ out = put32be(out, c.hashOffset)
+ out = put32be(out, c.identOffset)
+ out = put32be(out, c.nSpecialSlots)
+ out = put32be(out, c.nCodeSlots)
+ out = put32be(out, c.codeLimit)
+ out = put8(out, c.hashSize)
+ out = put8(out, c.hashType)
+ out = put8(out, c._pad1)
+ out = put8(out, c.pageSize)
+ out = put32be(out, c._pad2)
+ out = put32be(out, c.scatterOffset)
+ out = put32be(out, c.teamOffset)
+ out = put32be(out, c._pad3)
+ out = put64be(out, c.codeLimit64)
+ out = put64be(out, c.execSegBase)
+ out = put64be(out, c.execSegLimit)
+ out = put64be(out, c.execSegFlags)
+ return out
+}
+
+const codeDirectorySize = 13*4 + 4 + 4*8
+
+// CodeSigCmd is Mach-O LC_CODE_SIGNATURE load command.
+type CodeSigCmd struct {
+ Cmd uint32 // LC_CODE_SIGNATURE
+ Cmdsize uint32 // sizeof this command (16)
+ Dataoff uint32 // file offset of data in __LINKEDIT segment
+ Datasize uint32 // file size of data in __LINKEDIT segment
+}
+
+func FindCodeSigCmd(f *macho.File) (CodeSigCmd, bool) {
+ get32 := f.ByteOrder.Uint32
+ for _, l := range f.Loads {
+ data := l.Raw()
+ cmd := get32(data)
+ if cmd == LC_CODE_SIGNATURE {
+ return CodeSigCmd{
+ cmd,
+ get32(data[4:]),
+ get32(data[8:]),
+ get32(data[12:]),
+ }, true
+ }
+ }
+ return CodeSigCmd{}, false
+}
+
+func put32be(b []byte, x uint32) []byte { binary.BigEndian.PutUint32(b, x); return b[4:] }
+func put64be(b []byte, x uint64) []byte { binary.BigEndian.PutUint64(b, x); return b[8:] }
+func put8(b []byte, x uint8) []byte { b[0] = x; return b[1:] }
+func puts(b, s []byte) []byte { n := copy(b, s); return b[n:] }
+
+// Size computes the size of the code signature.
+// id is the identifier used for signing (a field in CodeDirectory blob, which
+// has no significance in ad-hoc signing).
+func Size(codeSize int64, id string) int64 {
+ nhashes := (codeSize + pageSize - 1) / pageSize
+ idOff := int64(codeDirectorySize)
+ hashOff := idOff + int64(len(id)+1)
+ cdirSz := hashOff + nhashes*sha256.Size
+ return int64(superBlobSize+blobSize) + cdirSz
+}
+
+// Sign generates an ad-hoc code signature and writes it to out.
+// out must have length at least Size(codeSize, id).
+// data is the file content without the signature, of size codeSize.
+// textOff and textSize is the file offset and size of the text segment.
+// isMain is true if this is a main executable.
+// id is the identifier used for signing (a field in CodeDirectory blob, which
+// has no significance in ad-hoc signing).
+func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int64, isMain bool) {
+ nhashes := (codeSize + pageSize - 1) / pageSize
+ idOff := int64(codeDirectorySize)
+ hashOff := idOff + int64(len(id)+1)
+ sz := Size(codeSize, id)
+
+ // emit blob headers
+ sb := SuperBlob{
+ magic: CSMAGIC_EMBEDDED_SIGNATURE,
+ length: uint32(sz),
+ count: 1,
+ }
+ blob := Blob{
+ typ: CSSLOT_CODEDIRECTORY,
+ offset: superBlobSize + blobSize,
+ }
+ cdir := CodeDirectory{
+ magic: CSMAGIC_CODEDIRECTORY,
+ length: uint32(sz) - (superBlobSize + blobSize),
+ version: 0x20400,
+ flags: 0x20002, // adhoc | linkerSigned
+ hashOffset: uint32(hashOff),
+ identOffset: uint32(idOff),
+ nCodeSlots: uint32(nhashes),
+ codeLimit: uint32(codeSize),
+ hashSize: sha256.Size,
+ hashType: CS_HASHTYPE_SHA256,
+ pageSize: uint8(pageSizeBits),
+ execSegBase: uint64(textOff),
+ execSegLimit: uint64(textSize),
+ }
+ if isMain {
+ cdir.execSegFlags = CS_EXECSEG_MAIN_BINARY
+ }
+
+ outp := out
+ outp = sb.put(outp)
+ outp = blob.put(outp)
+ outp = cdir.put(outp)
+
+ // emit the identifier
+ outp = puts(outp, []byte(id+"\000"))
+
+ // emit hashes
+ var buf [pageSize]byte
+ h := sha256.New()
+ p := 0
+ for p < int(codeSize) {
+ n, err := io.ReadFull(data, buf[:])
+ if err == io.EOF {
+ break
+ }
+ if err != nil && err != io.ErrUnexpectedEOF {
+ panic(err)
+ }
+ if p+n > int(codeSize) {
+ n = int(codeSize) - p
+ }
+ p += n
+ h.Reset()
+ h.Write(buf[:n])
+ b := h.Sum(nil)
+ outp = puts(outp, b[:])
+ }
+}
From 7fca39aa05ad3c60abac1ae51ae9847dfbe017d6 Mon Sep 17 00:00:00 2001
From: Cherry Zhang
Date: Sat, 21 Nov 2020 17:43:16 -0500
Subject: [PATCH 31/50] cmd/internal/buildid: exclude Mach-O code signature in
hash calculation
The code signature contains hashes of the entire file (except the
signature itself), including the buildid. Therefore, the buildid
cannot depend on the signature. Otherwise updating buildid will
invalidate the signature, and vice versa. As we cannot change the
code-signing algorithm, we can only change buildid calculation.
This CL changes the buildid calculation to exclude the Mach-O
code signature. So updating code signature after stamping the
buildid will not invalidate the buildid.
Updates #38485, #42684.
Change-Id: I8a9e2e25ca9dc00d9556d13b81652f43bbf6a084
Reviewed-on: https://go-review.googlesource.com/c/go/+/272255
Trust: Cherry Zhang
Run-TryBot: Cherry Zhang
TryBot-Result: Go Bot
Reviewed-by: Austin Clements
Reviewed-by: Than McIntosh
---
src/cmd/internal/buildid/buildid_test.go | 31 +++++++++++++++
src/cmd/internal/buildid/rewrite.go | 50 ++++++++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/src/cmd/internal/buildid/buildid_test.go b/src/cmd/internal/buildid/buildid_test.go
index 904c2c6f37..e832f9987e 100644
--- a/src/cmd/internal/buildid/buildid_test.go
+++ b/src/cmd/internal/buildid/buildid_test.go
@@ -11,6 +11,7 @@ import (
"io/ioutil"
"os"
"reflect"
+ "strings"
"testing"
)
@@ -146,3 +147,33 @@ func TestFindAndHash(t *testing.T) {
}
}
}
+
+func TestExcludedReader(t *testing.T) {
+ const s = "0123456789abcdefghijklmn"
+ tests := []struct {
+ start, end int64 // excluded range
+ results []string // expected results of reads
+ }{
+ {12, 15, []string{"0123456789", "ab\x00\x00\x00fghij", "klmn"}}, // within one read
+ {8, 21, []string{"01234567\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00lmn"}}, // across multiple reads
+ {10, 20, []string{"0123456789", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "klmn"}}, // a whole read
+ {0, 5, []string{"\x00\x00\x00\x00\x0056789", "abcdefghij", "klmn"}}, // start
+ {12, 24, []string{"0123456789", "ab\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00"}}, // end
+ }
+ p := make([]byte, 10)
+ for _, test := range tests {
+ r := &excludedReader{strings.NewReader(s), 0, test.start, test.end}
+ for _, res := range test.results {
+ n, err := r.Read(p)
+ if err != nil {
+ t.Errorf("read failed: %v", err)
+ }
+ if n != len(res) {
+ t.Errorf("unexpected number of bytes read: want %d, got %d", len(res), n)
+ }
+ if string(p[:n]) != res {
+ t.Errorf("unexpected bytes: want %q, got %q", res, p[:n])
+ }
+ }
+ }
+}
diff --git a/src/cmd/internal/buildid/rewrite.go b/src/cmd/internal/buildid/rewrite.go
index 5be54552a6..d3d2009d1c 100644
--- a/src/cmd/internal/buildid/rewrite.go
+++ b/src/cmd/internal/buildid/rewrite.go
@@ -6,7 +6,9 @@ package buildid
import (
"bytes"
+ "cmd/internal/codesign"
"crypto/sha256"
+ "debug/macho"
"fmt"
"io"
)
@@ -26,6 +28,11 @@ func FindAndHash(r io.Reader, id string, bufSize int) (matches []int64, hash [32
zeros := make([]byte, len(id))
idBytes := []byte(id)
+ // For Mach-O files, we want to exclude the code signature.
+ // The code signature contains hashes of the whole file (except the signature
+ // itself), including the buildid. So the buildid cannot contain the signature.
+ r = excludeMachoCodeSignature(r)
+
// The strategy is to read the file through buf, looking for id,
// but we need to worry about what happens if id is broken up
// and returned in parts by two different reads.
@@ -89,3 +96,46 @@ func Rewrite(w io.WriterAt, pos []int64, id string) error {
}
return nil
}
+
+func excludeMachoCodeSignature(r io.Reader) io.Reader {
+ ra, ok := r.(io.ReaderAt)
+ if !ok {
+ return r
+ }
+ f, err := macho.NewFile(ra)
+ if err != nil {
+ return r
+ }
+ cmd, ok := codesign.FindCodeSigCmd(f)
+ if !ok {
+ return r
+ }
+ return &excludedReader{r, 0, int64(cmd.Dataoff), int64(cmd.Dataoff + cmd.Datasize)}
+}
+
+// excludedReader wraps an io.Reader. Reading from it returns the bytes from
+// the underlying reader, except that when the byte offset is within the
+// range between start and end, it returns zero bytes.
+type excludedReader struct {
+ r io.Reader
+ off int64 // current offset
+ start, end int64 // the range to be excluded (read as zero)
+}
+
+func (r *excludedReader) Read(p []byte) (int, error) {
+ n, err := r.r.Read(p)
+ if n > 0 && r.off+int64(n) > r.start && r.off < r.end {
+ cstart := r.start - r.off
+ if cstart < 0 {
+ cstart = 0
+ }
+ cend := r.end - r.off
+ if cend > int64(n) {
+ cend = int64(n)
+ }
+ zeros := make([]byte, cend-cstart)
+ copy(p[cstart:cend], zeros)
+ }
+ r.off += int64(n)
+ return n, err
+}
From 283d65413db75edbc4691c4fecf23228509436f0 Mon Sep 17 00:00:00 2001
From: Kevin Burke
Date: Fri, 27 Nov 2020 13:55:27 -0800
Subject: [PATCH 32/50] encoding/json: revert "add "json: " prefix to
SyntaxError messages"
This reverts commit 6af088bfc66c13143c9ef46b4cf0805df77a8fbe.
Reason for revert: Broke many tests inside Google which implies many
tests were broken outside of Google as well. The tests may be brittle
but still would require work to change and it's not clear it's worth
the benefit.
Updates #36221
Fixes #42675
Change-Id: Id3a14eb37e7119f5abe50e80dfbf120fdc44db72
Reviewed-on: https://go-review.googlesource.com/c/go/+/273747
Run-TryBot: Joe Tsai
TryBot-Result: Go Bot
Reviewed-by: Russ Cox
Reviewed-by: Joe Tsai
Trust: Joe Tsai
---
doc/go1.16.html | 6 ------
src/cmd/go/testdata/script/mod_proxy_invalid.txt | 4 ++--
src/cmd/go/testdata/script/mod_query_empty.txt | 2 +-
src/encoding/json/scanner.go | 2 +-
src/html/template/escape_test.go | 2 +-
5 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 0c1fe5b381..ffdbc97c62 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -454,12 +454,6 @@ Do not send CLs removing the interior tags from such phrases.
From 3d913a926675d8d6fcdc3cfaefd3136dfeba06e1 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Thu, 29 Oct 2020 13:51:20 -0400
Subject: [PATCH 42/50] os: add ReadFile, WriteFile, CreateTemp (was TempFile),
MkdirTemp (was TempDir) from io/ioutil
io/ioutil was a poorly defined collection of helpers.
Proposal #40025 moved out the generic I/O helpers to io.
This CL for proposal #42026 moves the OS-specific helpers to os,
making the entire io/ioutil package deprecated.
For #42026.
Change-Id: I018bcb2115ef2ff1bc7ca36a9247eda429af21ad
Reviewed-on: https://go-review.googlesource.com/c/go/+/266364
Trust: Russ Cox
Trust: Emmanuel Odeke
Run-TryBot: Russ Cox
TryBot-Result: Go Bot
Reviewed-by: Emmanuel Odeke
---
src/io/ioutil/ioutil.go | 70 ++++----------
src/os/dir.go | 22 ++++-
src/os/example_test.go | 96 +++++++++++++++++++
src/os/export_test.go | 1 +
src/os/file.go | 60 ++++++++++++
src/os/os_test.go | 26 +++++-
src/os/read_test.go | 127 ++++++++++++++++++++++++++
src/os/removeall_test.go | 7 +-
src/os/tempfile.go | 118 ++++++++++++++++++++++++
src/os/tempfile_test.go | 193 +++++++++++++++++++++++++++++++++++++++
src/os/testdata/hello | 1 +
src/runtime/stubs.go | 3 +
12 files changed, 666 insertions(+), 58 deletions(-)
create mode 100644 src/os/read_test.go
create mode 100644 src/os/tempfile.go
create mode 100644 src/os/tempfile_test.go
create mode 100644 src/os/testdata/hello
diff --git a/src/io/ioutil/ioutil.go b/src/io/ioutil/ioutil.go
index a001c86b2f..45682b89c9 100644
--- a/src/io/ioutil/ioutil.go
+++ b/src/io/ioutil/ioutil.go
@@ -3,6 +3,11 @@
// license that can be found in the LICENSE file.
// Package ioutil implements some I/O utility functions.
+//
+// As of Go 1.16, the same functionality is now provided
+// by package io or package os, and those implementations
+// should be preferred in new code.
+// See the specific function documentation for details.
package ioutil
import (
@@ -26,67 +31,30 @@ func ReadAll(r io.Reader) ([]byte, error) {
// A successful call returns err == nil, not err == EOF. Because ReadFile
// reads the whole file, it does not treat an EOF from Read as an error
// to be reported.
+//
+// As of Go 1.16, this function simply calls os.ReadFile.
func ReadFile(filename string) ([]byte, error) {
- f, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer f.Close()
- // It's a good but not certain bet that FileInfo will tell us exactly how much to
- // read, so let's try it but be prepared for the answer to be wrong.
- const minRead = 512
- var n int64 = minRead
-
- if fi, err := f.Stat(); err == nil {
- // As initial capacity for readAll, use Size + a little extra in case Size
- // is zero, and to avoid another allocation after Read has filled the
- // buffer. The readAll call will read into its allocated internal buffer
- // cheaply. If the size was wrong, we'll either waste some space off the end
- // or reallocate as needed, but in the overwhelmingly common case we'll get
- // it just right.
- if size := fi.Size() + minRead; size > n {
- n = size
- }
- }
-
- if int64(int(n)) != n {
- n = minRead
- }
-
- b := make([]byte, 0, n)
- for {
- if len(b) == cap(b) {
- // Add more capacity (let append pick how much).
- b = append(b, 0)[:len(b)]
- }
- n, err := f.Read(b[len(b):cap(b)])
- b = b[:len(b)+n]
- if err != nil {
- if err == io.EOF {
- err = nil
- }
- return b, err
- }
- }
+ return os.ReadFile(filename)
}
// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm
// (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
+//
+// As of Go 1.16, this function simply calls os.WriteFile.
func WriteFile(filename string, data []byte, perm fs.FileMode) error {
- f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
- if err != nil {
- return err
- }
- _, err = f.Write(data)
- if err1 := f.Close(); err == nil {
- err = err1
- }
- return err
+ return os.WriteFile(filename, data, perm)
}
// ReadDir reads the directory named by dirname and returns
-// a list of directory entries sorted by filename.
+// a list of fs.FileInfo for the directory's contents,
+// sorted by filename. If an error occurs reading the directory,
+// ReadDir returns no directory entries along with the error.
+//
+// As of Go 1.16, os.ReadDir is a more efficient and correct choice:
+// it returns a list of fs.DirEntry instead of fs.FileInfo,
+// and it returns partial results in the case of an error
+// midway through reading a directory.
func ReadDir(dirname string) ([]fs.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
diff --git a/src/os/dir.go b/src/os/dir.go
index 1d90b970e7..5306bcb3ba 100644
--- a/src/os/dir.go
+++ b/src/os/dir.go
@@ -4,7 +4,10 @@
package os
-import "io/fs"
+import (
+ "io/fs"
+ "sort"
+)
type readdirMode int
@@ -103,3 +106,20 @@ func (f *File) ReadDir(n int) ([]DirEntry, error) {
// testingForceReadDirLstat forces ReadDir to call Lstat, for testing that code path.
// This can be difficult to provoke on some Unix systems otherwise.
var testingForceReadDirLstat bool
+
+// ReadDir reads the named directory,
+// returning all its directory entries sorted by filename.
+// If an error occurs reading the directory,
+// ReadDir returns the entries it was able to read before the error,
+// along with the error.
+func ReadDir(name string) ([]DirEntry, error) {
+ f, err := Open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ dirs, err := f.ReadDir(-1)
+ sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() })
+ return dirs, err
+}
diff --git a/src/os/example_test.go b/src/os/example_test.go
index fbb277b6f1..3adce51784 100644
--- a/src/os/example_test.go
+++ b/src/os/example_test.go
@@ -9,6 +9,7 @@ import (
"io/fs"
"log"
"os"
+ "path/filepath"
"time"
)
@@ -144,3 +145,98 @@ func ExampleUnsetenv() {
os.Setenv("TMPDIR", "/my/tmp")
defer os.Unsetenv("TMPDIR")
}
+
+func ExampleReadDir() {
+ files, err := os.ReadDir(".")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, file := range files {
+ fmt.Println(file.Name())
+ }
+}
+
+func ExampleMkdirTemp() {
+ dir, err := os.MkdirTemp("", "example")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(dir) // clean up
+
+ file := filepath.Join(dir, "tmpfile")
+ if err := os.WriteFile(file, []byte("content"), 0666); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func ExampleMkdirTemp_suffix() {
+ logsDir, err := os.MkdirTemp("", "*-logs")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(logsDir) // clean up
+
+ // Logs can be cleaned out earlier if needed by searching
+ // for all directories whose suffix ends in *-logs.
+ globPattern := filepath.Join(os.TempDir(), "*-logs")
+ matches, err := filepath.Glob(globPattern)
+ if err != nil {
+ log.Fatalf("Failed to match %q: %v", globPattern, err)
+ }
+
+ for _, match := range matches {
+ if err := os.RemoveAll(match); err != nil {
+ log.Printf("Failed to remove %q: %v", match, err)
+ }
+ }
+}
+
+func ExampleCreateTemp() {
+ f, err := os.CreateTemp("", "example")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.Remove(f.Name()) // clean up
+
+ if _, err := f.Write([]byte("content")); err != nil {
+ log.Fatal(err)
+ }
+ if err := f.Close(); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func ExampleCreateTemp_suffix() {
+ f, err := os.CreateTemp("", "example.*.txt")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.Remove(f.Name()) // clean up
+
+ if _, err := f.Write([]byte("content")); err != nil {
+ f.Close()
+ log.Fatal(err)
+ }
+ if err := f.Close(); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func ExampleReadFile() {
+ data, err := os.ReadFile("testdata/hello")
+ if err != nil {
+ log.Fatal(err)
+ }
+ os.Stdout.Write(data)
+
+ // Output:
+ // Hello, Gophers!
+}
+
+func ExampleWriteFile() {
+ err := os.WriteFile("testdata/hello", []byte("Hello, Gophers!"), 0666)
+ if err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/src/os/export_test.go b/src/os/export_test.go
index d66264a68f..f3cb1a2bef 100644
--- a/src/os/export_test.go
+++ b/src/os/export_test.go
@@ -10,3 +10,4 @@ var Atime = atime
var LstatP = &lstat
var ErrWriteAtInAppendMode = errWriteAtInAppendMode
var TestingForceReadDirLstat = &testingForceReadDirLstat
+var ErrPatternHasSeparator = errPatternHasSeparator
diff --git a/src/os/file.go b/src/os/file.go
index 420e62ef2c..304b055dbe 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -625,3 +625,63 @@ func (dir dirFS) Open(name string) (fs.File, error) {
}
return f, nil
}
+
+// ReadFile reads the named file and returns the contents.
+// A successful call returns err == nil, not err == EOF.
+// Because ReadFile reads the whole file, it does not treat an EOF from Read
+// as an error to be reported.
+func ReadFile(name string) ([]byte, error) {
+ f, err := Open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ var size int
+ if info, err := f.Stat(); err == nil {
+ size64 := info.Size()
+ if int64(int(size64)) == size64 {
+ size = int(size64)
+ }
+ }
+ size++ // one byte for final read at EOF
+
+ // If a file claims a small size, read at least 512 bytes.
+ // In particular, files in Linux's /proc claim size 0 but
+ // then do not work right if read in small pieces,
+ // so an initial read of 1 byte would not work correctly.
+ if size < 512 {
+ size = 512
+ }
+
+ data := make([]byte, 0, size)
+ for {
+ if len(data) >= cap(data) {
+ d := append(data[:cap(data)], 0)
+ data = d[:len(data)]
+ }
+ n, err := f.Read(data[len(data):cap(data)])
+ data = data[:len(data)+n]
+ if err != nil {
+ if err == io.EOF {
+ err = nil
+ }
+ return data, err
+ }
+ }
+}
+
+// WriteFile writes data to the named file, creating it if necessary.
+// If the file does not exist, WriteFile creates it with permissions perm (before umask);
+// otherwise WriteFile truncates it before writing, without changing permissions.
+func WriteFile(name string, data []byte, perm FileMode) error {
+ f, err := OpenFile(name, O_WRONLY|O_CREATE|O_TRUNC, perm)
+ if err != nil {
+ return err
+ }
+ _, err = f.Write(data)
+ if err1 := f.Close(); err1 != nil && err == nil {
+ err = err1
+ }
+ return err
+}
diff --git a/src/os/os_test.go b/src/os/os_test.go
index a1c0578887..c5e5cbbb1b 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -419,19 +419,19 @@ func testReadDir(dir string, contents []string, t *testing.T) {
}
}
-func TestReaddirnames(t *testing.T) {
+func TestFileReaddirnames(t *testing.T) {
testReaddirnames(".", dot, t)
testReaddirnames(sysdir.name, sysdir.files, t)
testReaddirnames(t.TempDir(), nil, t)
}
-func TestReaddir(t *testing.T) {
+func TestFileReaddir(t *testing.T) {
testReaddir(".", dot, t)
testReaddir(sysdir.name, sysdir.files, t)
testReaddir(t.TempDir(), nil, t)
}
-func TestReadDir(t *testing.T) {
+func TestFileReadDir(t *testing.T) {
testReadDir(".", dot, t)
testReadDir(sysdir.name, sysdir.files, t)
testReadDir(t.TempDir(), nil, t)
@@ -1235,6 +1235,7 @@ func TestChmod(t *testing.T) {
}
func checkSize(t *testing.T, f *File, size int64) {
+ t.Helper()
dir, err := f.Stat()
if err != nil {
t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
@@ -2690,3 +2691,22 @@ func TestDirFS(t *testing.T) {
t.Fatal(err)
}
}
+
+func TestReadFileProc(t *testing.T) {
+ // Linux files in /proc report 0 size,
+ // but then if ReadFile reads just a single byte at offset 0,
+ // the read at offset 1 returns EOF instead of more data.
+ // ReadFile has a minimum read size of 512 to work around this,
+ // but test explicitly that it's working.
+ name := "/proc/sys/fs/pipe-max-size"
+ if _, err := Stat(name); err != nil {
+ t.Skip(err)
+ }
+ data, err := ReadFile(name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data) == 0 || data[len(data)-1] != '\n' {
+ t.Fatalf("read %s: not newline-terminated: %q", name, data)
+ }
+}
diff --git a/src/os/read_test.go b/src/os/read_test.go
new file mode 100644
index 0000000000..5c58d7d7df
--- /dev/null
+++ b/src/os/read_test.go
@@ -0,0 +1,127 @@
+// Copyright 2009 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 os_test
+
+import (
+ "bytes"
+ . "os"
+ "path/filepath"
+ "testing"
+)
+
+func checkNamedSize(t *testing.T, path string, size int64) {
+ dir, err := Stat(path)
+ if err != nil {
+ t.Fatalf("Stat %q (looking for size %d): %s", path, size, err)
+ }
+ if dir.Size() != size {
+ t.Errorf("Stat %q: size %d want %d", path, dir.Size(), size)
+ }
+}
+
+func TestReadFile(t *testing.T) {
+ filename := "rumpelstilzchen"
+ contents, err := ReadFile(filename)
+ if err == nil {
+ t.Fatalf("ReadFile %s: error expected, none found", filename)
+ }
+
+ filename = "read_test.go"
+ contents, err = ReadFile(filename)
+ if err != nil {
+ t.Fatalf("ReadFile %s: %v", filename, err)
+ }
+
+ checkNamedSize(t, filename, int64(len(contents)))
+}
+
+func TestWriteFile(t *testing.T) {
+ f, err := CreateTemp("", "ioutil-test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer f.Close()
+ defer Remove(f.Name())
+
+ msg := "Programming today is a race between software engineers striving to " +
+ "build bigger and better idiot-proof programs, and the Universe trying " +
+ "to produce bigger and better idiots. So far, the Universe is winning."
+
+ if err := WriteFile(f.Name(), []byte(msg), 0644); err != nil {
+ t.Fatalf("WriteFile %s: %v", f.Name(), err)
+ }
+
+ data, err := ReadFile(f.Name())
+ if err != nil {
+ t.Fatalf("ReadFile %s: %v", f.Name(), err)
+ }
+
+ if string(data) != msg {
+ t.Fatalf("ReadFile: wrong data:\nhave %q\nwant %q", string(data), msg)
+ }
+}
+
+func TestReadOnlyWriteFile(t *testing.T) {
+ if Getuid() == 0 {
+ t.Skipf("Root can write to read-only files anyway, so skip the read-only test.")
+ }
+
+ // We don't want to use CreateTemp directly, since that opens a file for us as 0600.
+ tempDir, err := MkdirTemp("", t.Name())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer RemoveAll(tempDir)
+ filename := filepath.Join(tempDir, "blurp.txt")
+
+ shmorp := []byte("shmorp")
+ florp := []byte("florp")
+ err = WriteFile(filename, shmorp, 0444)
+ if err != nil {
+ t.Fatalf("WriteFile %s: %v", filename, err)
+ }
+ err = WriteFile(filename, florp, 0444)
+ if err == nil {
+ t.Fatalf("Expected an error when writing to read-only file %s", filename)
+ }
+ got, err := ReadFile(filename)
+ if err != nil {
+ t.Fatalf("ReadFile %s: %v", filename, err)
+ }
+ if !bytes.Equal(got, shmorp) {
+ t.Fatalf("want %s, got %s", shmorp, got)
+ }
+}
+
+func TestReadDir(t *testing.T) {
+ dirname := "rumpelstilzchen"
+ _, err := ReadDir(dirname)
+ if err == nil {
+ t.Fatalf("ReadDir %s: error expected, none found", dirname)
+ }
+
+ dirname = "."
+ list, err := ReadDir(dirname)
+ if err != nil {
+ t.Fatalf("ReadDir %s: %v", dirname, err)
+ }
+
+ foundFile := false
+ foundSubDir := false
+ for _, dir := range list {
+ switch {
+ case !dir.IsDir() && dir.Name() == "read_test.go":
+ foundFile = true
+ case dir.IsDir() && dir.Name() == "exec":
+ foundSubDir = true
+ }
+ }
+ if !foundFile {
+ t.Fatalf("ReadDir %s: read_test.go file not found", dirname)
+ }
+ if !foundSubDir {
+ t.Fatalf("ReadDir %s: exec directory not found", dirname)
+ }
+}
diff --git a/src/os/removeall_test.go b/src/os/removeall_test.go
index bc9c468ce3..90efa313ea 100644
--- a/src/os/removeall_test.go
+++ b/src/os/removeall_test.go
@@ -355,11 +355,12 @@ func TestRemoveAllButReadOnlyAndPathError(t *testing.T) {
// The error should be of type *PathError.
// see issue 30491 for details.
if pathErr, ok := err.(*PathError); ok {
- if g, w := pathErr.Path, filepath.Join(tempDir, "b", "y"); g != w {
- t.Errorf("got %q, expected pathErr.path %q", g, w)
+ want := filepath.Join(tempDir, "b", "y")
+ if pathErr.Path != want {
+ t.Errorf("RemoveAll(%q): err.Path=%q, want %q", tempDir, pathErr.Path, want)
}
} else {
- t.Errorf("got %T, expected *fs.PathError", err)
+ t.Errorf("RemoveAll(%q): error has type %T, want *fs.PathError", tempDir, err)
}
for _, dir := range dirs {
diff --git a/src/os/tempfile.go b/src/os/tempfile.go
new file mode 100644
index 0000000000..2728485c32
--- /dev/null
+++ b/src/os/tempfile.go
@@ -0,0 +1,118 @@
+// Copyright 2010 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 os
+
+import (
+ "errors"
+ "strings"
+)
+
+// fastrand provided by runtime.
+// We generate random temporary file names so that there's a good
+// chance the file doesn't exist yet - keeps the number of tries in
+// TempFile to a minimum.
+func fastrand() uint32
+
+func nextRandom() string {
+ return uitoa(uint(fastrand()))
+}
+
+// CreateTemp creates a new temporary file in the directory dir,
+// opens the file for reading and writing, and returns the resulting file.
+// The filename is generated by taking pattern and adding a random string to the end.
+// If pattern includes a "*", the random string replaces the last "*".
+// If dir is the empty string, TempFile uses the default directory for temporary files, as returned by TempDir.
+// Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file.
+// The caller can use the file's Name method to find the pathname of the file.
+// It is the caller's responsibility to remove the file when it is no longer needed.
+func CreateTemp(dir, pattern string) (*File, error) {
+ if dir == "" {
+ dir = TempDir()
+ }
+
+ prefix, suffix, err := prefixAndSuffix(pattern)
+ if err != nil {
+ return nil, &PathError{Op: "createtemp", Path: pattern, Err: err}
+ }
+ prefix = joinPath(dir, prefix)
+
+ try := 0
+ for {
+ name := prefix + nextRandom() + suffix
+ f, err := OpenFile(name, O_RDWR|O_CREATE|O_EXCL, 0600)
+ if IsExist(err) {
+ if try++; try < 10000 {
+ continue
+ }
+ return nil, &PathError{Op: "createtemp", Path: dir + string(PathSeparator) + prefix + "*" + suffix, Err: ErrExist}
+ }
+ return f, err
+ }
+}
+
+var errPatternHasSeparator = errors.New("pattern contains path separator")
+
+// prefixAndSuffix splits pattern by the last wildcard "*", if applicable,
+// returning prefix as the part before "*" and suffix as the part after "*".
+func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
+ for i := 0; i < len(pattern); i++ {
+ if IsPathSeparator(pattern[i]) {
+ return "", "", errPatternHasSeparator
+ }
+ }
+ if pos := strings.LastIndex(pattern, "*"); pos != -1 {
+ prefix, suffix = pattern[:pos], pattern[pos+1:]
+ } else {
+ prefix = pattern
+ }
+ return prefix, suffix, nil
+}
+
+// MkdirTemp creates a new temporary directory in the directory dir
+// and returns the pathname of the new directory.
+// The new directory's name is generated by adding a random string to the end of pattern.
+// If pattern includes a "*", the random string replaces the last "*" instead.
+// If dir is the empty string, TempFile uses the default directory for temporary files, as returned by TempDir.
+// Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory.
+// It is the caller's responsibility to remove the directory when it is no longer needed.
+func MkdirTemp(dir, pattern string) (string, error) {
+ if dir == "" {
+ dir = TempDir()
+ }
+
+ prefix, suffix, err := prefixAndSuffix(pattern)
+ if err != nil {
+ return "", &PathError{Op: "mkdirtemp", Path: pattern, Err: err}
+ }
+ prefix = joinPath(dir, prefix)
+
+ try := 0
+ for {
+ name := prefix + nextRandom() + suffix
+ err := Mkdir(name, 0700)
+ if err == nil {
+ return name, nil
+ }
+ if IsExist(err) {
+ if try++; try < 10000 {
+ continue
+ }
+ return "", &PathError{Op: "mkdirtemp", Path: dir + string(PathSeparator) + prefix + "*" + suffix, Err: ErrExist}
+ }
+ if IsNotExist(err) {
+ if _, err := Stat(dir); IsNotExist(err) {
+ return "", err
+ }
+ }
+ return "", err
+ }
+}
+
+func joinPath(dir, name string) string {
+ if len(dir) > 0 && IsPathSeparator(dir[len(dir)-1]) {
+ return dir + name
+ }
+ return dir + string(PathSeparator) + name
+}
diff --git a/src/os/tempfile_test.go b/src/os/tempfile_test.go
new file mode 100644
index 0000000000..e71a2444c9
--- /dev/null
+++ b/src/os/tempfile_test.go
@@ -0,0 +1,193 @@
+// Copyright 2010 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 os_test
+
+import (
+ "errors"
+ "io/fs"
+ . "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "testing"
+)
+
+func TestCreateTemp(t *testing.T) {
+ dir, err := MkdirTemp("", "TestCreateTempBadDir")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer RemoveAll(dir)
+
+ nonexistentDir := filepath.Join(dir, "_not_exists_")
+ f, err := CreateTemp(nonexistentDir, "foo")
+ if f != nil || err == nil {
+ t.Errorf("CreateTemp(%q, `foo`) = %v, %v", nonexistentDir, f, err)
+ }
+}
+
+func TestCreateTempPattern(t *testing.T) {
+ tests := []struct{ pattern, prefix, suffix string }{
+ {"tempfile_test", "tempfile_test", ""},
+ {"tempfile_test*", "tempfile_test", ""},
+ {"tempfile_test*xyz", "tempfile_test", "xyz"},
+ }
+ for _, test := range tests {
+ f, err := CreateTemp("", test.pattern)
+ if err != nil {
+ t.Errorf("CreateTemp(..., %q) error: %v", test.pattern, err)
+ continue
+ }
+ defer Remove(f.Name())
+ base := filepath.Base(f.Name())
+ f.Close()
+ if !(strings.HasPrefix(base, test.prefix) && strings.HasSuffix(base, test.suffix)) {
+ t.Errorf("CreateTemp pattern %q created bad name %q; want prefix %q & suffix %q",
+ test.pattern, base, test.prefix, test.suffix)
+ }
+ }
+}
+
+func TestCreateTempBadPattern(t *testing.T) {
+ tmpDir, err := MkdirTemp("", t.Name())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer RemoveAll(tmpDir)
+
+ const sep = string(PathSeparator)
+ tests := []struct {
+ pattern string
+ wantErr bool
+ }{
+ {"ioutil*test", false},
+ {"tempfile_test*foo", false},
+ {"tempfile_test" + sep + "foo", true},
+ {"tempfile_test*" + sep + "foo", true},
+ {"tempfile_test" + sep + "*foo", true},
+ {sep + "tempfile_test" + sep + "*foo", true},
+ {"tempfile_test*foo" + sep, true},
+ }
+ for _, tt := range tests {
+ t.Run(tt.pattern, func(t *testing.T) {
+ tmpfile, err := CreateTemp(tmpDir, tt.pattern)
+ if tmpfile != nil {
+ defer tmpfile.Close()
+ }
+ if tt.wantErr {
+ if err == nil {
+ t.Errorf("CreateTemp(..., %#q) succeeded, expected error", tt.pattern)
+ }
+ if !errors.Is(err, ErrPatternHasSeparator) {
+ t.Errorf("CreateTemp(..., %#q): %v, expected ErrPatternHasSeparator", tt.pattern, err)
+ }
+ } else if err != nil {
+ t.Errorf("CreateTemp(..., %#q): %v", tt.pattern, err)
+ }
+ })
+ }
+}
+
+func TestMkdirTemp(t *testing.T) {
+ name, err := MkdirTemp("/_not_exists_", "foo")
+ if name != "" || err == nil {
+ t.Errorf("MkdirTemp(`/_not_exists_`, `foo`) = %v, %v", name, err)
+ }
+
+ tests := []struct {
+ pattern string
+ wantPrefix, wantSuffix string
+ }{
+ {"tempfile_test", "tempfile_test", ""},
+ {"tempfile_test*", "tempfile_test", ""},
+ {"tempfile_test*xyz", "tempfile_test", "xyz"},
+ }
+
+ dir := filepath.Clean(TempDir())
+
+ runTestMkdirTemp := func(t *testing.T, pattern, wantRePat string) {
+ name, err := MkdirTemp(dir, pattern)
+ if name == "" || err != nil {
+ t.Fatalf("MkdirTemp(dir, `tempfile_test`) = %v, %v", name, err)
+ }
+ defer Remove(name)
+
+ re := regexp.MustCompile(wantRePat)
+ if !re.MatchString(name) {
+ t.Errorf("MkdirTemp(%q, %q) created bad name\n\t%q\ndid not match pattern\n\t%q", dir, pattern, name, wantRePat)
+ }
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.pattern, func(t *testing.T) {
+ wantRePat := "^" + regexp.QuoteMeta(filepath.Join(dir, tt.wantPrefix)) + "[0-9]+" + regexp.QuoteMeta(tt.wantSuffix) + "$"
+ runTestMkdirTemp(t, tt.pattern, wantRePat)
+ })
+ }
+
+ // Separately testing "*xyz" (which has no prefix). That is when constructing the
+ // pattern to assert on, as in the previous loop, using filepath.Join for an empty
+ // prefix filepath.Join(dir, ""), produces the pattern:
+ // ^[0-9]+xyz$
+ // yet we just want to match
+ // "^/[0-9]+xyz"
+ t.Run("*xyz", func(t *testing.T) {
+ wantRePat := "^" + regexp.QuoteMeta(filepath.Join(dir)) + regexp.QuoteMeta(string(filepath.Separator)) + "[0-9]+xyz$"
+ runTestMkdirTemp(t, "*xyz", wantRePat)
+ })
+}
+
+// test that we return a nice error message if the dir argument to TempDir doesn't
+// exist (or that it's empty and TempDir doesn't exist)
+func TestMkdirTempBadDir(t *testing.T) {
+ dir, err := MkdirTemp("", "MkdirTempBadDir")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer RemoveAll(dir)
+
+ badDir := filepath.Join(dir, "not-exist")
+ _, err = MkdirTemp(badDir, "foo")
+ if pe, ok := err.(*fs.PathError); !ok || !IsNotExist(err) || pe.Path != badDir {
+ t.Errorf("TempDir error = %#v; want PathError for path %q satisifying IsNotExist", err, badDir)
+ }
+}
+
+func TestMkdirTempBadPattern(t *testing.T) {
+ tmpDir, err := MkdirTemp("", t.Name())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer RemoveAll(tmpDir)
+
+ const sep = string(PathSeparator)
+ tests := []struct {
+ pattern string
+ wantErr bool
+ }{
+ {"ioutil*test", false},
+ {"tempfile_test*foo", false},
+ {"tempfile_test" + sep + "foo", true},
+ {"tempfile_test*" + sep + "foo", true},
+ {"tempfile_test" + sep + "*foo", true},
+ {sep + "tempfile_test" + sep + "*foo", true},
+ {"tempfile_test*foo" + sep, true},
+ }
+ for _, tt := range tests {
+ t.Run(tt.pattern, func(t *testing.T) {
+ _, err := MkdirTemp(tmpDir, tt.pattern)
+ if tt.wantErr {
+ if err == nil {
+ t.Errorf("MkdirTemp(..., %#q) succeeded, expected error", tt.pattern)
+ }
+ if !errors.Is(err, ErrPatternHasSeparator) {
+ t.Errorf("MkdirTemp(..., %#q): %v, expected ErrPatternHasSeparator", tt.pattern, err)
+ }
+ } else if err != nil {
+ t.Errorf("MkdirTemp(..., %#q): %v", tt.pattern, err)
+ }
+ })
+ }
+}
diff --git a/src/os/testdata/hello b/src/os/testdata/hello
new file mode 100644
index 0000000000..e47c092a51
--- /dev/null
+++ b/src/os/testdata/hello
@@ -0,0 +1 @@
+Hello, Gophers!
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index d77cb4d460..b55c3c0590 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -133,6 +133,9 @@ func sync_fastrand() uint32 { return fastrand() }
//go:linkname net_fastrand net.fastrand
func net_fastrand() uint32 { return fastrand() }
+//go:linkname os_fastrand os.fastrand
+func os_fastrand() uint32 { return fastrand() }
+
// in internal/bytealg/equal_*.s
//go:noescape
func memequal(a, b unsafe.Pointer, size uintptr) bool
From ac38af2f3db7b16067bd8983d1f5278c5c9ef706 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Wed, 2 Dec 2020 10:14:53 -0500
Subject: [PATCH 43/50] cmd/go: stop tests from using network during -short
It turned out that "go get" was using the network to look up
https://github.com?go-get=1 while resolving github.com/google/go-cmp,
and that is not the fastest page to load.
Stop that lookup by adjusting the path prefixes in the vcs table.
It also turned out that "go get" was using the network to look up
https://rsc.io?go-get=1 while resolving https://rsc.io/nonexist.svn.
That's a bit more defensible maybe, since rsc.io is not a known VCS host.
But for tests we really want to avoid the network entirely, so this CL
adds a special case in repoRootFromVCSPaths that returns a hard error
for plain "rsc.io" instead of doing the web fetch.
To keep us honest in the future, I added two automatically-set env
variables TESTGONETWORK=panic and TESTGOVCS=panic.
These cause the go command to panic rather than make a network request
or invoke a VCS command.
go test -short cmd/go now passes with these checks.
This reduced the time spent in go test -short cmd/go on my
Google workstation from 154s to 30s. (Yay network firewalls.)
Change-Id: I49207fca7f901fa011765fb984dc9cec8b691f11
Reviewed-on: https://go-review.googlesource.com/c/go/+/274441
Trust: Russ Cox
Trust: Jay Conrod
Run-TryBot: Russ Cox
Reviewed-by: Jay Conrod
---
.../go/internal/modfetch/codehost/codehost.go | 3 +
src/cmd/go/internal/vcs/vcs.go | 101 +++++++++---------
src/cmd/go/internal/web/http.go | 7 ++
src/cmd/go/script_test.go | 3 +
.../go/testdata/script/mod_sumdb_proxy.txt | 6 +-
5 files changed, 67 insertions(+), 53 deletions(-)
diff --git a/src/cmd/go/internal/modfetch/codehost/codehost.go b/src/cmd/go/internal/modfetch/codehost/codehost.go
index c5fbb31b2b..286d3f7220 100644
--- a/src/cmd/go/internal/modfetch/codehost/codehost.go
+++ b/src/cmd/go/internal/modfetch/codehost/codehost.go
@@ -264,6 +264,9 @@ func RunWithStdin(dir string, stdin io.Reader, cmdline ...interface{}) ([]byte,
}
cmd := str.StringList(cmdline...)
+ if os.Getenv("TESTGOVCS") == "panic" {
+ panic(fmt.Sprintf("use of vcs: %v", cmd))
+ }
if cfg.BuildX {
text := new(strings.Builder)
if dir != "" {
diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go
index e7bef9f591..4894ecdc35 100644
--- a/src/cmd/go/internal/vcs/vcs.go
+++ b/src/cmd/go/internal/vcs/vcs.go
@@ -23,6 +23,7 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/search"
+ "cmd/go/internal/str"
"cmd/go/internal/web"
"golang.org/x/mod/module"
@@ -539,7 +540,7 @@ func (v *Cmd) TagSync(dir, tag string) error {
// A vcsPath describes how to convert an import path into a
// version control system and repository name.
type vcsPath struct {
- prefix string // prefix this description applies to
+ pathPrefix string // prefix this description applies to
regexp *lazyregexp.Regexp // compiled pattern for import path
repo string // repository to use (expand with match of re)
vcs string // version control system to use (expand with match of re)
@@ -826,6 +827,20 @@ var errUnknownSite = errors.New("dynamic lookup required to find mapping")
// repoRootFromVCSPaths attempts to map importPath to a repoRoot
// using the mappings defined in vcsPaths.
func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths []*vcsPath) (*RepoRoot, error) {
+ if str.HasPathPrefix(importPath, "example.net") {
+ // TODO(rsc): This should not be necessary, but it's required to keep
+ // tests like ../../testdata/script/mod_get_extra.txt from using the network.
+ // That script has everything it needs in the replacement set, but it is still
+ // doing network calls.
+ return nil, fmt.Errorf("no modules on example.net")
+ }
+ if importPath == "rsc.io" {
+ // This special case allows tests like ../../testdata/script/govcs.txt
+ // to avoid making any network calls. The module lookup for a path
+ // like rsc.io/nonexist.svn/foo needs to not make a network call for
+ // a lookup on rsc.io.
+ return nil, fmt.Errorf("rsc.io is not a module")
+ }
// A common error is to use https://packagepath because that's what
// hg and git require. Diagnose this helpfully.
if prefix := httpPrefix(importPath); prefix != "" {
@@ -834,20 +849,20 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths
return nil, fmt.Errorf("%q not allowed in import path", prefix+"//")
}
for _, srv := range vcsPaths {
- if !strings.HasPrefix(importPath, srv.prefix) {
+ if !str.HasPathPrefix(importPath, srv.pathPrefix) {
continue
}
m := srv.regexp.FindStringSubmatch(importPath)
if m == nil {
- if srv.prefix != "" {
- return nil, importErrorf(importPath, "invalid %s import path %q", srv.prefix, importPath)
+ if srv.pathPrefix != "" {
+ return nil, importErrorf(importPath, "invalid %s import path %q", srv.pathPrefix, importPath)
}
continue
}
// Build map of named subexpression matches for expand.
match := map[string]string{
- "prefix": srv.prefix,
+ "prefix": srv.pathPrefix + "/",
"import": importPath,
}
for i, name := range srv.regexp.SubexpNames() {
@@ -1098,18 +1113,6 @@ type metaImport struct {
Prefix, VCS, RepoRoot string
}
-// pathPrefix reports whether sub is a prefix of s,
-// only considering entire path components.
-func pathPrefix(s, sub string) bool {
- // strings.HasPrefix is necessary but not sufficient.
- if !strings.HasPrefix(s, sub) {
- return false
- }
- // The remainder after the prefix must either be empty or start with a slash.
- rem := s[len(sub):]
- return rem == "" || rem[0] == '/'
-}
-
// A ImportMismatchError is returned where metaImport/s are present
// but none match our import path.
type ImportMismatchError struct {
@@ -1133,7 +1136,7 @@ func matchGoImport(imports []metaImport, importPath string) (metaImport, error)
errImportMismatch := ImportMismatchError{importPath: importPath}
for i, im := range imports {
- if !pathPrefix(importPath, im.Prefix) {
+ if !str.HasPathPrefix(importPath, im.Prefix) {
errImportMismatch.mismatches = append(errImportMismatch.mismatches, im.Prefix)
continue
}
@@ -1175,52 +1178,52 @@ func expand(match map[string]string, s string) string {
var vcsPaths = []*vcsPath{
// Github
{
- prefix: "github.com/",
- regexp: lazyregexp.New(`^(?Pgithub\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`),
- vcs: "git",
- repo: "https://{root}",
- check: noVCSSuffix,
+ pathPrefix: "github.com",
+ regexp: lazyregexp.New(`^(?Pgithub\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`),
+ vcs: "git",
+ repo: "https://{root}",
+ check: noVCSSuffix,
},
// Bitbucket
{
- prefix: "bitbucket.org/",
- regexp: lazyregexp.New(`^(?Pbitbucket\.org/(?P[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`),
- repo: "https://{root}",
- check: bitbucketVCS,
+ pathPrefix: "bitbucket.org",
+ regexp: lazyregexp.New(`^(?Pbitbucket\.org/(?P[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`),
+ repo: "https://{root}",
+ check: bitbucketVCS,
},
// IBM DevOps Services (JazzHub)
{
- prefix: "hub.jazz.net/git/",
- regexp: lazyregexp.New(`^(?Phub\.jazz\.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`),
- vcs: "git",
- repo: "https://{root}",
- check: noVCSSuffix,
+ pathPrefix: "hub.jazz.net/git",
+ regexp: lazyregexp.New(`^(?Phub\.jazz\.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`),
+ vcs: "git",
+ repo: "https://{root}",
+ check: noVCSSuffix,
},
// Git at Apache
{
- prefix: "git.apache.org/",
- regexp: lazyregexp.New(`^(?Pgit\.apache\.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`),
- vcs: "git",
- repo: "https://{root}",
+ pathPrefix: "git.apache.org",
+ regexp: lazyregexp.New(`^(?Pgit\.apache\.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`),
+ vcs: "git",
+ repo: "https://{root}",
},
// Git at OpenStack
{
- prefix: "git.openstack.org/",
- regexp: lazyregexp.New(`^(?Pgit\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`),
- vcs: "git",
- repo: "https://{root}",
+ pathPrefix: "git.openstack.org",
+ regexp: lazyregexp.New(`^(?Pgit\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`),
+ vcs: "git",
+ repo: "https://{root}",
},
// chiselapp.com for fossil
{
- prefix: "chiselapp.com/",
- regexp: lazyregexp.New(`^(?Pchiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`),
- vcs: "fossil",
- repo: "https://{root}",
+ pathPrefix: "chiselapp.com",
+ regexp: lazyregexp.New(`^(?Pchiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`),
+ vcs: "fossil",
+ repo: "https://{root}",
},
// General syntax for any server.
@@ -1238,11 +1241,11 @@ var vcsPaths = []*vcsPath{
var vcsPathsAfterDynamic = []*vcsPath{
// Launchpad. See golang.org/issue/11436.
{
- prefix: "launchpad.net/",
- regexp: lazyregexp.New(`^(?Plaunchpad\.net/((?P[A-Za-z0-9_.\-]+)(?P/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`),
- vcs: "bzr",
- repo: "https://{root}",
- check: launchpadVCS,
+ pathPrefix: "launchpad.net",
+ regexp: lazyregexp.New(`^(?Plaunchpad\.net/((?P[A-Za-z0-9_.\-]+)(?P/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`),
+ vcs: "bzr",
+ repo: "https://{root}",
+ check: launchpadVCS,
},
}
diff --git a/src/cmd/go/internal/web/http.go b/src/cmd/go/internal/web/http.go
index e0509808d6..72fa2b2ca6 100644
--- a/src/cmd/go/internal/web/http.go
+++ b/src/cmd/go/internal/web/http.go
@@ -80,6 +80,13 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) {
return res, nil
}
+ if url.Host == "localhost.localdev" {
+ return nil, fmt.Errorf("no such host localhost.localdev")
+ }
+ if os.Getenv("TESTGONETWORK") == "panic" && !strings.HasPrefix(url.Host, "127.0.0.1") && !strings.HasPrefix(url.Host, "0.0.0.0") {
+ panic("use of network: " + url.String())
+ }
+
fetch := func(url *urlpkg.URL) (*urlpkg.URL, *http.Response, error) {
// Note: The -v build flag does not mean "print logging information",
// despite its historical misuse for this in GOPATH-based go get.
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index b1d1499038..aee3742f13 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -142,6 +142,9 @@ func (ts *testScript) setup() {
"goversion=" + goVersion(ts),
":=" + string(os.PathListSeparator),
}
+ if !testenv.HasExternalNetwork() {
+ ts.env = append(ts.env, "TESTGONETWORK=panic", "TESTGOVCS=panic")
+ }
if runtime.GOOS == "plan9" {
ts.env = append(ts.env, "path="+testBin+string(filepath.ListSeparator)+os.Getenv("path"))
diff --git a/src/cmd/go/testdata/script/mod_sumdb_proxy.txt b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt
index 7bbc3f9e19..70b8e3fc44 100644
--- a/src/cmd/go/testdata/script/mod_sumdb_proxy.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt
@@ -17,14 +17,12 @@ rm $GOPATH/pkg/mod/cache/download/sumdb
rm go.sum
# direct access fails (because localhost.localdev does not exist)
-# The text of the error message is hard to predict because some DNS servers
-# will resolve unknown domains like localhost.localdev to a real IP
-# to serve ads.
+# web.get is providing the error message - there's no actual network access.
cp go.mod.orig go.mod
env GOSUMDB=$sumdb
env GOPROXY=direct
! go get -d rsc.io/fortune@v1.0.0
-stderr 'verifying.*localhost.localdev'
+stderr 'verifying module: rsc.io/fortune@v1.0.0: .*: no such host localhost.localdev'
rm $GOPATH/pkg/mod/cache/download/sumdb
rm go.sum
From 05ddb879c73bc0c84ed1a80864aaf27b4a3d032f Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Wed, 2 Dec 2020 12:56:29 -0500
Subject: [PATCH 44/50] cmd/go: fix TestNewReleaseRebuildsStalePackagesInGOPATH
Broken during CL 267719.
Change-Id: If5acb8231d3053c0e714a79c02cb56eaba6e74e6
Reviewed-on: https://go-review.googlesource.com/c/go/+/274854
Trust: Russ Cox
Run-TryBot: Russ Cox
TryBot-Result: Go Bot
Reviewed-by: Jay Conrod
---
src/cmd/go/go_test.go | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index a730c87f97..1b8a21ecfa 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -838,6 +838,9 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
return err
}
tg.tempFile(dest, string(data))
+ if strings.Contains(copydir, filepath.Join("pkg", "tool")) {
+ os.Chmod(tg.path(dest), 0777)
+ }
return nil
})
if err != nil {
From 2d0258d49568d4b34f5c4dec53985bb80bf370cc Mon Sep 17 00:00:00 2001
From: Filippo Valsorda
Date: Wed, 25 Nov 2020 02:40:32 +0100
Subject: [PATCH 45/50] crypto/ed25519/internal/edwards25519: fix typo in
comments
Change-Id: I8133762d53d9e5d3cc13e0f97b9679a3248a7f0f
Reviewed-on: https://go-review.googlesource.com/c/go/+/273087
Trust: Filippo Valsorda
Reviewed-by: Katie Hockman
---
src/crypto/ed25519/internal/edwards25519/edwards25519.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/crypto/ed25519/internal/edwards25519/edwards25519.go b/src/crypto/ed25519/internal/edwards25519/edwards25519.go
index fd03c252af..b091481b77 100644
--- a/src/crypto/ed25519/internal/edwards25519/edwards25519.go
+++ b/src/crypto/ed25519/internal/edwards25519/edwards25519.go
@@ -722,7 +722,7 @@ func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool {
FeOne(&p.Z)
FeSquare(&u, &p.Y)
FeMul(&v, &u, &d)
- FeSub(&u, &u, &p.Z) // y = y^2-1
+ FeSub(&u, &u, &p.Z) // u = y^2-1
FeAdd(&v, &v, &p.Z) // v = dy^2+1
FeSquare(&v3, &v)
From 48838c35dc7c8e938a83db66faabf3a51f4adc3d Mon Sep 17 00:00:00 2001
From: Carlos Alexandro Becker
Date: Wed, 2 Dec 2020 21:04:13 +0000
Subject: [PATCH 46/50] go/parser: ignore subdirectories in ParseDir
Issue and PR on GoReleaser:
- https://github.com/goreleaser/goreleaser/issues/1897
- https://github.com/goreleaser/goreleaser/pull/1899
Fixes #42951.
Change-Id: Ia0d6018e0bad59cd60cd600188c368c431032a4b
GitHub-Last-Rev: be59d85fe2d473f4dfd828a244023c4064d6e31f
GitHub-Pull-Request: golang/go#42581
Reviewed-on: https://go-review.googlesource.com/c/go/+/269897
Trust: Robert Griesemer
Trust: Dmitri Shuralyov
Run-TryBot: Robert Griesemer
Reviewed-by: Robert Griesemer
---
src/go/parser/interface.go | 2 +-
src/go/parser/parser_test.go | 8 ++++++++
.../parser/testdata/issue42951/not_a_file.go/invalid.go | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
create mode 100644 src/go/parser/testdata/issue42951/not_a_file.go/invalid.go
diff --git a/src/go/parser/interface.go b/src/go/parser/interface.go
index cc7e455c4d..d5c18a9e2d 100644
--- a/src/go/parser/interface.go
+++ b/src/go/parser/interface.go
@@ -140,7 +140,7 @@ func ParseDir(fset *token.FileSet, path string, filter func(fs.FileInfo) bool, m
pkgs = make(map[string]*ast.Package)
for _, d := range list {
- if strings.HasSuffix(d.Name(), ".go") && (filter == nil || filter(d)) {
+ if !d.IsDir() && strings.HasSuffix(d.Name(), ".go") && (filter == nil || filter(d)) {
filename := filepath.Join(path, d.Name())
if src, err := ParseFile(fset, filename, nil, mode); err == nil {
name := src.Name.Name
diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go
index 7193a329fe..a4f882d368 100644
--- a/src/go/parser/parser_test.go
+++ b/src/go/parser/parser_test.go
@@ -82,6 +82,14 @@ func TestParseDir(t *testing.T) {
}
}
+func TestIssue42951(t *testing.T) {
+ path := "./testdata/issue42951"
+ _, err := ParseDir(token.NewFileSet(), path, nil, 0)
+ if err != nil {
+ t.Errorf("ParseDir(%s): %v", path, err)
+ }
+}
+
func TestParseExpr(t *testing.T) {
// just kicking the tires:
// a valid arithmetic expression
diff --git a/src/go/parser/testdata/issue42951/not_a_file.go/invalid.go b/src/go/parser/testdata/issue42951/not_a_file.go/invalid.go
new file mode 100644
index 0000000000..bb698be11c
--- /dev/null
+++ b/src/go/parser/testdata/issue42951/not_a_file.go/invalid.go
@@ -0,0 +1 @@
+This file should not be parsed by ParseDir.
From f26f227f66ff4113cad0cd51c0780e5849e9accc Mon Sep 17 00:00:00 2001
From: Roland Shoemaker
Date: Tue, 1 Dec 2020 13:02:44 -0800
Subject: [PATCH 47/50] doc/go1.16: add crypto/tls Config.Clone note
For #40700
Fixes #42896
Change-Id: I842c9d60b18abe2ee061c6705a5c7ba62b224d77
Reviewed-on: https://go-review.googlesource.com/c/go/+/274613
Trust: Roland Shoemaker
Reviewed-by: Dmitri Shuralyov
---
doc/go1.16.html | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/doc/go1.16.html b/doc/go1.16.html
index ffdbc97c62..2132cbc9c1 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -405,7 +405,8 @@ Do not send CLs removing the interior tags from such phrases.
- TODO: https://golang.org/cl/246637: make config.Clone return nil if the source is nil
+ Config.Clone now returns
+ a nil *Config if the source is nil, rather than panicking.
From 78e442ea79294480c28e44b21702c6452e704110 Mon Sep 17 00:00:00 2001
From: Joe Tsai
Date: Tue, 1 Dec 2020 14:59:23 -0800
Subject: [PATCH 48/50] doc/go1.16: add encoding/json note for tag change
For #40700
Fixes #42898
Change-Id: I652657ff8d6cce20bf868f0b1101d723d3f704d1
Reviewed-on: https://go-review.googlesource.com/c/go/+/274614
Trust: Joe Tsai
Reviewed-by: Dmitri Shuralyov
---
doc/go1.16.html | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 2132cbc9c1..086557ca48 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -456,7 +456,11 @@ Do not send CLs removing the interior tags from such phrases.
- TODO: https://golang.org/cl/234818: allow semicolon in field key / struct tag
+ The json struct field tags understood by
+ Marshal,
+ Unmarshal,
+ and related functionality now permit semicolon characters within
+ a JSON object name for a Go struct field.
From da54dfb6a1f3bef827b9ec3780c98fde77a97d11 Mon Sep 17 00:00:00 2001
From: KimMachineGun
Date: Sun, 29 Nov 2020 08:18:12 +0000
Subject: [PATCH 49/50] doc/go1.16: document new behavior of asn1.Unmarshal on
invalid argument
For #41509
Change-Id: Ie761c428710d15848cb80ffd2d85de747113f2d4
GitHub-Last-Rev: 05541624593d945d82b6f4cfae1461654eabea7b
GitHub-Pull-Request: golang/go#42315
Reviewed-on: https://go-review.googlesource.com/c/go/+/267057
Trust: Dmitri Shuralyov
Reviewed-by: Ian Lance Taylor
---
doc/go1.16.html | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 086557ca48..f8b2c3f371 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -453,6 +453,18 @@ Do not send CLs removing the interior tags from such phrases.
+
+ Unmarshal and
+ UnmarshalWithParams
+ now return an error instead of panic when the argument is not
+ a pointer or is nil. This change matches the behavior of other
+ encoding packages such as encoding/json.
+