From 1402b27d465d9949027a048ea2c86a3583400b4c Mon Sep 17 00:00:00 2001
From: Damien Neil
Date: Mon, 7 Jun 2021 16:30:03 -0700
Subject: [PATCH 25/45] strconv: document parsing of leading +/-
Explicitly document the handling of a sign prefix, and the interaction
between the sign and base prefixes.
Fixes #46641.
Change-Id: I3cd6773e3f074fe671a944a05a79d2408137fcd4
Reviewed-on: https://go-review.googlesource.com/c/go/+/325875
Trust: Damien Neil
Run-TryBot: Damien Neil
TryBot-Result: Go Bot
Reviewed-by: Rob Pike
---
src/strconv/atoi.go | 11 ++++++++---
src/strconv/atoi_test.go | 10 ++++++++++
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/src/strconv/atoi.go b/src/strconv/atoi.go
index c9ba0383b3..631b487d97 100644
--- a/src/strconv/atoi.go
+++ b/src/strconv/atoi.go
@@ -57,6 +57,8 @@ const IntSize = intSize
const maxUint64 = 1<<64 - 1
// ParseUint is like ParseInt but for unsigned numbers.
+//
+// A sign prefix is not permitted.
func ParseUint(s string, base int, bitSize int) (uint64, error) {
const fnParseUint = "ParseUint"
@@ -159,10 +161,13 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) {
// ParseInt interprets a string s in the given base (0, 2 to 36) and
// bit size (0 to 64) and returns the corresponding value i.
//
+// The string may begin with a leading sign: "+" or "-".
+//
// If the base argument is 0, the true base is implied by the string's
-// prefix: 2 for "0b", 8 for "0" or "0o", 16 for "0x", and 10 otherwise.
-// Also, for argument base 0 only, underscore characters are permitted
-// as defined by the Go syntax for integer literals.
+// prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o",
+// 16 for "0x", and 10 otherwise. Also, for argument base 0 only,
+// underscore characters are permitted as defined by the Go syntax for
+// integer literals.
//
// The bitSize argument specifies the integer type
// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
diff --git a/src/strconv/atoi_test.go b/src/strconv/atoi_test.go
index 178fb01ea7..867fa66a14 100644
--- a/src/strconv/atoi_test.go
+++ b/src/strconv/atoi_test.go
@@ -33,6 +33,9 @@ var parseUint64Tests = []parseUint64Test{
{"_12345", 0, ErrSyntax},
{"1__2345", 0, ErrSyntax},
{"12345_", 0, ErrSyntax},
+ {"-0", 0, ErrSyntax},
+ {"-1", 0, ErrSyntax},
+ {"+1", 0, ErrSyntax},
}
type parseUint64BaseTest struct {
@@ -140,8 +143,10 @@ var parseInt64Tests = []parseInt64Test{
{"", 0, ErrSyntax},
{"0", 0, nil},
{"-0", 0, nil},
+ {"+0", 0, nil},
{"1", 1, nil},
{"-1", -1, nil},
+ {"+1", 1, nil},
{"12345", 12345, nil},
{"-12345", -12345, nil},
{"012345", 12345, nil},
@@ -236,6 +241,11 @@ var parseInt64BaseTests = []parseInt64BaseTest{
{"0__12345", 0, 0, ErrSyntax},
{"01234__5", 0, 0, ErrSyntax},
{"012345_", 0, 0, ErrSyntax},
+
+ {"+0xf", 0, 0xf, nil},
+ {"-0xf", 0, -0xf, nil},
+ {"0x+f", 0, 0, ErrSyntax},
+ {"0x-f", 0, 0, ErrSyntax},
}
type parseUint32Test struct {
From a5bc060b42fe1bee8910a1081eff0a1047b15869 Mon Sep 17 00:00:00 2001
From: Damien Neil
Date: Tue, 8 Jun 2021 14:26:13 -0700
Subject: [PATCH 26/45] doc/go1.17: document strconv changes for Go 1.17
For #44513.
Fixes #46021.
Change-Id: I40a4645fedfae24f67e249743c6a143e71b9f507
Reviewed-on: https://go-review.googlesource.com/c/go/+/326150
Trust: Damien Neil
Run-TryBot: Damien Neil
TryBot-Result: Go Bot
Reviewed-by: Heschi Kreinick
Reviewed-by: Dmitri Shuralyov
---
doc/go1.17.html | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index 6c53aaaa88..988026f44d 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -838,12 +838,9 @@ func Foo() bool {
- strconv
-
-
- TODO: https://golang.org/cl/170079: implement Ryū-like algorithm for fixed precision ftoa
-
-
-
- TODO: https://golang.org/cl/170080: Implement Ryū algorithm for ftoa shortest mode
+
+ The strconv
package now uses Ulf Adams's Ryū algorithm for formatting floating-point numbers.
+ This algorithm improves performance on most inputs, and is more than 99% faster on worst-case inputs.
From 182157c81ad5a147ba13c6e80f844b2242598aed Mon Sep 17 00:00:00 2001
From: Heschi Kreinick
Date: Wed, 9 Jun 2021 12:59:30 -0400
Subject: [PATCH 27/45] doc/go1.17: remove lingering TODO
As far as I can tell the Core Library section is complete. Remove its
TODO.
Change-Id: Ia84c6656fac045e25fae1a7ce8b488a3a26fd250
Reviewed-on: https://go-review.googlesource.com/c/go/+/326469
Trust: Heschi Kreinick
Run-TryBot: Heschi Kreinick
TryBot-Result: Go Bot
Reviewed-by: Dmitri Shuralyov
Reviewed-by: Damien Neil
---
doc/go1.17.html | 4 ----
1 file changed, 4 deletions(-)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index 988026f44d..49fbabdc3f 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -418,10 +418,6 @@ func Foo() bool {
Core library
-
- TODO: complete the Core library section
-
-
From 27f83723e98d8e3795a07bdca2b3a8155b0d72b3 Mon Sep 17 00:00:00 2001
From: Heschi Kreinick
Date: Wed, 9 Jun 2021 15:21:39 -0400
Subject: [PATCH 28/45] api: promote next to go1.17
Change-Id: If631878a2f6ec0317b4fad614f98ab102810ed47
Reviewed-on: https://go-review.googlesource.com/c/go/+/326410
Trust: Heschi Kreinick
Run-TryBot: Heschi Kreinick
TryBot-Result: Go Bot
Reviewed-by: Dmitri Shuralyov
---
api/go1.17.txt | 159 +++++++++++++++++++++++++++++++++++++++++++++++++
api/next.txt | 99 ------------------------------
2 files changed, 159 insertions(+), 99 deletions(-)
create mode 100644 api/go1.17.txt
diff --git a/api/go1.17.txt b/api/go1.17.txt
new file mode 100644
index 0000000000..f054458715
--- /dev/null
+++ b/api/go1.17.txt
@@ -0,0 +1,159 @@
+pkg archive/zip, method (*File) OpenRaw() (io.Reader, error)
+pkg archive/zip, method (*Writer) Copy(*File) error
+pkg archive/zip, method (*Writer) CreateRaw(*FileHeader) (io.Writer, error)
+pkg compress/lzw, method (*Reader) Close() error
+pkg compress/lzw, method (*Reader) Read([]uint8) (int, error)
+pkg compress/lzw, method (*Reader) Reset(io.Reader, Order, int)
+pkg compress/lzw, method (*Writer) Close() error
+pkg compress/lzw, method (*Writer) Reset(io.Writer, Order, int)
+pkg compress/lzw, method (*Writer) Write([]uint8) (int, error)
+pkg compress/lzw, type Reader struct
+pkg compress/lzw, type Writer struct
+pkg crypto/tls, method (*CertificateRequestInfo) Context() context.Context
+pkg crypto/tls, method (*ClientHelloInfo) Context() context.Context
+pkg crypto/tls, method (*Conn) HandshakeContext(context.Context) error
+pkg database/sql, method (*NullByte) Scan(interface{}) error
+pkg database/sql, method (*NullInt16) Scan(interface{}) error
+pkg database/sql, method (NullByte) Value() (driver.Value, error)
+pkg database/sql, method (NullInt16) Value() (driver.Value, error)
+pkg database/sql, type NullByte struct
+pkg database/sql, type NullByte struct, Byte uint8
+pkg database/sql, type NullByte struct, Valid bool
+pkg database/sql, type NullInt16 struct
+pkg database/sql, type NullInt16 struct, Int16 int16
+pkg database/sql, type NullInt16 struct, Valid bool
+pkg debug/elf, const SHT_MIPS_ABIFLAGS = 1879048234
+pkg debug/elf, const SHT_MIPS_ABIFLAGS SectionType
+pkg encoding/csv, method (*Reader) FieldPos(int) (int, int)
+pkg go/build, type Context struct, ToolTags []string
+pkg go/parser, const SkipObjectResolution = 64
+pkg go/parser, const SkipObjectResolution Mode
+pkg io/fs, func FileInfoToDirEntry(FileInfo) DirEntry
+pkg math, const MaxFloat64 = 1.79769e+308 // 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
+pkg math, const MaxInt = 9223372036854775807
+pkg math, const MaxInt ideal-int
+pkg math, const MaxUint = 18446744073709551615
+pkg math, const MaxUint ideal-int
+pkg math, const MinInt = -9223372036854775808
+pkg math, const MinInt ideal-int
+pkg math, const SmallestNonzeroFloat32 = 1.4013e-45 // 1/713623846352979940529142984724747568191373312
+pkg math, const SmallestNonzeroFloat64 = 4.94066e-324 // 1/202402253307310618352495346718917307049556649764142118356901358027430339567995346891960383701437124495187077864316811911389808737385793476867013399940738509921517424276566361364466907742093216341239767678472745068562007483424692698618103355649159556340810056512358769552333414615230502532186327508646006263307707741093494784
+pkg net, method (*ParseError) Temporary() bool
+pkg net, method (*ParseError) Timeout() bool
+pkg net, method (IP) IsPrivate() bool
+pkg net/http, func AllowQuerySemicolons(Handler) Handler
+pkg net/url, method (Values) Has(string) bool
+pkg reflect, func VisibleFields(Type) []StructField
+pkg reflect, method (Method) IsExported() bool
+pkg reflect, method (StructField) IsExported() bool
+pkg runtime/cgo (darwin-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (darwin-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (freebsd-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (freebsd-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (freebsd-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (freebsd-386-cgo), type Handle uintptr
+pkg runtime/cgo (freebsd-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (freebsd-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (freebsd-arm-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Delete()
+pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (freebsd-arm-cgo), type Handle uintptr
+pkg runtime/cgo (linux-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (linux-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (linux-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (linux-386-cgo), type Handle uintptr
+pkg runtime/cgo (linux-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (linux-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (linux-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (linux-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (linux-arm-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (linux-arm-cgo), method (Handle) Delete()
+pkg runtime/cgo (linux-arm-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (linux-arm-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-386-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-amd64-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-arm-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-arm-cgo), type Handle uintptr
+pkg runtime/cgo (netbsd-arm64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Delete()
+pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (netbsd-arm64-cgo), type Handle uintptr
+pkg runtime/cgo (openbsd-386-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (openbsd-386-cgo), method (Handle) Delete()
+pkg runtime/cgo (openbsd-386-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (openbsd-386-cgo), type Handle uintptr
+pkg runtime/cgo (openbsd-amd64-cgo), func NewHandle(interface{}) Handle
+pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Delete()
+pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Value() interface{}
+pkg runtime/cgo (openbsd-amd64-cgo), type Handle uintptr
+pkg strconv, func QuotedPrefix(string) (string, error)
+pkg sync/atomic, method (*Value) CompareAndSwap(interface{}, interface{}) bool
+pkg sync/atomic, method (*Value) Swap(interface{}) interface{}
+pkg syscall (netbsd-386), const SYS_WAIT6 = 481
+pkg syscall (netbsd-386), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-386), const WEXITED = 32
+pkg syscall (netbsd-386), const WEXITED ideal-int
+pkg syscall (netbsd-386-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-386-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-386-cgo), const WEXITED = 32
+pkg syscall (netbsd-386-cgo), const WEXITED ideal-int
+pkg syscall (netbsd-amd64), const SYS_WAIT6 = 481
+pkg syscall (netbsd-amd64), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-amd64), const WEXITED = 32
+pkg syscall (netbsd-amd64), const WEXITED ideal-int
+pkg syscall (netbsd-amd64-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-amd64-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-amd64-cgo), const WEXITED = 32
+pkg syscall (netbsd-amd64-cgo), const WEXITED ideal-int
+pkg syscall (netbsd-arm), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm), const WEXITED = 32
+pkg syscall (netbsd-arm), const WEXITED ideal-int
+pkg syscall (netbsd-arm-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm-cgo), const WEXITED = 32
+pkg syscall (netbsd-arm-cgo), const WEXITED ideal-int
+pkg syscall (netbsd-arm64), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm64), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm64), const WEXITED = 32
+pkg syscall (netbsd-arm64), const WEXITED ideal-int
+pkg syscall (netbsd-arm64-cgo), const SYS_WAIT6 = 481
+pkg syscall (netbsd-arm64-cgo), const SYS_WAIT6 ideal-int
+pkg syscall (netbsd-arm64-cgo), const WEXITED = 32
+pkg syscall (netbsd-arm64-cgo), const WEXITED ideal-int
+pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC = 2048
+pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC ideal-int
+pkg syscall (windows-386), type SysProcAttr struct, AdditionalInheritedHandles []Handle
+pkg syscall (windows-386), type SysProcAttr struct, ParentProcess Handle
+pkg syscall (windows-amd64), type SysProcAttr struct, AdditionalInheritedHandles []Handle
+pkg syscall (windows-amd64), type SysProcAttr struct, ParentProcess Handle
+pkg testing, method (*B) Setenv(string, string)
+pkg testing, method (*T) Setenv(string, string)
+pkg text/template/parse, const SkipFuncCheck = 2
+pkg text/template/parse, const SkipFuncCheck Mode
+pkg time, const Layout = "01/02 03:04:05PM '06 -0700"
+pkg time, const Layout ideal-string
+pkg time, func UnixMicro(int64) Time
+pkg time, func UnixMilli(int64) Time
+pkg time, method (*Time) IsDST() bool
+pkg time, method (Time) GoString() string
+pkg time, method (Time) UnixMicro() int64
+pkg time, method (Time) UnixMilli() int64
diff --git a/api/next.txt b/api/next.txt
index 9e996005c6..e69de29bb2 100644
--- a/api/next.txt
+++ b/api/next.txt
@@ -1,99 +0,0 @@
-pkg compress/lzw, method (*Reader) Close() error
-pkg compress/lzw, method (*Reader) Read([]uint8) (int, error)
-pkg compress/lzw, method (*Reader) Reset(io.Reader, Order, int)
-pkg compress/lzw, method (*Writer) Close() error
-pkg compress/lzw, method (*Writer) Reset(io.Writer, Order, int)
-pkg compress/lzw, method (*Writer) Write([]uint8) (int, error)
-pkg compress/lzw, type Reader struct
-pkg compress/lzw, type Writer struct
-pkg crypto/tls, method (*CertificateRequestInfo) Context() context.Context
-pkg crypto/tls, method (*ClientHelloInfo) Context() context.Context
-pkg crypto/tls, method (*Conn) HandshakeContext(context.Context) error
-pkg debug/elf, const SHT_MIPS_ABIFLAGS = 1879048234
-pkg debug/elf, const SHT_MIPS_ABIFLAGS SectionType
-pkg encoding/csv, method (*Reader) FieldPos(int) (int, int)
-pkg go/ast, method (*FuncDecl) IsMethod() bool
-pkg go/build, type Context struct, ToolTags []string
-pkg go/parser, const SkipObjectResolution = 64
-pkg go/parser, const SkipObjectResolution Mode
-pkg go/types, type Config struct, GoVersion string
-pkg io/fs, func FileInfoToDirEntry(FileInfo) DirEntry
-pkg net, method (*ParseError) Temporary() bool
-pkg net, method (*ParseError) Timeout() bool
-pkg net, method (IP) IsPrivate() bool
-pkg reflect, func VisibleFields(Type) []StructField
-pkg reflect, method (Method) IsExported() bool
-pkg reflect, method (StructField) IsExported() bool
-pkg runtime/cgo (darwin-amd64-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Delete()
-pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (darwin-amd64-cgo), type Handle uintptr
-pkg runtime/cgo (freebsd-386-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (freebsd-386-cgo), method (Handle) Delete()
-pkg runtime/cgo (freebsd-386-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (freebsd-386-cgo), type Handle uintptr
-pkg runtime/cgo (freebsd-amd64-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Delete()
-pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (freebsd-amd64-cgo), type Handle uintptr
-pkg runtime/cgo (freebsd-arm-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Delete()
-pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (freebsd-arm-cgo), type Handle uintptr
-pkg runtime/cgo (linux-386-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (linux-386-cgo), method (Handle) Delete()
-pkg runtime/cgo (linux-386-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (linux-386-cgo), type Handle uintptr
-pkg runtime/cgo (linux-amd64-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (linux-amd64-cgo), method (Handle) Delete()
-pkg runtime/cgo (linux-amd64-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (linux-amd64-cgo), type Handle uintptr
-pkg runtime/cgo (linux-arm-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (linux-arm-cgo), method (Handle) Delete()
-pkg runtime/cgo (linux-arm-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (linux-arm-cgo), type Handle uintptr
-pkg runtime/cgo (netbsd-386-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (netbsd-386-cgo), method (Handle) Delete()
-pkg runtime/cgo (netbsd-386-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (netbsd-386-cgo), type Handle uintptr
-pkg runtime/cgo (netbsd-amd64-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Delete()
-pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (netbsd-amd64-cgo), type Handle uintptr
-pkg runtime/cgo (netbsd-arm-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Delete()
-pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (netbsd-arm-cgo), type Handle uintptr
-pkg runtime/cgo (netbsd-arm64-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Delete()
-pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (netbsd-arm64-cgo), type Handle uintptr
-pkg runtime/cgo (openbsd-386-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (openbsd-386-cgo), method (Handle) Delete()
-pkg runtime/cgo (openbsd-386-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (openbsd-386-cgo), type Handle uintptr
-pkg runtime/cgo (openbsd-amd64-cgo), func NewHandle(interface{}) Handle
-pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Delete()
-pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Value() interface{}
-pkg runtime/cgo (openbsd-amd64-cgo), type Handle uintptr
-pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC = 2048
-pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC ideal-int
-pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC = 2048
-pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC ideal-int
-pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC = 2048
-pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC ideal-int
-pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC = 2048
-pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC ideal-int
-pkg syscall (windows-386), type SysProcAttr struct, AdditionalInheritedHandles []Handle
-pkg syscall (windows-386), type SysProcAttr struct, ParentProcess Handle
-pkg syscall (windows-amd64), type SysProcAttr struct, AdditionalInheritedHandles []Handle
-pkg syscall (windows-amd64), type SysProcAttr struct, ParentProcess Handle
-pkg testing, method (*B) Setenv(string, string)
-pkg testing, method (*T) Setenv(string, string)
-pkg text/template/parse, const SkipFuncCheck = 2
-pkg text/template/parse, const SkipFuncCheck Mode
-pkg time, func UnixMicro(int64) Time
-pkg time, func UnixMilli(int64) Time
-pkg time, method (*Time) IsDST() bool
-pkg time, method (Time) UnixMicro() int64
-pkg time, method (Time) UnixMilli() int64
From dc00dc6c6bf3b5554e37f60799aec092276ff807 Mon Sep 17 00:00:00 2001
From: Filippo Valsorda
Date: Mon, 7 Jun 2021 08:24:22 -0400
Subject: [PATCH 29/45] crypto/tls: let HTTP/1.1 clients connect to servers
with NextProtos "h2"
Fixes #46310
Change-Id: Idd5e30f05c439f736ae6f3904cbb9cc2ba772315
Reviewed-on: https://go-review.googlesource.com/c/go/+/325432
Trust: Filippo Valsorda
Run-TryBot: Filippo Valsorda
TryBot-Result: Go Bot
Reviewed-by: Roland Shoemaker
---
src/crypto/tls/handshake_client.go | 44 ++++----
src/crypto/tls/handshake_client_tls13.go | 14 +--
src/crypto/tls/handshake_server.go | 42 ++++++--
src/crypto/tls/handshake_server_test.go | 21 ++++
src/crypto/tls/handshake_server_tls13.go | 15 ++-
.../tls/testdata/Server-TLSv12-ALPN-Fallback | 91 ++++++++++++++++
.../tls/testdata/Server-TLSv13-ALPN-Fallback | 100 ++++++++++++++++++
7 files changed, 277 insertions(+), 50 deletions(-)
create mode 100644 src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
create mode 100644 src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index 13a7f3442c..4af3d998a3 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -711,17 +711,11 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
}
}
- if hs.serverHello.alpnProtocol != "" {
- if len(hs.hello.alpnProtocols) == 0 {
- c.sendAlert(alertUnsupportedExtension)
- return false, errors.New("tls: server advertised unrequested ALPN extension")
- }
- if mutualProtocol([]string{hs.serverHello.alpnProtocol}, hs.hello.alpnProtocols) == "" {
- c.sendAlert(alertUnsupportedExtension)
- return false, errors.New("tls: server selected unadvertised ALPN protocol")
- }
- c.clientProtocol = hs.serverHello.alpnProtocol
+ if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return false, err
}
+ c.clientProtocol = hs.serverHello.alpnProtocol
c.scts = hs.serverHello.scts
@@ -753,6 +747,23 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
return true, nil
}
+// checkALPN ensure that the server's choice of ALPN protocol is compatible with
+// the protocols that we advertised in the Client Hello.
+func checkALPN(clientProtos []string, serverProto string) error {
+ if serverProto == "" {
+ return nil
+ }
+ if len(clientProtos) == 0 {
+ return errors.New("tls: server advertised unrequested ALPN extension")
+ }
+ for _, proto := range clientProtos {
+ if proto == serverProto {
+ return nil
+ }
+ }
+ return errors.New("tls: server selected unadvertised ALPN protocol")
+}
+
func (hs *clientHandshakeState) readFinished(out []byte) error {
c := hs.c
@@ -979,19 +990,6 @@ func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
return serverAddr.String()
}
-// mutualProtocol finds the mutual ALPN protocol given list of possible
-// protocols and a list of the preference order.
-func mutualProtocol(protos, preferenceProtos []string) string {
- for _, s := range preferenceProtos {
- for _, c := range protos {
- if s == c {
- return s
- }
- }
- }
- return ""
-}
-
// hostnameInSNI converts name into an appropriate hostname for SNI.
// Literal IP addresses and absolute FQDNs are not permitted as SNI values.
// See RFC 6066, Section 3.
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index be37c681c6..eb59ac90d1 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -396,17 +396,11 @@ func (hs *clientHandshakeStateTLS13) readServerParameters() error {
}
hs.transcript.Write(encryptedExtensions.marshal())
- if encryptedExtensions.alpnProtocol != "" {
- if len(hs.hello.alpnProtocols) == 0 {
- c.sendAlert(alertUnsupportedExtension)
- return errors.New("tls: server advertised unrequested ALPN extension")
- }
- if mutualProtocol([]string{encryptedExtensions.alpnProtocol}, hs.hello.alpnProtocols) == "" {
- c.sendAlert(alertUnsupportedExtension)
- return errors.New("tls: server selected unadvertised ALPN protocol")
- }
- c.clientProtocol = encryptedExtensions.alpnProtocol
+ if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return err
}
+ c.clientProtocol = encryptedExtensions.alpnProtocol
return nil
}
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
index b231981e09..43f30e2fef 100644
--- a/src/crypto/tls/handshake_server.go
+++ b/src/crypto/tls/handshake_server.go
@@ -217,15 +217,13 @@ func (hs *serverHandshakeState) processClientHello() error {
c.serverName = hs.clientHello.serverName
}
- if len(c.config.NextProtos) > 0 && len(hs.clientHello.alpnProtocols) > 0 {
- selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos)
- if selectedProto == "" {
- c.sendAlert(alertNoApplicationProtocol)
- return fmt.Errorf("tls: client requested unsupported application protocols (%s)", hs.clientHello.alpnProtocols)
- }
- hs.hello.alpnProtocol = selectedProto
- c.clientProtocol = selectedProto
+ selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
+ if err != nil {
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
}
+ hs.hello.alpnProtocol = selectedProto
+ c.clientProtocol = selectedProto
hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
if err != nil {
@@ -277,6 +275,34 @@ func (hs *serverHandshakeState) processClientHello() error {
return nil
}
+// negotiateALPN picks a shared ALPN protocol that both sides support in server
+// preference order. If ALPN is not configured or the peer doesn't support it,
+// it returns "" and no error.
+func negotiateALPN(serverProtos, clientProtos []string) (string, error) {
+ if len(serverProtos) == 0 || len(clientProtos) == 0 {
+ return "", nil
+ }
+ var http11fallback bool
+ for _, s := range serverProtos {
+ for _, c := range clientProtos {
+ if s == c {
+ return s, nil
+ }
+ if s == "h2" && c == "http/1.1" {
+ http11fallback = true
+ }
+ }
+ }
+ // As a special case, let http/1.1 clients connect to h2 servers as if they
+ // didn't support ALPN. We used not to enforce protocol overlap, so over
+ // time a number of HTTP servers were configured with only "h2", but
+ // expected to accept connections from "http/1.1" clients. See Issue 46310.
+ if http11fallback {
+ return "", nil
+ }
+ return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
+}
+
// supportsECDHE returns whether ECDHE key exchanges can be used with this
// pre-TLS 1.3 client.
func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index 4483838045..f61b4c88ef 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -949,6 +949,27 @@ func TestHandshakeServerALPNNotConfigured(t *testing.T) {
runServerTestTLS13(t, test)
}
+func TestHandshakeServerALPNFallback(t *testing.T) {
+ config := testConfig.Clone()
+ config.NextProtos = []string{"proto1", "h2", "proto2"}
+
+ test := &serverTest{
+ name: "ALPN-Fallback",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ command: []string{"openssl", "s_client", "-alpn", "proto3,http/1.1,proto4", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ config: config,
+ validate: func(state ConnectionState) error {
+ if state.NegotiatedProtocol != "" {
+ return fmt.Errorf("Got protocol %q, wanted nothing", state.NegotiatedProtocol)
+ }
+ return nil
+ },
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
// TestHandshakeServerSNI involves a client sending an SNI extension of
// "snitest.com", which happens to match the CN of testSNICertificate. The test
// verifies that the server correctly selects that certificate.
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
index c375ec4246..08251b84de 100644
--- a/src/crypto/tls/handshake_server_tls13.go
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -11,7 +11,6 @@ import (
"crypto/hmac"
"crypto/rsa"
"errors"
- "fmt"
"hash"
"io"
"sync/atomic"
@@ -551,15 +550,13 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
encryptedExtensions := new(encryptedExtensionsMsg)
- if len(c.config.NextProtos) > 0 && len(hs.clientHello.alpnProtocols) > 0 {
- selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos)
- if selectedProto == "" {
- c.sendAlert(alertNoApplicationProtocol)
- return fmt.Errorf("tls: client requested unsupported application protocols (%s)", hs.clientHello.alpnProtocols)
- }
- encryptedExtensions.alpnProtocol = selectedProto
- c.clientProtocol = selectedProto
+ selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
+ if err != nil {
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
}
+ encryptedExtensions.alpnProtocol = selectedProto
+ c.clientProtocol = selectedProto
hs.transcript.Write(encryptedExtensions.marshal())
if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil {
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
new file mode 100644
index 0000000000..4fadf39062
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 a6 01 00 00 a2 03 03 b5 c9 ab 32 7f |..............2.|
+00000010 e1 af 3f f2 ac 2a 11 dd 33 f9 b5 21 88 0d e4 29 |..?..*..3..!...)|
+00000020 e2 47 49 dc c7 31 a8 a5 25 81 0c 00 00 04 cc a8 |.GI..1..%.......|
+00000030 00 ff 01 00 00 75 00 0b 00 04 03 00 01 02 00 0a |.....u..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000050 00 00 00 10 00 19 00 17 06 70 72 6f 74 6f 33 08 |.........proto3.|
+00000060 68 74 74 70 2f 31 2e 31 06 70 72 6f 74 6f 34 00 |http/1.1.proto4.|
+00000070 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 |..........0.....|
+00000080 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 |................|
+00000090 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 |................|
+000000a0 01 03 02 02 02 04 02 05 02 06 02 |...........|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............|
+00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0|
+00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............|
+00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..|
+00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.|
+00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....|
+00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010|
+000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101|
+000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U|
+000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...|
+000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...|
+000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......|
+000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.|
+00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B|
+00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.|
+00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t|
+00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l|
+00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.|
+00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....|
+00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.|
+00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U|
+00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U|
+00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.|
+000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...|
+000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..|
+000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...|
+000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{|
+000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa|
+00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*|
+00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0|
+00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(|
+00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C|
+00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..|
+00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.|
+00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.|
+00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr|
+00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B|
+00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
+000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G|
+000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 5f |......_X.;t...._|
+000002d0 37 27 84 58 1e ea 1e 40 1b de a9 8f 04 d4 94 64 |7'.X...@.......d|
+000002e0 4e 27 c7 f1 b3 30 d0 53 f5 3d 57 50 d2 17 97 c8 |N'...0.S.=WP....|
+000002f0 3d 61 af a6 21 ab 1c 34 47 70 f8 b1 3b 9c 06 86 |=a..!..4Gp..;...|
+00000300 87 00 e2 13 50 83 91 ad bc 84 bd b4 7b f3 4b ed |....P.......{.K.|
+00000310 ca 81 0c 94 37 a8 ec 67 ca 9c f3 00 f6 af c2 92 |....7..g........|
+00000320 c4 8c 78 07 18 0e 43 24 1b 98 16 50 5c 2b 75 0e |..x...C$...P\+u.|
+00000330 40 66 dc 40 cd 10 1a 51 25 f3 96 25 1a 3e 70 af |@f.@...Q%..%.>p.|
+00000340 16 24 d0 1c 0e 33 f9 c1 74 cf b7 e2 28 ac 60 16 |.$...3..t...(.`.|
+00000350 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 30 f2 bb f7 a7 ac |....%...! 0.....|
+00000010 23 20 22 ee 73 0d 49 9c b3 7b c1 9a db 2c 85 f3 |# ".s.I..{...,..|
+00000020 c0 82 31 60 bd 8b 14 4e 73 43 14 03 03 00 01 01 |..1`...NsC......|
+00000030 16 03 03 00 20 09 8d c7 86 ee cc f4 c7 36 a3 49 |.... ........6.I|
+00000040 d3 f7 a1 4a 68 a2 1e b4 fc cc a2 15 cb 01 92 d8 |...Jh...........|
+00000050 72 b0 d1 6f eb |r..o.|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c a2 ac 05 |o...Q...h.B.L...|
+00000040 9c 69 69 99 08 9f de a4 d4 e7 37 ab 14 38 4c 47 |.ii.......7..8LG|
+00000050 70 f0 97 1d db 2d 0a 14 c2 1e f0 16 9f 6d 37 02 |p....-.......m7.|
+00000060 4b f1 16 be 98 3f df 74 83 7c 19 85 61 49 38 16 |K....?.t.|..aI8.|
+00000070 ee 35 7a e2 3f 74 fe 8d e3 07 93 a1 5e fa f2 02 |.5z.?t......^...|
+00000080 e5 c8 60 3f 11 83 8b 0e 32 52 f1 aa 52 b7 0a 89 |..`?....2R..R...|
+00000090 14 03 03 00 01 01 16 03 03 00 20 9e 65 15 cf 45 |.......... .e..E|
+000000a0 a5 03 69 c9 b1 d8 9e 92 a3 a2 b0 df 2e 62 b1 3a |..i..........b.:|
+000000b0 17 78 cd e5 1d f3 51 42 7e 4e 25 17 03 03 00 1d |.x....QB~N%.....|
+000000c0 d9 ae d0 fa b7 90 a9 2f 28 8d 1d 6f 54 1f c0 1e |......./(..oT...|
+000000d0 4d ae b6 91 f0 e8 84 cf 86 11 22 25 ea 15 03 03 |M........."%....|
+000000e0 00 12 0e 71 f2 11 9e 9f 58 ad c0 d8 fc fa 34 bc |...q....X.....4.|
+000000f0 02 5a 60 00 |.Z`.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
new file mode 100644
index 0000000000..6203e6877c
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 eb 01 00 00 e7 03 03 1c d3 8e 3b d9 |..............;.|
+00000010 fe 7d e7 f9 9f fa c6 51 c3 8c 1b dd dc 87 95 f4 |.}.....Q........|
+00000020 39 23 67 e4 d6 bd 94 93 fc 88 4e 20 c3 c0 e2 c1 |9#g.......N ....|
+00000030 3d 12 ec 4c 0a 3f 40 51 13 24 61 11 c0 5d 09 f9 |=..L.?@Q.$a..]..|
+00000040 08 d6 3e cd e7 b3 51 c3 06 8f b4 42 00 04 13 03 |..>...Q....B....|
+00000050 00 ff 01 00 00 9a 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 10 00 19 00 17 06 70 72 6f 74 6f 33 08 |.........proto3.|
+00000080 68 74 74 70 2f 31 2e 31 06 70 72 6f 74 6f 34 00 |http/1.1.proto4.|
+00000090 16 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 |................|
+000000a0 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 |................|
+000000b0 05 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 |..........+.....|
+000000c0 00 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 |.-.....3.&.$... |
+000000d0 f4 05 eb 4a 7a 73 20 18 74 aa 14 2a 0c 35 63 29 |...Jzs .t..*.5c)|
+000000e0 cb f2 ad d1 a2 3d bd 9d 02 b4 62 00 bc eb 10 58 |.....=....b....X|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 00 00 00 00 00 00 00 00 20 c3 c0 e2 c1 |........... ....|
+00000030 3d 12 ec 4c 0a 3f 40 51 13 24 61 11 c0 5d 09 f9 |=..L.?@Q.$a..]..|
+00000040 08 d6 3e cd e7 b3 51 c3 06 8f b4 42 13 03 00 00 |..>...Q....B....|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 2f |..+.....3.$... /|
+00000060 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
+00000070 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 14 |.........._X.;t.|
+00000080 03 03 00 01 01 17 03 03 00 17 fb 75 d8 5c 50 35 |...........u.\P5|
+00000090 55 82 ba 65 1e 63 73 b8 c1 e9 d7 f5 28 68 3c c1 |U..e.cs.....(h<.|
+000000a0 5d 17 03 03 02 6d 56 c9 a9 09 73 6a bc fd 1a 3c |]....mV...sj...<|
+000000b0 6a f8 3e 32 99 83 e8 f6 01 9e 5e 30 e8 53 7f 72 |j.>2......^0.S.r|
+000000c0 fd 86 72 a8 9e 47 25 67 c1 f1 9a 03 c0 9d 6f 9d |..r..G%g......o.|
+000000d0 bd ed 29 30 8f 3c 01 ce 49 bb 5f dd 58 9a ae 80 |..)0.<..I._.X...|
+000000e0 5c 2d 81 fc ea 7b 03 03 3d 5d bb 92 23 73 67 89 |\-...{..=]..#sg.|
+000000f0 2e f0 ec 08 20 8a 36 eb 43 a6 a1 68 d0 39 95 37 |.... .6.C..h.9.7|
+00000100 6b 15 a9 0e 46 20 92 51 9c 04 bf 3b 07 97 84 cb |k...F .Q...;....|
+00000110 1f 30 38 37 2e ff e7 0f f5 14 93 5a 84 f1 f7 10 |.087.......Z....|
+00000120 c2 a5 0d bb 97 96 ef 4a e0 13 c0 63 72 2b 60 f3 |.......J...cr+`.|
+00000130 59 b5 57 aa 5f d1 da a9 0e dd 9c dd c2 cb 61 fe |Y.W._.........a.|
+00000140 e2 69 8e db 5d 70 6c 3a 33 e0 9e db 9a 31 26 6a |.i..]pl:3....1&j|
+00000150 2b 9e 19 8e bb 5d 06 48 ea c0 a1 c6 11 24 fb c4 |+....].H.....$..|
+00000160 ce ae 48 54 64 81 d1 84 38 a6 e0 7a 7b 74 2b bc |..HTd...8..z{t+.|
+00000170 ce 07 8b b6 04 1f 5b 4c 36 29 68 0c 8c c7 32 15 |......[L6)h...2.|
+00000180 93 e0 10 52 c2 27 23 96 c5 0c 9c e9 e2 a9 08 7d |...R.'#........}|
+00000190 25 68 65 f5 4e 44 eb a9 85 78 13 e1 0d 86 5e dc |%he.ND...x....^.|
+000001a0 fd e5 c6 dd 65 46 8e 2f 32 82 83 0b dd 67 f8 42 |....eF./2....g.B|
+000001b0 65 87 3b 08 fe b1 f5 12 e9 74 21 04 12 6d 75 35 |e.;......t!..mu5|
+000001c0 b2 eb 93 95 72 10 fa 56 96 77 c3 0c 17 8c 9e f6 |....r..V.w......|
+000001d0 77 19 28 37 96 3e 73 98 f4 d2 91 4f 40 db 76 56 |w.(7.>s....O@.vV|
+000001e0 ce b5 a8 7a b8 86 d0 9a ba b5 8b 40 c2 63 e1 cf |...z.......@.c..|
+000001f0 49 29 2c 5d 1a 9b 8b 56 cb 93 ca 2c c0 d0 15 b7 |I),]...V...,....|
+00000200 8a f1 6a d5 0a a8 81 57 b1 6e 10 cd a5 ff b1 4d |..j....W.n.....M|
+00000210 47 c6 9b 35 f1 5f 83 91 22 f6 88 68 65 b3 b9 c9 |G..5._.."..he...|
+00000220 02 dc 4b f7 13 39 06 e6 3a ec 94 ef 51 15 05 72 |..K..9..:...Q..r|
+00000230 1d f4 9d 3b da ca 8d 2c 64 be 9b 45 99 2c 63 cc |...;...,d..E.,c.|
+00000240 22 b3 8b 93 ad f6 2c f0 d2 d9 11 3f 5b c0 40 fa |".....,....?[.@.|
+00000250 90 6e a0 76 b2 43 b9 4c 72 c4 24 28 a2 bf 56 d6 |.n.v.C.Lr.$(..V.|
+00000260 d2 a7 2a d1 8c 5e 1d eb f8 be d0 43 da 7a c7 88 |..*..^.....C.z..|
+00000270 61 67 a2 69 85 23 43 3e d4 88 f2 33 c3 5b 38 0a |ag.i.#C>...3.[8.|
+00000280 1e de 28 3b 3b 19 de 95 2f 84 c0 37 88 80 59 2f |..(;;.../..7..Y/|
+00000290 a6 ee 93 1a 69 08 c3 df 7c cf da c3 9b 96 70 d9 |....i...|.....p.|
+000002a0 60 c5 e9 0f 42 f6 1a f2 58 5e f2 32 61 6a b2 a3 |`...B...X^.2aj..|
+000002b0 1f 97 fa 08 6c 3f 4b 83 1f 04 66 80 8a 26 3a 7f |....l?K...f..&:.|
+000002c0 24 30 ec 10 ae 7d 19 ff 39 91 ca 97 4e ed 0a d7 |$0...}..9...N...|
+000002d0 64 3b 6b 50 29 33 0d b2 10 bc 83 63 3c fb 9a 82 |d;kP)3.....c<...|
+000002e0 3b 7f bc 04 40 f1 33 64 4a 80 cd 01 f9 f4 c6 89 |;...@.3dJ.......|
+000002f0 65 27 25 f9 cf 4f 7e c8 6e d9 0e ec 47 4a 51 29 |e'%..O~.n...GJQ)|
+00000300 2f be 34 50 bd 9b d2 d8 b7 ea bb 0b a1 e0 20 1b |/.4P.......... .|
+00000310 02 9c f2 17 03 03 00 99 61 dc 0b 3a 30 de 39 f6 |........a..:0.9.|
+00000320 f3 db f8 6c 3b fa 4e 1e 7e 62 a5 ae 73 ba e1 41 |...l;.N.~b..s..A|
+00000330 58 77 2a c1 7a 0c 50 bb 0c 57 b4 c4 25 bf 2f 9f |Xw*.z.P..W..%./.|
+00000340 38 91 e2 65 22 9d ca ac 18 58 7e 81 2d fd 74 24 |8..e"....X~.-.t$|
+00000350 28 69 76 11 df 9d 23 b8 be ae 8b e0 93 8e 5d df |(iv...#.......].|
+00000360 0a 64 d0 b7 02 68 aa 86 01 0d 55 11 3b 76 70 c6 |.d...h....U.;vp.|
+00000370 83 0c 5e 0a e3 37 a5 8b ad 25 50 b9 e8 5c 6b 04 |..^..7...%P..\k.|
+00000380 b4 51 ec 9c d3 fa c6 b7 9c f0 46 aa 73 da 3c 0d |.Q........F.s.<.|
+00000390 d3 bd 32 81 d4 d2 f1 1a b0 92 f3 73 3e 54 2b 05 |..2........s>T+.|
+000003a0 92 24 34 75 df d6 18 a0 6a 82 95 4c 9b fc 7e b6 |.$4u....j..L..~.|
+000003b0 8e 17 03 03 00 35 8f 34 0e 3b 91 d8 e7 74 24 71 |.....5.4.;...t$q|
+000003c0 0e 7b f3 12 bb 76 2f 31 12 17 b8 9e 24 ce f9 2f |.{...v/1....$../|
+000003d0 3f 5d f2 13 4b 2e 9b 1e c4 78 03 a6 c8 07 11 a3 |?]..K....x......|
+000003e0 98 79 61 6e 4f 44 6e 18 ee c4 9b 17 03 03 00 93 |.yanODn.........|
+000003f0 64 dd 52 a9 d9 51 63 6a a0 a3 c2 75 6b 5d 1d 54 |d.R..Qcj...uk].T|
+00000400 ce d4 53 7e 14 8e d9 26 93 28 78 65 16 1b 95 77 |..S~...&.(xe...w|
+00000410 68 0a 46 f1 82 36 bb 8a fa 0d df 54 8c 3d 83 e0 |h.F..6.....T.=..|
+00000420 d7 de 2d 96 e9 c4 d7 22 d3 97 8e ae 90 f8 fc e6 |..-...."........|
+00000430 a6 4b 78 98 4c c5 28 87 91 46 fa f4 1c 8d 0e ec |.Kx.L.(..F......|
+00000440 0d 71 40 9a 04 49 b4 e8 5b 62 6f cd 16 c1 d5 fb |.q@..I..[bo.....|
+00000450 73 2a 96 8f e5 a2 f4 11 1e df 2d 40 45 6b d5 a9 |s*........-@Ek..|
+00000460 e4 e3 f7 93 fc fa d7 20 af d5 f7 b4 0e 09 ad d5 |....... ........|
+00000470 26 87 b8 6c e2 20 95 fb c0 70 3e 38 be b7 b1 9f |&..l. ...p>8....|
+00000480 70 da c1 |p..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 29 d2 b9 bb 9b |..........5)....|
+00000010 de 6c 5d 22 23 c1 fe 99 4c c5 33 bf fd 70 36 6b |.l]"#...L.3..p6k|
+00000020 f1 a5 92 e8 bf 7c 3d 6e ef 6a 44 73 bc cb 27 1c |.....|=n.jDs..'.|
+00000030 09 5d bf 99 4c 19 24 c3 3b 30 91 b5 e3 b6 63 45 |.]..L.$.;0....cE|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 52 55 85 7c b8 87 dd c7 b2 d9 5b |.....RU.|......[|
+00000010 18 1d bb ac bf b6 ab 76 82 be 64 0e b2 7b 2c 0f |.......v..d..{,.|
+00000020 aa 17 92 17 03 03 00 13 79 0a 60 b1 46 20 33 74 |........y.`.F 3t|
+00000030 ed 12 a0 23 de 68 88 fc 6f dd 8e |...#.h..o..|
From 8d11b1d1172817359d08231deaf29f72d315b762 Mon Sep 17 00:00:00 2001
From: "Bryan C. Mills"
Date: Tue, 8 Jun 2021 15:53:08 -0400
Subject: [PATCH 30/45] cmd/go: report the imports of CompiledGoFiles in
ImportMap
Ideally we should encode the load.PackageInternal data in a way that
doesn't rely on 1:1 correlations of slices, but this is a minimal fix
to unblock Go 1.17.
Fixes #46462
Change-Id: I6e029c69f757aadc54d4be02c01d6b294c217542
Reviewed-on: https://go-review.googlesource.com/c/go/+/326610
Trust: Bryan C. Mills
Run-TryBot: Bryan C. Mills
Reviewed-by: Michael Matloob
TryBot-Result: Go Bot
---
src/cmd/go/internal/list/list.go | 14 ++++++-
src/cmd/go/internal/load/pkg.go | 4 +-
.../script/list_cgo_compiled_importmap.txt | 38 +++++++++++++++++++
3 files changed, 52 insertions(+), 4 deletions(-)
create mode 100644 src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index 53aaf311ec..7cb9ec6d94 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -724,8 +724,18 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
// Record non-identity import mappings in p.ImportMap.
for _, p := range pkgs {
- for i, srcPath := range p.Internal.RawImports {
- path := p.Imports[i]
+ nRaw := len(p.Internal.RawImports)
+ for i, path := range p.Imports {
+ var srcPath string
+ if i < nRaw {
+ srcPath = p.Internal.RawImports[i]
+ } else {
+ // This path is not within the raw imports, so it must be an import
+ // found only within CompiledGoFiles. Those paths are found in
+ // CompiledImports.
+ srcPath = p.Internal.CompiledImports[i-nRaw]
+ }
+
if path != srcPath {
if p.ImportMap == nil {
p.ImportMap = make(map[string]string)
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 738904865e..a83cc9a812 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -194,8 +194,8 @@ type PackageInternal struct {
// Unexported fields are not part of the public API.
Build *build.Package
Imports []*Package // this package's direct imports
- CompiledImports []string // additional Imports necessary when using CompiledGoFiles (all from standard library)
- RawImports []string // this package's original imports as they appear in the text of the program
+ CompiledImports []string // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports
+ RawImports []string // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports
ForceLibrary bool // this package is a library (even if named "main")
CmdlineFiles bool // package built from files listed on command line
CmdlinePkg bool // package listed on command line
diff --git a/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt
new file mode 100644
index 0000000000..3d68ef3055
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt
@@ -0,0 +1,38 @@
+# Regression test for https://golang.org/issue/46462.
+#
+# The "runtime/cgo" import found in synthesized .go files (reported in
+# the CompiledGoFiles field) should have a corresponding entry in the
+# ImportMap field when a runtime/cgo variant (such as a test variant)
+# will be used.
+
+[short] skip # -compiled can be slow (because it compiles things)
+[!cgo] skip
+
+env CGO_ENABLED=1
+env GOFLAGS=-tags=netcgo # Force net to use cgo even on Windows.
+
+
+# "runtime/cgo [runtime.test]" appears in the the test dependencies of "runtime",
+# because "runtime/cgo" itself depends on "runtime"
+
+go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .Imports}}{{end}}' runtime
+
+ # Control case: the explicitly-imported package "sync" is a test variant,
+ # because "sync" depends on "runtime".
+stdout '"sync \[runtime\.test\]"'
+! stdout '"sync"'
+
+ # Experiment: the implicitly-imported package "runtime/cgo" is also a test variant,
+ # because "runtime/cgo" also depends on "runtime".
+stdout '"runtime/cgo \[runtime\.test\]"'
+! stdout '"runtime/cgo"'
+
+
+# Because the import of "runtime/cgo" in the cgo-generated file actually refers
+# to "runtime/cgo [runtime.test]", the latter should be listed in the ImportMap.
+# BUG(#46462): Today, it is not.
+
+go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .ImportMap}}{{end}}' runtime
+
+stdout '"sync":"sync \[runtime\.test\]"' # control
+stdout '"runtime/cgo":"runtime/cgo \[runtime\.test\]"' # experiment
From 770f1de8c54256d5b17447028e47b201ba8e62c8 Mon Sep 17 00:00:00 2001
From: Damien Neil
Date: Thu, 10 Jun 2021 10:50:37 -0700
Subject: [PATCH 31/45] net/http: remove test-only private key from production
binaries
The net/http/internal package contains a PEM-encoded private key used in
tests. This key is initialized at init time, which prevents it from
being stripped by the linker in non-test binaries.
Move the certificate and key to a new net/http/internal/testcert
package to ensure it is only included in binaries that reference it.
Fixes #46677.
Change-Id: Ie98bda529169314cc791063e7ce4d99ef99113c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/326771
Trust: Damien Neil
Run-TryBot: Damien Neil
TryBot-Result: Go Bot
Reviewed-by: Bryan C. Mills
---
src/go/build/deps_test.go | 4 +++-
src/net/http/httptest/server.go | 4 ++--
src/net/http/internal/{ => testcert}/testcert.go | 5 +++--
src/net/http/serve_test.go | 7 ++++---
src/net/http/transport_internal_test.go | 4 ++--
src/net/http/transport_test.go | 4 ++--
6 files changed, 16 insertions(+), 12 deletions(-)
rename src/net/http/internal/{ => testcert}/testcert.go (94%)
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index 5d1cf7f4c9..45e2f25df7 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -440,7 +440,8 @@ var depsRules = `
# HTTP, King of Dependencies.
FMT
- < golang.org/x/net/http2/hpack, net/http/internal, net/http/internal/ascii;
+ < golang.org/x/net/http2/hpack
+ < net/http/internal, net/http/internal/ascii, net/http/internal/testcert;
FMT, NET, container/list, encoding/binary, log
< golang.org/x/text/transform
@@ -459,6 +460,7 @@ var depsRules = `
golang.org/x/net/http2/hpack,
net/http/internal,
net/http/internal/ascii,
+ net/http/internal/testcert,
net/http/httptrace,
mime/multipart,
log
diff --git a/src/net/http/httptest/server.go b/src/net/http/httptest/server.go
index a02a6d64c3..4f85ff55d8 100644
--- a/src/net/http/httptest/server.go
+++ b/src/net/http/httptest/server.go
@@ -14,7 +14,7 @@ import (
"log"
"net"
"net/http"
- "net/http/internal"
+ "net/http/internal/testcert"
"os"
"strings"
"sync"
@@ -144,7 +144,7 @@ func (s *Server) StartTLS() {
if s.client == nil {
s.client = &http.Client{Transport: &http.Transport{}}
}
- cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+ cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
if err != nil {
panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
}
diff --git a/src/net/http/internal/testcert.go b/src/net/http/internal/testcert/testcert.go
similarity index 94%
rename from src/net/http/internal/testcert.go
rename to src/net/http/internal/testcert/testcert.go
index 2284a836fb..5f94704ef5 100644
--- a/src/net/http/internal/testcert.go
+++ b/src/net/http/internal/testcert/testcert.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package internal
+// Package testcert contains a test-only localhost certificate.
+package testcert
import "strings"
@@ -25,7 +26,7 @@ h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM
fblo6RBxUQ==
-----END CERTIFICATE-----`)
-// LocalhostKey is the private key for localhostCert.
+// LocalhostKey is the private key for LocalhostCert.
var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9
SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index c2f8811469..6394da3bb7 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -25,6 +25,7 @@ import (
"net/http/httptest"
"net/http/httputil"
"net/http/internal"
+ "net/http/internal/testcert"
"net/url"
"os"
"os/exec"
@@ -1475,7 +1476,7 @@ func TestServeTLS(t *testing.T) {
defer afterTest(t)
defer SetTestHookServerServe(nil)
- cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+ cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
if err != nil {
t.Fatal(err)
}
@@ -1599,7 +1600,7 @@ func TestAutomaticHTTP2_Serve_WithTLSConfig(t *testing.T) {
}
func TestAutomaticHTTP2_ListenAndServe(t *testing.T) {
- cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+ cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
if err != nil {
t.Fatal(err)
}
@@ -1609,7 +1610,7 @@ func TestAutomaticHTTP2_ListenAndServe(t *testing.T) {
}
func TestAutomaticHTTP2_ListenAndServe_GetCertificate(t *testing.T) {
- cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+ cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
if err != nil {
t.Fatal(err)
}
diff --git a/src/net/http/transport_internal_test.go b/src/net/http/transport_internal_test.go
index 1097ffd173..1cce27235d 100644
--- a/src/net/http/transport_internal_test.go
+++ b/src/net/http/transport_internal_test.go
@@ -12,7 +12,7 @@ import (
"errors"
"io"
"net"
- "net/http/internal"
+ "net/http/internal/testcert"
"strings"
"testing"
)
@@ -191,7 +191,7 @@ func (f roundTripFunc) RoundTrip(r *Request) (*Response, error) {
// Issue 25009
func TestTransportBodyAltRewind(t *testing.T) {
- cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+ cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
if err != nil {
t.Fatal(err)
}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index dcaacece61..690e0c299d 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -30,7 +30,7 @@ import (
"net/http/httptest"
"net/http/httptrace"
"net/http/httputil"
- "net/http/internal"
+ "net/http/internal/testcert"
"net/textproto"
"net/url"
"os"
@@ -4299,7 +4299,7 @@ func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
// Issue 13839
func TestNoCrashReturningTransportAltConn(t *testing.T) {
- cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+ cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
if err != nil {
t.Fatal(err)
}
From 2721da26083f253c46c2fd0c1dadee14ae4202f5 Mon Sep 17 00:00:00 2001
From: Rhys Hiltner
Date: Thu, 10 Jun 2021 15:05:07 -0700
Subject: [PATCH 32/45] doc/go1.17: fix formatting near httptest
Change-Id: Ic1a0add3a1e137ca5cd0f3e9ce3266191b0b55cd
Reviewed-on: https://go-review.googlesource.com/c/go/+/326777
Trust: Alberto Donizetti
Reviewed-by: Dmitri Shuralyov
---
doc/go1.17.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index 49fbabdc3f..101957aabd 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -763,9 +763,9 @@ func Foo() bool {
- net/http/httptest
-
- ResponseRecorder.WriteHeader>
+ ResponseRecorder.WriteHeader
now panics when the provided code is not a valid three-digit HTTP status code.
- This matches the behavior of ResponseWriter>
+ This matches the behavior of ResponseWriter
implementations in the net/http
package.
From 2f1128461dcc6c9915f21327ce18fa1925269f30 Mon Sep 17 00:00:00 2001
From: "Bryan C. Mills"
Date: Thu, 10 Jun 2021 16:54:53 -0400
Subject: [PATCH 33/45] cmd/go: match Windows paths in
TestScript/mod_invalid_version
Fixes #46691
Change-Id: I3bef9a773be640bed96eb2dc395cb11671a0767a
Reviewed-on: https://go-review.googlesource.com/c/go/+/326869
Trust: Bryan C. Mills
Run-TryBot: Bryan C. Mills
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
---
src/cmd/go/testdata/script/mod_invalid_version.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt
index 34d9c47674..6846a792a5 100644
--- a/src/cmd/go/testdata/script/mod_invalid_version.txt
+++ b/src/cmd/go/testdata/script/mod_invalid_version.txt
@@ -19,7 +19,7 @@ cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@14c0d48ead0c
cd outside
! go list -m golang.org/x/text
-stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\..\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
+stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
cd ..
go list -m golang.org/x/text
stdout 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c'
@@ -47,10 +47,10 @@ cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@v2.1.1-0.20170915032832-14c0d48ead0c
cd outside
! go list -m golang.org/x/text
-stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
+stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
cd ..
! go list -m golang.org/x/text
-stderr $WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
+stderr $WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
# A pseudo-version with fewer than 12 digits of SHA-1 prefix is invalid.
cp go.mod.orig go.mod
From e2dc6dd5c9b6799c9bb987f3a4600fb0df686d09 Mon Sep 17 00:00:00 2001
From: Brad Fitzpatrick
Date: Thu, 10 Jun 2021 14:40:58 -0700
Subject: [PATCH 34/45] doc/go1.17: clean up formatting of gofmt section
It was the only h3 in , and it lacked around its content.
It looked like it was part of the prior section:
https://tip.golang.org/doc/go1.17#gofmt
Change-Id: I7e9ef70e9a03474225833f44420aabd70dab3cd5
Reviewed-on: https://go-review.googlesource.com/c/go/+/326774
Reviewed-by: Dmitri Shuralyov
Trust: Brad Fitzpatrick
---
doc/go1.17.html | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index 101957aabd..4fa38921f0 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -293,7 +293,9 @@ Do not send CLs removing the interior tags from such phrases.
https://golang.org/design/draft-gobuild.
-gofmt
+Gofmt
+
+
gofmt
(and go
fmt
) now synchronizes
//go:build
lines with // +build
lines. If a file
only has // +build
lines, they will be moved to the appropriate
@@ -301,7 +303,7 @@ Do not send CLs removing the interior tags from such phrases.
added. Otherwise, // +build
lines will be overwritten based on
any existing //go:build
lines. For more information, see
https://golang.org/design/draft-gobuild.
-
+
Vet
From 77aa209b386a184e7f4b44938f2a05a1b5c5a3cf Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Thu, 10 Jun 2021 15:35:05 -0700
Subject: [PATCH 35/45] runtime: loop on EINTR in macOS sigNoteSleep
Fixes #46466
Change-Id: I8fb15d0c8ef7ef6e6fc1b9e0e033d213255fe0df
Reviewed-on: https://go-review.googlesource.com/c/go/+/326778
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Michael Knyszek
Reviewed-by: Cherry Mui
---
src/runtime/os_darwin.go | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index 00139351ab..079be107d7 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -118,10 +118,15 @@ func sigNoteWakeup(*note) {
// sigNoteSleep waits for a note created by sigNoteSetup to be woken.
func sigNoteSleep(*note) {
- entersyscallblock()
- var b byte
- read(sigNoteRead, unsafe.Pointer(&b), 1)
- exitsyscall()
+ for {
+ var b byte
+ entersyscallblock()
+ n := read(sigNoteRead, unsafe.Pointer(&b), 1)
+ exitsyscall()
+ if n != -_EINTR {
+ return
+ }
+ }
}
// BSD interface for threading.
From 16b5d766d8af8bc348f93e6cb2b53a4e2d5d72ca Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Fri, 11 Jun 2021 17:36:50 +0200
Subject: [PATCH 36/45] syscall: do not load native libraries on non-native
powershell on arm
The powershell that currently ships on ARM Windows isn't native, so it
won't load native DLLs. So just skip the tests for now, and reenable it
if this ever changes.
Updates #46701.
Change-Id: I2559fdf13cb65d3ecdc4c6f6df7dec1b490b9651
Reviewed-on: https://go-review.googlesource.com/c/go/+/327210
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
Trust: Jason A. Donenfeld
Run-TryBot: Jason A. Donenfeld
---
src/syscall/syscall_windows_test.go | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/syscall/syscall_windows_test.go b/src/syscall/syscall_windows_test.go
index ea8fa191dc..3243952ded 100644
--- a/src/syscall/syscall_windows_test.go
+++ b/src/syscall/syscall_windows_test.go
@@ -10,6 +10,7 @@ import (
"os"
"os/exec"
"path/filepath"
+ "runtime"
"strings"
"syscall"
"testing"
@@ -79,6 +80,9 @@ func TestTOKEN_ALL_ACCESS(t *testing.T) {
func TestStdioAreInheritable(t *testing.T) {
testenv.MustHaveGoBuild(t)
testenv.MustHaveExecPath(t, "gcc")
+ if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" {
+ t.Skip("Powershell is not native on ARM; see golang.org/issues/46701")
+ }
tmpdir := t.TempDir()
From e552a6d31270c86064632af1d092e0db5a930250 Mon Sep 17 00:00:00 2001
From: Constantin Konstantinidis
Date: Sat, 5 Jun 2021 07:48:30 +0200
Subject: [PATCH 37/45] cmd/go: remove hint when no module is suggested
Fixes #46528
Change-Id: I2453d321ece878ea7823865758aa4a16b3ed7fe8
Reviewed-on: https://go-review.googlesource.com/c/go/+/325430
Reviewed-by: Bryan C. Mills
Run-TryBot: Bryan C. Mills
Trust: Heschi Kreinick
Trust: Dmitri Shuralyov
TryBot-Result: Go Bot
---
src/cmd/go/internal/modload/import.go | 10 ++++++----
src/cmd/go/testdata/script/mod_install_hint.txt | 5 +++++
2 files changed, 11 insertions(+), 4 deletions(-)
create mode 100644 src/cmd/go/testdata/script/mod_install_hint.txt
diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go
index f76befcfe3..60bd26fb22 100644
--- a/src/cmd/go/internal/modload/import.go
+++ b/src/cmd/go/internal/modload/import.go
@@ -178,11 +178,13 @@ func (e *ImportMissingSumError) Error() string {
// Importing package is unknown, or the missing package was named on the
// command line. Recommend 'go mod download' for the modules that could
// provide the package, since that shouldn't change go.mod.
- args := make([]string, len(e.mods))
- for i, mod := range e.mods {
- args[i] = mod.Path
+ if len(e.mods) > 0 {
+ args := make([]string, len(e.mods))
+ for i, mod := range e.mods {
+ args[i] = mod.Path
+ }
+ hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
}
- hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
} else {
// Importing package is known (common case). Recommend 'go get' on the
// current version of the importing package.
diff --git a/src/cmd/go/testdata/script/mod_install_hint.txt b/src/cmd/go/testdata/script/mod_install_hint.txt
new file mode 100644
index 0000000000..ab02840eb8
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_install_hint.txt
@@ -0,0 +1,5 @@
+# Module is replaced but not required. No hint appears as no module is suggested.
+go mod init m
+go mod edit -replace=github.com/notrequired@v0.5.0=github.com/doesnotexist@v0.5.0
+! go install github.com/notrequired
+! stderr 'to add it:'
\ No newline at end of file
From 9d46ee5ac4acd6602692f70c5149a3f6db058558 Mon Sep 17 00:00:00 2001
From: Michael Anthony Knyszek
Date: Fri, 11 Jun 2021 13:58:05 +0000
Subject: [PATCH 38/45] reflect: handle stack-to-register translation in
callMethod
callMethod previously assumed erroneously that between the "value" and
"method" ABIs (that is, the ABI the caller is following to call this
method value and the actual ABI of the method), it could never happen
that an argument passed on the stack in the former could be passed in
registers in the latter. The cited reason was that the latter always
uses strictly more registers.
However, there are situations where the value ABI could pass a value on
the stack, but later is passed in a register. For instance, if the
receiver pushes a value passed in registers that uses multiple registers
to be passed on the stack, later arguments which were passed on the
stack may now be passed in registers.
This change fixes callMethod to no longer makes this assumption, and
handles the stack-to-register translation explicitly.
Fixes #46696.
Change-Id: I7100a664d97bbe401302cc893b3a98b28cdcdfc0
Reviewed-on: https://go-review.googlesource.com/c/go/+/327089
Trust: Michael Knyszek
Run-TryBot: Michael Knyszek
TryBot-Result: Go Bot
Reviewed-by: Cherry Mui
---
src/reflect/abi_test.go | 43 ++++++++++++++++++++++++++++++++++++++++-
src/reflect/value.go | 42 ++++++++++++++++++++++++++++++----------
2 files changed, 74 insertions(+), 11 deletions(-)
diff --git a/src/reflect/abi_test.go b/src/reflect/abi_test.go
index 1a2a48b5ed..5a0130f7b4 100644
--- a/src/reflect/abi_test.go
+++ b/src/reflect/abi_test.go
@@ -79,7 +79,34 @@ func TestMethodValueCallABI(t *testing.T) {
t.Errorf("bad method value call: got %#v, want %#v", r2, a2)
}
if s.Value != 3 {
- t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 1)
+ t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 3)
+ }
+
+ s, i = makeMethodValue("ValueRegMethodSpillInt")
+ f3 := i.(func(StructFillRegs, int, MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, int))
+ r3a, r3b := f3(a2, 42, MagicLastTypeNameForTestingRegisterABI{})
+ if r3a != a2 {
+ t.Errorf("bad method value call: got %#v, want %#v", r3a, a2)
+ }
+ if r3b != 42 {
+ t.Errorf("bad method value call: got %#v, want %#v", r3b, 42)
+ }
+ if s.Value != 4 {
+ t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 4)
+ }
+
+ s, i = makeMethodValue("ValueRegMethodSpillPtr")
+ f4 := i.(func(StructFillRegs, *byte, MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, *byte))
+ vb := byte(10)
+ r4a, r4b := f4(a2, &vb, MagicLastTypeNameForTestingRegisterABI{})
+ if r4a != a2 {
+ t.Errorf("bad method value call: got %#v, want %#v", r4a, a2)
+ }
+ if r4b != &vb {
+ t.Errorf("bad method value call: got %#v, want %#v", r4b, &vb)
+ }
+ if s.Value != 5 {
+ t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 5)
}
}
@@ -112,6 +139,20 @@ func (m *StructWithMethods) SpillStructCall(s StructFillRegs, _ MagicLastTypeNam
return s
}
+// When called as a method value, i is passed on the stack.
+// When called as a method, i is passed in a register.
+func (m *StructWithMethods) ValueRegMethodSpillInt(s StructFillRegs, i int, _ MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, int) {
+ m.Value = 4
+ return s, i
+}
+
+// When called as a method value, i is passed on the stack.
+// When called as a method, i is passed in a register.
+func (m *StructWithMethods) ValueRegMethodSpillPtr(s StructFillRegs, i *byte, _ MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, *byte) {
+ m.Value = 5
+ return s, i
+}
+
func TestReflectCallABI(t *testing.T) {
// Enable register-based reflect.Call and ensure we don't
// use potentially incorrect cached versions by clearing
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 418dff781f..c963a407bc 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -952,25 +952,47 @@ func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *a
continue
}
- // There are three cases to handle in translating each
+ // There are four cases to handle in translating each
// argument:
// 1. Stack -> stack translation.
- // 2. Registers -> stack translation.
- // 3. Registers -> registers translation.
- // The fourth cases can't happen, because a method value
- // call uses strictly fewer registers than a method call.
+ // 2. Stack -> registers translation.
+ // 3. Registers -> stack translation.
+ // 4. Registers -> registers translation.
+ // TODO(mknyszek): Cases 2 and 3 below only work on little endian
+ // architectures. This is OK for now, but this needs to be fixed
+ // before supporting the register ABI on big endian architectures.
// If the value ABI passes the value on the stack,
// then the method ABI does too, because it has strictly
// fewer arguments. Simply copy between the two.
if vStep := valueSteps[0]; vStep.kind == abiStepStack {
mStep := methodSteps[0]
- if mStep.kind != abiStepStack || vStep.size != mStep.size {
- panic("method ABI and value ABI do not align")
+ // Handle stack -> stack translation.
+ if mStep.kind == abiStepStack {
+ if vStep.size != mStep.size {
+ panic("method ABI and value ABI do not align")
+ }
+ typedmemmove(t,
+ add(methodFrame, mStep.stkOff, "precomputed stack offset"),
+ add(valueFrame, vStep.stkOff, "precomputed stack offset"))
+ continue
+ }
+ // Handle stack -> register translation.
+ for _, mStep := range methodSteps {
+ from := add(valueFrame, vStep.stkOff+mStep.offset, "precomputed stack offset")
+ switch mStep.kind {
+ case abiStepPointer:
+ // Do the pointer copy directly so we get a write barrier.
+ methodRegs.Ptrs[mStep.ireg] = *(*unsafe.Pointer)(from)
+ fallthrough // We need to make sure this ends up in Ints, too.
+ case abiStepIntReg:
+ memmove(unsafe.Pointer(&methodRegs.Ints[mStep.ireg]), from, mStep.size)
+ case abiStepFloatReg:
+ memmove(unsafe.Pointer(&methodRegs.Floats[mStep.freg]), from, mStep.size)
+ default:
+ panic("unexpected method step")
+ }
}
- typedmemmove(t,
- add(methodFrame, mStep.stkOff, "precomputed stack offset"),
- add(valueFrame, vStep.stkOff, "precomputed stack offset"))
continue
}
// Handle register -> stack translation.
From 1ed0d129e9ba9b55e9ae36ac1d7f2766ba16b373 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Fri, 11 Jun 2021 11:50:42 -0700
Subject: [PATCH 39/45] runtime: testprogcgo: don't call exported Go functions
directly from Go
Instead route through a C function, to avoid declaration conflicts
between the declaration needed in the cgo comment and the declaration
generated by cgo in _cgo_export.h.
This is not something user code will ever do, so no need to make it
work in cgo.
Fixes #46502
Change-Id: I1bfffdc76ef8ea63e3829871298d0774157957a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/327309
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Cherry Mui
Reviewed-by: Jason A. Donenfeld
---
src/runtime/testdata/testprogcgo/aprof.go | 4 ++--
src/runtime/testdata/testprogcgo/aprof_c.c | 9 +++++++++
src/runtime/testdata/testprogcgo/bigstack1_windows.c | 12 ++++++++++++
src/runtime/testdata/testprogcgo/bigstack_windows.go | 4 ++--
4 files changed, 25 insertions(+), 4 deletions(-)
create mode 100644 src/runtime/testdata/testprogcgo/aprof_c.c
create mode 100644 src/runtime/testdata/testprogcgo/bigstack1_windows.c
diff --git a/src/runtime/testdata/testprogcgo/aprof.go b/src/runtime/testdata/testprogcgo/aprof.go
index aabca9e1eb..44a15b0865 100644
--- a/src/runtime/testdata/testprogcgo/aprof.go
+++ b/src/runtime/testdata/testprogcgo/aprof.go
@@ -10,7 +10,7 @@ package main
// The test fails when the function is the first C function.
// The exported functions are the first C functions, so we use that.
-// extern void GoNop();
+// extern void CallGoNop();
import "C"
import (
@@ -38,7 +38,7 @@ func CgoCCodeSIGPROF() {
break
}
}
- C.GoNop()
+ C.CallGoNop()
}
c <- true
}()
diff --git a/src/runtime/testdata/testprogcgo/aprof_c.c b/src/runtime/testdata/testprogcgo/aprof_c.c
new file mode 100644
index 0000000000..d588e13045
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/aprof_c.c
@@ -0,0 +1,9 @@
+// Copyright 2021 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.
+
+#include "_cgo_export.h"
+
+void CallGoNop() {
+ GoNop();
+}
diff --git a/src/runtime/testdata/testprogcgo/bigstack1_windows.c b/src/runtime/testdata/testprogcgo/bigstack1_windows.c
new file mode 100644
index 0000000000..551fb68309
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/bigstack1_windows.c
@@ -0,0 +1,12 @@
+// Copyright 2021 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.
+
+// This is not in bigstack_windows.c because it needs to be part of
+// testprogcgo but is not part of the DLL built from bigstack_windows.c.
+
+#include "_cgo_export.h"
+
+void CallGoBigStack1(char* p) {
+ goBigStack1(p);
+}
diff --git a/src/runtime/testdata/testprogcgo/bigstack_windows.go b/src/runtime/testdata/testprogcgo/bigstack_windows.go
index f58fcf993f..135b5fcfe0 100644
--- a/src/runtime/testdata/testprogcgo/bigstack_windows.go
+++ b/src/runtime/testdata/testprogcgo/bigstack_windows.go
@@ -6,7 +6,7 @@ package main
/*
typedef void callback(char*);
-extern void goBigStack1(char*);
+extern void CallGoBigStack1(char*);
extern void bigStack(callback*);
*/
import "C"
@@ -18,7 +18,7 @@ func init() {
func BigStack() {
// Create a large thread stack and call back into Go to test
// if Go correctly determines the stack bounds.
- C.bigStack((*C.callback)(C.goBigStack1))
+ C.bigStack((*C.callback)(C.CallGoBigStack1))
}
//export goBigStack1
From 67b1b6a2e3a405e3e0b5c6a76f702b2a6071c1f0 Mon Sep 17 00:00:00 2001
From: Cuong Manh Le
Date: Sun, 13 Jun 2021 10:55:19 +0700
Subject: [PATCH 40/45] cmd/compile: allow ir.OSLICE2ARRPTR in mayCall
CL 301650 adds conversion from slice to array ptr. The conversion
expression may appear as argument to a function call, so it will be
tested by mayCall. But ir.OSLICE2ARRPTR op is not handled by mayCall,
causes the compiler crashes.
Updates #395
Fixes #46720
Change-Id: I39e1b3e38e224a31f3dec46dbbdc855ff3b2c6a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/327649
Trust: Cuong Manh Le
Trust: Josh Bleecher Snyder
Run-TryBot: Cuong Manh Le
Reviewed-by: Matthew Dempsky
Reviewed-by: Josh Bleecher Snyder
TryBot-Result: Go Bot
---
src/cmd/compile/internal/walk/walk.go | 2 +-
test/fixedbugs/issue46720.go | 15 +++++++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
create mode 100644 test/fixedbugs/issue46720.go
diff --git a/src/cmd/compile/internal/walk/walk.go b/src/cmd/compile/internal/walk/walk.go
index fe2c62cd4f..26da6e3145 100644
--- a/src/cmd/compile/internal/walk/walk.go
+++ b/src/cmd/compile/internal/walk/walk.go
@@ -313,7 +313,7 @@ func mayCall(n ir.Node) bool {
return true
case ir.OINDEX, ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR,
- ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODIV, ir.OMOD:
+ ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODIV, ir.OMOD, ir.OSLICE2ARRPTR:
// These ops might panic, make sure they are done
// before we start marshaling args for a call. See issue 16760.
return true
diff --git a/test/fixedbugs/issue46720.go b/test/fixedbugs/issue46720.go
new file mode 100644
index 0000000000..3b0151ae84
--- /dev/null
+++ b/test/fixedbugs/issue46720.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2021 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 p
+
+func f() {
+ nonce := make([]byte, 24)
+ g((*[24]byte)(nonce))
+}
+
+//go:noinline
+func g(*[24]byte) {}
From 24cff0f0444793be81062684c478a3f7ca955499 Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Sat, 12 Jun 2021 12:34:40 +0200
Subject: [PATCH 41/45] cmd/go, misc/cgo: skip test if no .edata
Clang does not produce binaries with an .edata section, even when it
exports symbols properly, so just skip this binutils-specific test for
that case. Later we can rewrite these tests entirely to do something
more robust.
Updates #46719.
Change-Id: I864b3c2d91e66800c55454ae11d4ab1623693d14
Reviewed-on: https://go-review.googlesource.com/c/go/+/327549
Trust: Jason A. Donenfeld
Run-TryBot: Jason A. Donenfeld
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
---
misc/cgo/testcshared/cshared_test.go | 2 +-
src/cmd/go/go_test.go | 10 +---------
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
index 90d8c365e6..fdc6df9602 100644
--- a/misc/cgo/testcshared/cshared_test.go
+++ b/misc/cgo/testcshared/cshared_test.go
@@ -400,7 +400,7 @@ func main() {
defer f.Close()
section := f.Section(".edata")
if section == nil {
- t.Fatalf(".edata section is not present")
+ t.Skip(".edata section is not present")
}
// TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index a059a6dd90..c0c86ab9f5 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -72,7 +72,6 @@ func tooSlow(t *testing.T) {
// (temp) directory.
var testGOROOT string
-var testCC string
var testGOCACHE string
var testGo string
@@ -179,13 +178,6 @@ func TestMain(m *testing.M) {
os.Exit(2)
}
- out, err = exec.Command(gotool, "env", "CC").CombinedOutput()
- if err != nil {
- fmt.Fprintf(os.Stderr, "could not find testing CC: %v\n%s", err, out)
- os.Exit(2)
- }
- testCC = strings.TrimSpace(string(out))
-
cmd := exec.Command(testGo, "env", "CGO_ENABLED")
cmd.Stderr = new(strings.Builder)
if out, err := cmd.Output(); err != nil {
@@ -2185,7 +2177,7 @@ func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
section := f.Section(".edata")
if section == nil {
- t.Fatalf(".edata section is not present")
+ t.Skip(".edata section is not present")
}
// TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
type IMAGE_EXPORT_DIRECTORY struct {
From 14305bf0b9ab87bcaca11416ab61e7a4ba09690d Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Fri, 11 Jun 2021 17:53:29 +0200
Subject: [PATCH 42/45] misc/cgo: generate Windows import libraries for clang
LLD won't import a .dll directly and instead requires an import library.
So generate these using -out-implib, the same way as was done in CL
312046, where it makes sense, and elsewhere build the import library
using a def file. We can't use -out-implib all the time, because the
output file gets overwritten each time the linker is called, rather than
merged.
Updates #46502.
Change-Id: Iefe54cb6c576004b83b1039ba673881b8640423d
Reviewed-on: https://go-review.googlesource.com/c/go/+/327211
Trust: Jason A. Donenfeld
Run-TryBot: Jason A. Donenfeld
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
---
misc/cgo/testcshared/cshared_test.go | 56 +++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
index fdc6df9602..19ad8c76a8 100644
--- a/misc/cgo/testcshared/cshared_test.go
+++ b/misc/cgo/testcshared/cshared_test.go
@@ -292,11 +292,60 @@ func createHeaders() error {
"-installsuffix", "testcshared",
"-o", libgoname,
filepath.Join(".", "libgo", "libgo.go")}
+ if GOOS == "windows" && strings.HasSuffix(args[6], ".a") {
+ args[6] = strings.TrimSuffix(args[6], ".a") + ".dll"
+ }
cmd = exec.Command(args[0], args[1:]...)
out, err = cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out)
}
+ if GOOS == "windows" {
+ // We can't simply pass -Wl,--out-implib, because this relies on having imports from multiple packages,
+ // which results in the linkers output implib getting overwritten at each step. So instead build the
+ // import library the traditional way, using a def file.
+ err = os.WriteFile("libgo.def",
+ []byte("LIBRARY libgo.dll\nEXPORTS\n\tDidInitRun\n\tDidMainRun\n\tDivu\n\tFromPkg\n\t_cgo_dummy_export\n"),
+ 0644)
+ if err != nil {
+ return fmt.Errorf("unable to write def file: %v", err)
+ }
+ out, err = exec.Command(cc[0], append(cc[1:], "-print-prog-name=dlltool")...).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("unable to find dlltool path: %v\n%s\n", err, out)
+ }
+ args := []string{strings.TrimSpace(string(out)), "-D", args[6], "-l", libgoname, "-d", "libgo.def"}
+
+ // This is an unfortunate workaround for https://github.com/mstorsjo/llvm-mingw/issues/205 in which
+ // we basically reimplement the contents of the dlltool.sh wrapper: https://git.io/JZFlU
+ dlltoolContents, err := os.ReadFile(args[0])
+ if err != nil {
+ return fmt.Errorf("unable to read dlltool: %v\n", err)
+ }
+ if bytes.HasPrefix(dlltoolContents, []byte("#!/bin/sh")) && bytes.Contains(dlltoolContents, []byte("llvm-dlltool")) {
+ base, name := filepath.Split(args[0])
+ args[0] = filepath.Join(base, "llvm-dlltool")
+ var machine string
+ switch strings.SplitN(name, "-", 2)[0] {
+ case "i686":
+ machine = "i386"
+ case "x86_64":
+ machine = "i386:x86-64"
+ case "armv7":
+ machine = "arm"
+ case "aarch64":
+ machine = "arm64"
+ }
+ if len(machine) > 0 {
+ args = append(args, "-m", machine)
+ }
+ }
+
+ out, err = exec.Command(args[0], args[1:]...).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("unable to run dlltool to create import library: %v\n%s\n", err, out)
+ }
+ }
if runtime.GOOS != GOOS && GOOS == "android" {
args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname))
@@ -749,7 +798,12 @@ func TestGo2C2Go(t *testing.T) {
defer os.RemoveAll(tmpdir)
lib := filepath.Join(tmpdir, "libtestgo2c2go."+libSuffix)
- run(t, nil, "go", "build", "-buildmode=c-shared", "-o", lib, "./go2c2go/go")
+ var env []string
+ if GOOS == "windows" && strings.HasSuffix(lib, ".a") {
+ env = append(env, "CGO_LDFLAGS=-Wl,--out-implib,"+lib, "CGO_LDFLAGS_ALLOW=.*")
+ lib = strings.TrimSuffix(lib, ".a") + ".dll"
+ }
+ run(t, env, "go", "build", "-buildmode=c-shared", "-o", lib, "./go2c2go/go")
cgoCflags := os.Getenv("CGO_CFLAGS")
if cgoCflags != "" {
From 3249b645c986849bbf72c1dc71efc4f90df465ec Mon Sep 17 00:00:00 2001
From: Cuong Manh Le
Date: Sun, 13 Jun 2021 22:26:21 +0700
Subject: [PATCH 43/45] cmd/compile: factor out rewrite multi-valued f()
So next CL can reuse code to rewrite OAS2FUNC.
Passes toolstash -cmp.
For #46725
Change-Id: I1113ed615b6d6b9494dd87000ce342d7a46d9e7b
Reviewed-on: https://go-review.googlesource.com/c/go/+/327650
Trust: Cuong Manh Le
Run-TryBot: Cuong Manh Le
TryBot-Result: Go Bot
Reviewed-by: Matthew Dempsky
---
.../compile/internal/typecheck/typecheck.go | 31 ++++++++++++-------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go
index 95f7b50259..391e18bd0a 100644
--- a/src/cmd/compile/internal/typecheck/typecheck.go
+++ b/src/cmd/compile/internal/typecheck/typecheck.go
@@ -945,16 +945,18 @@ func typecheckargs(n ir.InitNode) {
return
}
- // Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
-
// Save n as n.Orig for fmt.go.
if ir.Orig(n) == n {
n.(ir.OrigNode).SetOrig(ir.SepCopy(n))
}
- as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
- as.Rhs.Append(list...)
+ // Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
+ rewriteMultiValueCall(n, list[0])
+}
+// rewriteMultiValueCall rewrites multi-valued f() to use temporaries,
+// so the backend wouldn't need to worry about tuple-valued expressions.
+func rewriteMultiValueCall(n ir.InitNode, call ir.Node) {
// If we're outside of function context, then this call will
// be executed during the generated init function. However,
// init.go hasn't yet created it. Instead, associate the
@@ -964,25 +966,30 @@ func typecheckargs(n ir.InitNode) {
if static {
ir.CurFunc = InitTodoFunc
}
- list = nil
- for _, f := range t.FieldSlice() {
- t := Temp(f.Type)
- as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, t))
- as.Lhs.Append(t)
- list = append(list, t)
+
+ as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call})
+ results := call.Type().FieldSlice()
+ list := make([]ir.Node, len(results))
+ for i, result := range results {
+ tmp := Temp(result.Type)
+ as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp))
+ as.Lhs.Append(tmp)
+ list[i] = tmp
}
if static {
ir.CurFunc = nil
}
+ n.PtrInit().Append(Stmt(as))
+
switch n := n.(type) {
+ default:
+ base.Fatalf("rewriteMultiValueCall %+v", n.Op())
case *ir.CallExpr:
n.Args = list
case *ir.ReturnStmt:
n.Results = list
}
-
- n.PtrInit().Append(Stmt(as))
}
func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {
From 326ea438bb579a2010e38e00f515a04344ff96b0 Mon Sep 17 00:00:00 2001
From: Cuong Manh Le
Date: Sun, 13 Jun 2021 22:28:44 +0700
Subject: [PATCH 44/45] cmd/compile: rewrite a, b = f() to use temporaries when
type not identical
If any of the LHS expressions of an OAS2FUNC are not identical to the
respective function call results, escape analysis mishandles the
implicit conversion, causes memory corruption.
Instead, we should insert autotmps like we already do for f(g()) calls
and return g() statements.
Fixes #46725
Change-Id: I71a08da0bf1a03d09a023da5b6f78fb37a4a4690
Reviewed-on: https://go-review.googlesource.com/c/go/+/327651
Trust: Cuong Manh Le
Run-TryBot: Cuong Manh Le
TryBot-Result: Go Bot
Reviewed-by: Matthew Dempsky
---
src/cmd/compile/internal/typecheck/stmt.go | 14 +++++-
.../compile/internal/typecheck/typecheck.go | 10 ++++
test/declbad.go | 4 +-
test/fixedbugs/issue46725.go | 48 +++++++++++++++++++
4 files changed, 73 insertions(+), 3 deletions(-)
create mode 100644 test/fixedbugs/issue46725.go
diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go
index 175216f279..922a01bfbe 100644
--- a/src/cmd/compile/internal/typecheck/stmt.go
+++ b/src/cmd/compile/internal/typecheck/stmt.go
@@ -204,8 +204,20 @@ assignOK:
r.Use = ir.CallUseList
rtyp := r.Type()
+ mismatched := false
+ failed := false
for i := range lhs {
- assignType(i, rtyp.Field(i).Type)
+ result := rtyp.Field(i).Type
+ assignType(i, result)
+
+ if lhs[i].Type() == nil || result == nil {
+ failed = true
+ } else if lhs[i] != ir.BlankNode && !types.Identical(lhs[i].Type(), result) {
+ mismatched = true
+ }
+ }
+ if mismatched && !failed {
+ rewriteMultiValueCall(stmt, r)
}
return
}
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go
index 391e18bd0a..bf52941b2c 100644
--- a/src/cmd/compile/internal/typecheck/typecheck.go
+++ b/src/cmd/compile/internal/typecheck/typecheck.go
@@ -989,6 +989,16 @@ func rewriteMultiValueCall(n ir.InitNode, call ir.Node) {
n.Args = list
case *ir.ReturnStmt:
n.Results = list
+ case *ir.AssignListStmt:
+ if n.Op() != ir.OAS2FUNC {
+ base.Fatalf("rewriteMultiValueCall: invalid op %v", n.Op())
+ }
+ as.SetOp(ir.OAS2FUNC)
+ n.SetOp(ir.OAS2)
+ n.Rhs = make([]ir.Node, len(list))
+ for i, tmp := range list {
+ n.Rhs[i] = AssignConv(tmp, n.Lhs[i].Type(), "assignment")
+ }
}
}
diff --git a/test/declbad.go b/test/declbad.go
index 728eceb7f1..b978652a2b 100644
--- a/test/declbad.go
+++ b/test/declbad.go
@@ -23,13 +23,13 @@ func main() {
{
// change of type for f
i, f, s := f3()
- f, g, t := f3() // ERROR "redeclared|cannot assign|incompatible"
+ f, g, t := f3() // ERROR "redeclared|cannot assign|incompatible|cannot use"
_, _, _, _, _ = i, f, s, g, t
}
{
// change of type for i
i, f, s := f3()
- j, i, t := f3() // ERROR "redeclared|cannot assign|incompatible"
+ j, i, t := f3() // ERROR "redeclared|cannot assign|incompatible|cannot use"
_, _, _, _, _ = i, f, s, j, t
}
{
diff --git a/test/fixedbugs/issue46725.go b/test/fixedbugs/issue46725.go
new file mode 100644
index 0000000000..29799c7d7e
--- /dev/null
+++ b/test/fixedbugs/issue46725.go
@@ -0,0 +1,48 @@
+// run
+
+// Copyright 2021 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 main
+
+import "runtime"
+
+type T [4]int
+
+//go:noinline
+func g(x []*T) ([]*T, []*T) { return x, x }
+
+func main() {
+ const Jenny = 8675309
+ s := [10]*T{{Jenny}}
+
+ done := make(chan struct{})
+ runtime.SetFinalizer(s[0], func(p *T) { close(done) })
+
+ var h, _ interface{} = g(s[:])
+
+ if wait(done) {
+ panic("GC'd early")
+ }
+
+ if h.([]*T)[0][0] != Jenny {
+ panic("lost Jenny's number")
+ }
+
+ if !wait(done) {
+ panic("never GC'd")
+ }
+}
+
+func wait(done <-chan struct{}) bool {
+ for i := 0; i < 10; i++ {
+ runtime.GC()
+ select {
+ case <-done:
+ return true
+ default:
+ }
+ }
+ return false
+}
From fdab5be159c508c4c1cf5be84119fd2b38403cdf Mon Sep 17 00:00:00 2001
From: Joel Sing
Date: Mon, 14 Jun 2021 23:47:10 +1000
Subject: [PATCH 45/45] doc/go1.17: further revise OpenBSD release notes
Simplify and remove forward-compatibility reference, as OpenBSD 6.9 has
already been released (1st of May 2021).
Updates #44513
Change-Id: I0a1abbb397f31d15c80a970edaa9723f894cafa9
Reviewed-on: https://go-review.googlesource.com/c/go/+/327652
Trust: Joel Sing
Reviewed-by: Cherry Mui
---
doc/go1.17.html | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index 4fa38921f0..35d0f97450 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -106,8 +106,7 @@ Do not send CLs removing the interior tags from such phrases.
of directly using machine instructions. In Go 1.17, this is also
done on the 32-bit x86 and 32-bit ARM architectures on OpenBSD
(the openbsd/386
and openbsd/arm
ports).
- This ensures forward-compatibility with future versions of
- OpenBSD, in particular, with OpenBSD 6.9 onwards, which requires
+ This ensures compatibility with OpenBSD 6.9 onwards, which require
system calls to be made through libc
for non-static
Go binaries.