aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2023-01-17 13:45:09 -0500
committerCherry Mui <cherryyz@google.com>2023-01-17 13:45:09 -0500
commit670ce9b8a85fe6c7ea617aa780451c4e564e3075 (patch)
tree8e83031552afeed1aed8a8ec2781e668ad98d68c
parentb3160e8bcedb25c5266e047ada01b6f462521401 (diff)
parent9088c691dac424540f562d6271c5ee479e9f9d80 (diff)
downloadgo-670ce9b8a85fe6c7ea617aa780451c4e564e3075.tar.gz
go-670ce9b8a85fe6c7ea617aa780451c4e564e3075.zip
[release-branch.go1.20] all: merge master (9088c69) into release-branch.go1.20
Merge List: + 2023-01-17 9088c691da cmd/compile: ensure temp register mask isn't empty + 2023-01-17 c0799f7015 os: document that Rename is not atomic on non-Unix platforms + 2023-01-17 d74c31f0ba doc/go1.20: update cryptography release notes + 2023-01-17 8e19929436 strings: remove redundant symbols + 2023-01-17 6cb8c43b84 cmd/go: include coverage build flags for "go list" + 2023-01-17 02ed0e5e67 crypto/ed25519: improve Ed25519ctx docs and add example + 2023-01-17 f375b305c8 crypto/x509: clarify that CheckSignatureFrom and CheckSignature are low-level APIs + 2023-01-17 8409251e10 cmd/go: document GODEBUG=installgoroot=all + 2023-01-17 66689c7d46 doc/go1.20: remove mention of arena goexperiment + 2023-01-17 145dd38471 archive/tar, archive/zip: document ErrInsecurePath and GODEBUG setting + 2023-01-16 1c65b69bd1 runtime: fix performance regression in morestack_noctxt on ppc64 + 2023-01-13 ebb572d82f Revert "internal/fsys: follow root symlink in fsys.Walk" + 2023-01-13 16cec4e7a0 doc/go1.20: mention build speed improvements + 2023-01-13 643f463186 cmd/cover: remove go.mod from testdata subdir Change-Id: I4d56c9353d423f7e7169db7e30cb59515d422a56
-rw-r--r--doc/go1.20.html89
-rw-r--r--src/archive/tar/reader.go8
-rw-r--r--src/archive/zip/reader.go8
-rw-r--r--src/cmd/compile/internal/ssa/regalloc.go2
-rw-r--r--src/cmd/cover/testdata/pkgcfg/go.mod3
-rw-r--r--src/cmd/go/alldocs.go10
-rw-r--r--src/cmd/go/internal/fsys/fsys.go28
-rw-r--r--src/cmd/go/internal/fsys/fsys_test.go4
-rw-r--r--src/cmd/go/internal/list/list.go3
-rw-r--r--src/cmd/go/internal/work/build.go10
-rw-r--r--src/cmd/go/script_test.go1
-rw-r--r--src/cmd/go/testdata/script/cover_list.txt28
-rw-r--r--src/cmd/go/testdata/script/list_goroot_symlink.txt63
-rw-r--r--src/cmd/go/testdata/script/list_symlink_dotdotdot.txt20
-rw-r--r--src/crypto/ed25519/ed25519.go37
-rw-r--r--src/crypto/ed25519/ed25519_test.go23
-rw-r--r--src/crypto/x509/x509.go13
-rw-r--r--src/os/file.go1
-rw-r--r--src/runtime/asm_ppc64x.s5
-rw-r--r--src/strings/clone_test.go2
-rw-r--r--test/fixedbugs/issue57846.go33
21 files changed, 274 insertions, 117 deletions
diff --git a/doc/go1.20.html b/doc/go1.20.html
index 23fa82c41b..324d59ed6e 100644
--- a/doc/go1.20.html
+++ b/doc/go1.20.html
@@ -289,17 +289,6 @@ Do not send CLs removing the interior tags from such phrases.
<h2 id="runtime">Runtime</h2>
-<p><!-- CL 423359, https://go.dev/issue/51317 -->
- The runtime now has experimental support for memory-safe arena allocation
- that makes it possible to eagerly free memory in bulk.
- When used appropriately, it has the potential to improve CPU performance by
- up to 15% in memory-allocation-heavy applications.
- To try it out, build your Go program with <code>GOEXPERIMENT=arenas</code>,
- which will make the <code>arena</code> package visible to your program.
- Source files that import the <code>arena</code> package must require the
- <code>goexperiment.arenas</code> build tag.
-</p>
-
<p><!-- CL 422634 -->
Some of the garbage collector's internal data structures were reorganized to
be both more space and CPU efficient.
@@ -350,8 +339,10 @@ Do not send CLs removing the interior tags from such phrases.
</p>
<p><!-- https://go.dev/issue/49569 -->
- Relative to Go 1.19, generated code performance is generally slightly improved,
- build wall times are slightly increased, build user times are slightly decreased.
+ Go 1.18 and 1.19 saw regressions in build speed, largely due to the addition
+ of support for generics and follow-on work. Go 1.20 improves build speeds by
+ up to 10%, bringing it back in line with Go 1.17.
+ Relative to Go 1.19, generated code performance is also generally slightly improved.
</p>
<h2 id="linker">Linker</h2>
@@ -398,13 +389,13 @@ Do not send CLs removing the interior tags from such phrases.
<p><!-- https://go.dev/issue/52221, CL 398914, CL 450335, https://go.dev/issue/56052 -->
Go 1.20 adds a new <a href="/pkg/crypto/ecdh/"><code>crypto/ecdh</code></a> package
- to provide direct support for Elliptic Curve Diffie-Hellman key exchange
+ to provide explicit support for Elliptic Curve Diffie-Hellman key exchanges
over NIST curves and Curve25519.
</p>
<p>
- Programs should prefer to use <code>crypto/ecdh</code>
- or <a href="/pkg/crypto/ecdsa/"><code>crypto/ecdsa</code></a>
- instead of the lower-level functionality in <a href="/pkg/crypto/elliptic/"><code>crypto/elliptic</code></a>.
+ Programs should use <code>crypto/ecdh</code> instead of the lower-level functionality in
+ <a href="/pkg/crypto/elliptic/"><code>crypto/elliptic</code></a> for ECDH, and
+ third-party modules for more advanced use cases.
</p>
<h3 id="errors">Wrapping multiple errors</h3>
@@ -592,6 +583,11 @@ proxyHandler := &httputil.ReverseProxy{
<dl id="crypto/ecdsa"><dt><a href="/pkg/crypto/ecdsa/">crypto/ecdsa</a></dt>
<dd>
+ <p><!-- CL 353849 -->
+ When using supported curves, all operations are now implemented in constant time.
+ This led to an increase in CPU time between 5% and 30%, mostly affecting P-384 and P-521.
+ </p>
+
<p><!-- https://go.dev/issue/56088, CL 450816 -->
The new <a href="/pkg/crypto/ecdsa/#PrivateKey.ECDH"><code>PrivateKey.ECDH</code></a> method
converts an <code>ecdsa.PrivateKey</code> to an <code>ecdh.PrivateKey</code>.
@@ -618,25 +614,21 @@ proxyHandler := &httputil.ReverseProxy{
</dd>
</dl><!-- crypto/ed25519 -->
-<dl id="crypto/elliptic"><dt><a href="/pkg/crypto/elliptic/">crypto/elliptic</a></dt>
- <dd>
- <p><!-- https://go.dev/issue/34648 -->
- Use of custom <a href="/pkg/crypto/elliptic/#Curve"><code>Curve</code></a> implementations
- not provided by this package (that is, curves other than
- <a href="/pkg/crypto/elliptic/#P224"><code>P224</code></a>,
- <a href="/pkg/crypto/elliptic/#P256"><code>P256</code></a>,
- <a href="/pkg/crypto/elliptic/#P384"><code>P384</code></a>, and
- <a href="/pkg/crypto/elliptic/#P521"><code>P521</code></a>)
- is deprecated.
- </p>
- </dd>
-</dl><!-- crypto/elliptic -->
-
<dl id="crypto/rsa"><dt><a href="/pkg/crypto/rsa/">crypto/rsa</a></dt>
<dd>
<p><!-- CL 418874, https://go.dev/issue/19974 -->
The new field <a href="/pkg/crypto/rsa/#OAEPOptions.MGFHash"><code>OAEPOptions.MGFHash</code></a>
- allows configuring the MGF1 hash separately for OAEP encryption.
+ allows configuring the MGF1 hash separately for OAEP decryption.
+ </p>
+
+ <p><!-- https://go.dev/issue/20654 -->
+ crypto/rsa now uses a new, safer, constant-time backend. This causes a CPU
+ runtime increase for decryption operations between approximately 15%
+ (RSA-2048 on amd64) and 45% (RSA-4096 on arm64), and more on 32-bit architectures.
+ Encryption operations are approximately 20x slower than before (but still 5-10x faster than decryption).
+ Performance is expected to improve in future releases.
+ Programs must not modify or manually generate the fields of
+ <a href="/pkg/crypto/rsa/#PrecomputedValues"><code>PrecomputedValues</code></a>.
</p>
</dd>
</dl><!-- crypto/rsa -->
@@ -652,9 +644,9 @@ proxyHandler := &httputil.ReverseProxy{
<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
<dd>
- <p><!-- CL 426455 -->
- The TLS client now shares parsed certificates across all clients actively using that certificate.
- The savings can be significant in programs that make many concurrent connections to a
+ <p><!-- CL 426455, CL 427155, CL 426454, https://go.dev/issue/46035 -->
+ Parsed certificates are now shared across all clients actively using that certificate.
+ The memory savings can be significant in programs that make many concurrent connections to a
server or collection of servers sharing any part of their certificate chains.
</p>
@@ -669,22 +661,22 @@ proxyHandler := &httputil.ReverseProxy{
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
- <p><!-- CL 450816 -->
- <a href="/pkg/crypto/x509/#CreateCertificateRequest"><code>CreateCertificateRequest</code></a>
+ <p><!-- CL 450816, CL 450815 -->
+ <a href="/pkg/crypto/x509/#ParsePKCS8PrivateKey"><code>ParsePKCS8PrivateKey</code></a>
and
<a href="/pkg/crypto/x509/#MarshalPKCS8PrivateKey"><code>MarshalPKCS8PrivateKey</code></a>
now support keys of type <a href="/pkg/crypto/ecdh.PrivateKey"><code>*crypto/ecdh.PrivateKey</code></a>.
- <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
+ <a href="/pkg/crypto/x509/#ParsePKIXPublicKey"><code>ParsePKIXPublicKey</code></a>
and
<a href="/pkg/crypto/x509/#MarshalPKIXPublicKey"><code>MarshalPKIXPublicKey</code></a>
now support keys of type <a href="/pkg/crypto/ecdh.PublicKey"><code>*crypto/ecdh.PublicKey</code></a>.
- X.509 unmarshaling continues to unmarshal elliptic curve keys into
+ Parsing NIST curve keys still returns values of type
<code>*ecdsa.PublicKey</code> and <code>*ecdsa.PrivateKey</code>.
- Use their new <code>ECDH</code> methods to convert to the <code>crypto/ecdh</code> form.
+ Use their new <code>ECDH</code> methods to convert to the <code>crypto/ecdh</code> types.
</p>
<p><!-- CL 449235 -->
The new <a href="/pkg/crypto/x509/#SetFallbackRoots"><code>SetFallbackRoots</code></a>
- function allows a program to define a set of fallback root certificates in case the
+ function allows a program to define a set of fallback root certificates in case an
operating system verifier or standard platform root bundle is unavailable at runtime.
It will most commonly be used with a new package, <a href="/pkg/golang.org/x/crypto/x509roots/fallback">golang.org/x/crypto/x509roots/fallback</a>,
which will provide an up to date root bundle.
@@ -841,6 +833,20 @@ proxyHandler := &httputil.ReverseProxy{
</dd>
</dl><!-- io -->
+<dl id="math/big"><dt><a href="/pkg/math/big/">math/big</a></dt>
+ <dd>
+ <p><!-- https://go.dev/issue/52182 -->
+ The <a href="/pkg/math/big/">math/big</a> package's wide scope and
+ input-dependent timing make it ill-suited for implementing cryptography.
+ The cryptography packages in the standard library no longer call non-trivial
+ <a href="/pkg/math/big#Int">Int</a> methods on attacker-controlled inputs.
+ In the future, the determination of whether a bug in math/big is
+ considered a security vulnerability will depend on its wider impact on the
+ standard library.
+ </p>
+ </dd>
+</dl><!-- math/big -->
+
<dl id="math/rand"><dt><a href="/pkg/math/rand/">math/rand</a></dt>
<dd>
<p><!-- https://go.dev/issue/54880, CL 436955, https://go.dev/issue/56319 -->
@@ -1238,3 +1244,4 @@ proxyHandler := &httputil.ReverseProxy{
<!-- CL 453616 fix deprecation comment in archive/zip -->
<!-- CL 453617 fix deprecation comment in encoding/csv -->
<!-- https://go.dev/issue/54661 x/tools/go/analysis -->
+<!-- CL 423359, https://go.dev/issue/51317 arena -->
diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go
index 82a5a5a293..768ca1968d 100644
--- a/src/archive/tar/reader.go
+++ b/src/archive/tar/reader.go
@@ -43,8 +43,14 @@ func NewReader(r io.Reader) *Reader {
// Next advances to the next entry in the tar archive.
// The Header.Size determines how many bytes can be read for the next file.
// Any remaining data in the current file is automatically discarded.
+// At the end of the archive, Next returns the error io.EOF.
//
-// io.EOF is returned at the end of the input.
+// If Next encounters a non-local name (as defined by [filepath.IsLocal])
+// and the GODEBUG environment variable contains `tarinsecurepath=0`,
+// Next returns the header with an ErrInsecurePath error.
+// A future version of Go may introduce this behavior by default.
+// Programs that want to accept non-local names can ignore
+// the ErrInsecurePath error and use the returned header.
func (tr *Reader) Next() (*Header, error) {
if tr.err != nil {
return nil, tr.err
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index a2ae74e541..a1554d2c52 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -87,6 +87,14 @@ func OpenReader(name string) (*ReadCloser, error) {
// NewReader returns a new Reader reading from r, which is assumed to
// have the given size in bytes.
+//
+// If any file inside the archive uses a non-local name
+// (as defined by [filepath.IsLocal]) or a name containing backslashes
+// and the GODEBUG environment variable contains `zipinsecurepath=0`,
+// NewReader returns the reader with an ErrInsecurePath error.
+// A future version of Go may introduce this behavior by default.
+// Programs that want to accept non-local names can ignore
+// the ErrInsecurePath error and use the returned reader.
func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
if size < 0 {
return nil, errors.New("zip: size cannot be negative")
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
index 3cfe7330d1..294c522a90 100644
--- a/src/cmd/compile/internal/ssa/regalloc.go
+++ b/src/cmd/compile/internal/ssa/regalloc.go
@@ -1561,7 +1561,7 @@ func (s *regAllocState) regalloc(f *Func) {
// (Not all instructions need that distinct part, but it is conservative.)
if opcodeTable[v.Op].needIntTemp {
m := s.allocatable & s.f.Config.gpRegMask
- if m&^desired.avoid != 0 {
+ if m&^desired.avoid&^s.nospill != 0 {
m &^= desired.avoid
}
tmpReg = s.allocReg(m, &tmpVal)
diff --git a/src/cmd/cover/testdata/pkgcfg/go.mod b/src/cmd/cover/testdata/pkgcfg/go.mod
deleted file mode 100644
index 3d2ee96414..0000000000
--- a/src/cmd/cover/testdata/pkgcfg/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module cfg
-
-go 1.19
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 4c72ab6d56..84afcab7a0 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -746,9 +746,15 @@
// If module-aware mode is enabled, "go install" runs in the context of the main
// module.
//
-// When module-aware mode is disabled, other packages are installed in the
+// When module-aware mode is disabled, non-main packages are installed in the
// directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
-// other packages are built and cached but not installed.
+// non-main packages are built and cached but not installed.
+//
+// Before Go 1.20, the standard library was installed to
+// $GOROOT/pkg/$GOOS_$GOARCH.
+// Starting in Go 1.20, the standard library is built and cached but not installed.
+// Setting GODEBUG=installgoroot=all restores the use of
+// $GOROOT/pkg/$GOOS_$GOARCH.
//
// For more about the build flags, see 'go help build'.
// For more about specifying packages, see 'go help packages'.
diff --git a/src/cmd/go/internal/fsys/fsys.go b/src/cmd/go/internal/fsys/fsys.go
index 07bdc16aba..454574a592 100644
--- a/src/cmd/go/internal/fsys/fsys.go
+++ b/src/cmd/go/internal/fsys/fsys.go
@@ -476,23 +476,19 @@ func IsDirWithGoFiles(dir string) (bool, error) {
// walk recursively descends path, calling walkFn. Copied, with some
// modifications from path/filepath.walk.
-// Walk follows the root if it's a symlink, but reports the original paths,
-// so it calls walk with both the resolvedPath (which is the path with the root resolved)
-// and path (which is the path reported to the walkFn).
-func walk(path, resolvedPath string, info fs.FileInfo, walkFn filepath.WalkFunc) error {
+func walk(path string, info fs.FileInfo, walkFn filepath.WalkFunc) error {
if err := walkFn(path, info, nil); err != nil || !info.IsDir() {
return err
}
- fis, err := ReadDir(resolvedPath)
+ fis, err := ReadDir(path)
if err != nil {
return walkFn(path, info, err)
}
for _, fi := range fis {
filename := filepath.Join(path, fi.Name())
- resolvedFilename := filepath.Join(resolvedPath, fi.Name())
- if err := walk(filename, resolvedFilename, fi, walkFn); err != nil {
+ if err := walk(filename, fi, walkFn); err != nil {
if !fi.IsDir() || err != filepath.SkipDir {
return err
}
@@ -509,23 +505,7 @@ func Walk(root string, walkFn filepath.WalkFunc) error {
if err != nil {
err = walkFn(root, nil, err)
} else {
- resolved := root
- if info.Mode()&os.ModeSymlink != 0 {
- // Walk follows root if it's a symlink (but does not follow other symlinks).
- if op, ok := OverlayPath(root); ok {
- resolved = op
- }
- resolved, err = os.Readlink(resolved)
- if err != nil {
- return err
- }
- // Re-stat to get the info for the resolved file.
- info, err = Lstat(resolved)
- if err != nil {
- return err
- }
- }
- err = walk(root, resolved, info, walkFn)
+ err = walk(root, info, walkFn)
}
if err == filepath.SkipDir {
return nil
diff --git a/src/cmd/go/internal/fsys/fsys_test.go b/src/cmd/go/internal/fsys/fsys_test.go
index deb63f22e6..b441e19afe 100644
--- a/src/cmd/go/internal/fsys/fsys_test.go
+++ b/src/cmd/go/internal/fsys/fsys_test.go
@@ -844,8 +844,8 @@ func TestWalkSymlink(t *testing.T) {
{"control", "dir", []string{"dir", "dir" + string(filepath.Separator) + "file"}},
// ensure Walk doesn't walk into the directory pointed to by the symlink
// (because it's supposed to use Lstat instead of Stat).
- {"symlink_to_dir", "symlink", []string{"symlink", "symlink" + string(filepath.Separator) + "file"}},
- {"overlay_to_symlink_to_dir", "overlay_symlink", []string{"overlay_symlink", "overlay_symlink" + string(filepath.Separator) + "file"}},
+ {"symlink_to_dir", "symlink", []string{"symlink"}},
+ {"overlay_to_symlink_to_dir", "overlay_symlink", []string{"overlay_symlink"}},
}
for _, tc := range testCases {
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index 72201850b2..811d659ba3 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -336,6 +336,9 @@ For more about modules, see https://golang.org/ref/mod.
func init() {
CmdList.Run = runList // break init cycle
work.AddBuildFlags(CmdList, work.DefaultBuildFlags)
+ if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign {
+ work.AddCoverFlags(CmdList, nil)
+ }
CmdList.Flag.Var(&listJsonFields, "json", "")
}
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index 27fa090f83..2f2860aeb5 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -590,9 +590,15 @@ variable and the presence of a go.mod file. See 'go help modules' for details.
If module-aware mode is enabled, "go install" runs in the context of the main
module.
-When module-aware mode is disabled, other packages are installed in the
+When module-aware mode is disabled, non-main packages are installed in the
directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
-other packages are built and cached but not installed.
+non-main packages are built and cached but not installed.
+
+Before Go 1.20, the standard library was installed to
+$GOROOT/pkg/$GOOS_$GOARCH.
+Starting in Go 1.20, the standard library is built and cached but not installed.
+Setting GODEBUG=installgoroot=all restores the use of
+$GOROOT/pkg/$GOOS_$GOARCH.
For more about the build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index 3cbaeff8ad..4211fb6121 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -211,6 +211,7 @@ func scriptEnv(srv *vcstest.Server, srvCertFile string) ([]string, error) {
"GOROOT_FINAL=" + testGOROOT_FINAL, // causes spurious rebuilds and breaks the "stale" built-in if not propagated
"GOTRACEBACK=system",
"TESTGO_GOROOT=" + testGOROOT,
+ "TESTGO_EXE=" + testGo,
"TESTGO_VCSTEST_HOST=" + httpURL.Host,
"TESTGO_VCSTEST_TLS_HOST=" + httpsURL.Host,
"TESTGO_VCSTEST_CERT=" + srvCertFile,
diff --git a/src/cmd/go/testdata/script/cover_list.txt b/src/cmd/go/testdata/script/cover_list.txt
new file mode 100644
index 0000000000..c66c087793
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_list.txt
@@ -0,0 +1,28 @@
+
+# This test is intended to verify that "go list" accepts coverage related
+# build arguments (such as -cover, -covermode). See issue #57785.
+
+[short] skip
+[!GOEXPERIMENT:coverageredesign] skip
+
+env GOBIN=$WORK/bin
+
+# Install a target and then do an ordinary staleness check on it.
+go install m/example
+! stale m/example
+
+# Run a second staleness check with "-cover" as a build flag. The
+# installed target should indeed be stale, since we didn't build it
+# with -cover.
+stale -cover m/example
+
+-- go.mod --
+module m
+
+go 1.20
+-- example/main.go --
+package main
+
+func main() {
+ println("hi mom")
+}
diff --git a/src/cmd/go/testdata/script/list_goroot_symlink.txt b/src/cmd/go/testdata/script/list_goroot_symlink.txt
new file mode 100644
index 0000000000..8e50e4beab
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_goroot_symlink.txt
@@ -0,0 +1,63 @@
+# Regression test for https://go.dev/issue/57754: 'go list' failed if ../src
+# relative to the location of the go executable was a symlink to the real src
+# directory. (cmd/go expects that ../src is GOROOT/src, but it appears that the
+# Debian build of the Go toolchain is attempting to split GOROOT into binary and
+# source artifacts in different parent directories.)
+
+[short] skip 'copies the cmd/go binary'
+[!symlink] skip 'tests symlink-specific behavior'
+
+# Ensure that the relative path to $WORK/lib/goroot/src from $PWD is a different
+# number of ".." hops than the relative path to it from $WORK/share/goroot/src.
+
+cd $WORK
+
+# Construct a fake GOROOT in $WORK/lib/goroot whose src directory is a symlink
+# to a subdirectory of $WORK/share. This mimics the directory structure reported
+# in https://go.dev/issue/57754.
+#
+# Symlink everything else to the original $GOROOT to avoid needless copying work.
+
+mkdir $WORK/lib/goroot
+mkdir $WORK/share/goroot
+symlink $WORK/share/goroot/src -> $GOROOT${/}src
+symlink $WORK/lib/goroot/src -> ../../share/goroot/src
+symlink $WORK/lib/goroot/pkg -> $GOROOT${/}pkg
+
+# Verify that our symlink shenanigans don't prevent cmd/go from finding its
+# GOROOT using os.Executable.
+#
+# To do so, we copy the actual cmd/go executable — which is implemented as the
+# cmd/go test binary instead of the original $GOROOT/bin/go, which may be
+# arbitrarily stale — into the bin subdirectory of the fake GOROOT, causing
+# os.Executable to report a path in that directory.
+
+mkdir $WORK/lib/goroot/bin
+cp $TESTGO_EXE $WORK/lib/goroot/bin/go$GOEXE
+
+env GOROOT='' # Clear to force cmd/go to find GOROOT itself.
+exec $WORK/lib/goroot/bin/go env GOROOT
+stdout $WORK${/}lib${/}goroot
+
+# Now verify that 'go list' can find standard-library packages in the symlinked
+# source tree, with paths matching the one reported by 'go env GOROOT'.
+
+exec $WORK/lib/goroot/bin/go list -f '{{.ImportPath}}: {{.Dir}}' encoding/binary
+stdout '^encoding/binary: '$WORK${/}lib${/}goroot${/}src${/}encoding${/}binary'$'
+
+ # BUG(#50807): This doesn't work on Windows for some reason — perhaps
+ # a bug in the Windows Lstat implementation with trailing separators?
+[!GOOS:windows] exec $WORK/lib/goroot/bin/go list -f '{{.ImportPath}}: {{.Dir}}' std
+[!GOOS:windows] stdout '^encoding/binary: '$WORK${/}lib${/}goroot${/}src${/}encoding${/}binary'$'
+
+# Most path lookups in GOROOT are not sensitive to symlinks. However, patterns
+# involving '...' wildcards must use Walk to check the GOROOT tree, which makes
+# them more sensitive to symlinks (because Walk doesn't follow them).
+#
+# So we check such a pattern to confirm that it works and reports a path relative
+# to $GOROOT/src (and not the symlink target).
+
+ # BUG(#50807): This should report encoding/binary, not "matched no packages".
+exec $WORK/lib/goroot/bin/go list -f '{{.ImportPath}}: {{.Dir}}' .../binary
+! stdout .
+stderr '^go: warning: "\.\.\./binary" matched no packages$'
diff --git a/src/cmd/go/testdata/script/list_symlink_dotdotdot.txt b/src/cmd/go/testdata/script/list_symlink_dotdotdot.txt
deleted file mode 100644
index 8df1982484..0000000000
--- a/src/cmd/go/testdata/script/list_symlink_dotdotdot.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-[!symlink] skip
-
-symlink $WORK/gopath/src/sym -> $WORK/gopath/src/tree
-symlink $WORK/gopath/src/tree/squirrel -> $WORK/gopath/src/dir2 # this symlink should not be followed
-cd sym
-go list ./...
-cmp stdout $WORK/gopath/src/want_list.txt
--- tree/go.mod --
-module example.com/tree
-
-go 1.20
--- tree/tree.go --
-package tree
--- tree/branch/branch.go --
-package branch
--- dir2/squirrel.go --
-package squirrel
--- want_list.txt --
-example.com/tree
-example.com/tree/branch
diff --git a/src/crypto/ed25519/ed25519.go b/src/crypto/ed25519/ed25519.go
index 921bbaa8ed..a45d056851 100644
--- a/src/crypto/ed25519/ed25519.go
+++ b/src/crypto/ed25519/ed25519.go
@@ -49,10 +49,10 @@ func (pub PublicKey) Equal(x crypto.PublicKey) bool {
return bytes.Equal(pub, xx)
}
-// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
+// PrivateKey is the type of Ed25519 private keys. It implements [crypto.Signer].
type PrivateKey []byte
-// Public returns the PublicKey corresponding to priv.
+// Public returns the [PublicKey] corresponding to priv.
func (priv PrivateKey) Public() crypto.PublicKey {
publicKey := make([]byte, PublicKeySize)
copy(publicKey, priv[32:])
@@ -75,11 +75,15 @@ func (priv PrivateKey) Seed() []byte {
return bytes.Clone(priv[:SeedSize])
}
-// Sign signs the given message with priv. rand is ignored. If opts.HashFunc()
-// is crypto.SHA512, the pre-hashed variant Ed25519ph is used and message is
-// expected to be a SHA-512 hash, otherwise opts.HashFunc() must be
-// crypto.Hash(0) and the message must not be hashed, as Ed25519 performs two
+// Sign signs the given message with priv. rand is ignored.
+//
+// If opts.HashFunc() is [crypto.SHA512], the pre-hashed variant Ed25519ph is used
+// and message is expected to be a SHA-512 hash, otherwise opts.HashFunc() must
+// be [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
// passes over messages to be signed.
+//
+// A value of type [Options] can be used as opts, or crypto.Hash(0) or
+// crypto.SHA512 directly to select plain Ed25519 or Ed25519ph, respectively.
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
hash := opts.HashFunc()
context := ""
@@ -108,7 +112,7 @@ func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOp
}
}
-// Options can be used with PrivateKey.Sign or VerifyWithOptions
+// Options can be used with [PrivateKey.Sign] or [VerifyWithOptions]
// to select Ed25519 variants.
type Options struct {
// Hash can be zero for regular Ed25519, or crypto.SHA512 for Ed25519ph.
@@ -119,10 +123,11 @@ type Options struct {
Context string
}
+// HashFunc returns o.Hash.
func (o *Options) HashFunc() crypto.Hash { return o.Hash }
// GenerateKey generates a public/private key pair using entropy from rand.
-// If rand is nil, crypto/rand.Reader will be used.
+// If rand is nil, [crypto/rand.Reader] will be used.
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
if rand == nil {
rand = cryptorand.Reader
@@ -141,7 +146,7 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
}
// NewKeyFromSeed calculates a private key from a seed. It will panic if
-// len(seed) is not SeedSize. This function is provided for interoperability
+// len(seed) is not [SeedSize]. This function is provided for interoperability
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
// package.
func NewKeyFromSeed(seed []byte) PrivateKey {
@@ -170,7 +175,7 @@ func newKeyFromSeed(privateKey, seed []byte) {
}
// Sign signs the message with privateKey and returns a signature. It will
-// panic if len(privateKey) is not PrivateKeySize.
+// panic if len(privateKey) is not [PrivateKeySize].
func Sign(privateKey PrivateKey, message []byte) []byte {
// Outline the function body so that the returned signature can be
// stack-allocated.
@@ -245,16 +250,18 @@ func sign(signature, privateKey, message []byte, domPrefix, context string) {
}
// Verify reports whether sig is a valid signature of message by publicKey. It
-// will panic if len(publicKey) is not PublicKeySize.
+// will panic if len(publicKey) is not [PublicKeySize].
func Verify(publicKey PublicKey, message, sig []byte) bool {
return verify(publicKey, message, sig, domPrefixPure, "")
}
// VerifyWithOptions reports whether sig is a valid signature of message by
-// publicKey. A valid signature is indicated by returning a nil error.
-// If opts.Hash is crypto.SHA512, the pre-hashed variant Ed25519ph is used
-// and message is expected to be a SHA-512 hash, otherwise opts.Hash must
-// be crypto.Hash(0) and the message must not be hashed, as Ed25519 performs two
+// publicKey. A valid signature is indicated by returning a nil error. It will
+// panic if len(publicKey) is not [PublicKeySize].
+//
+// If opts.Hash is [crypto.SHA512], the pre-hashed variant Ed25519ph is used and
+// message is expected to be a SHA-512 hash, otherwise opts.Hash must be
+// [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
// passes over messages to be signed.
func VerifyWithOptions(publicKey PublicKey, message, sig []byte, opts *Options) error {
switch {
diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go
index ae5c872e02..47c8698e2a 100644
--- a/src/crypto/ed25519/ed25519_test.go
+++ b/src/crypto/ed25519/ed25519_test.go
@@ -14,11 +14,34 @@ import (
"crypto/sha512"
"encoding/hex"
"internal/testenv"
+ "log"
"os"
"strings"
"testing"
)
+func Example_ed25519ctx() {
+ pub, priv, err := GenerateKey(nil)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ msg := []byte("The quick brown fox jumps over the lazy dog")
+
+ sig, err := priv.Sign(nil, msg, &Options{
+ Context: "Example_ed25519ctx",
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ if err := VerifyWithOptions(pub, msg, sig, &Options{
+ Context: "Example_ed25519ctx",
+ }); err != nil {
+ log.Fatal("invalid signature")
+ }
+}
+
type zeroReader struct{}
func (zeroReader) Read(buf []byte) (int, error) {
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index c72010c1e3..36229bba4f 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -815,8 +815,10 @@ func (c *Certificate) hasSANExtension() bool {
return oidInExtensions(oidExtensionSubjectAltName, c.Extensions)
}
-// CheckSignatureFrom verifies that the signature on c is a valid signature
-// from parent. SHA1WithRSA and ECDSAWithSHA1 signatures are not supported.
+// CheckSignatureFrom verifies that the signature on c is a valid signature from parent.
+//
+// This is a low-level API that performs very limited checks, and not a full
+// path verifier. Most users should use [Certificate.Verify] instead.
func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
// RFC 5280, 4.2.1.9:
// "If the basic constraints extension is not present in a version 3
@@ -836,13 +838,16 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
return ErrUnsupportedAlgorithm
}
- // TODO(agl): don't ignore the path length constraint.
-
return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false)
}
// CheckSignature verifies that signature is a valid signature over signed from
// c's public key.
+//
+// This is a low-level API that performs no validity checks on the certificate.
+//
+// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]
+// signatures are currently accepted.
func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
return checkSignature(algo, signed, signature, c.PublicKey, true)
}
diff --git a/src/os/file.go b/src/os/file.go
index 6781b54da0..3d71ac068e 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -338,6 +338,7 @@ var lstat = Lstat
// Rename renames (moves) oldpath to newpath.
// If newpath already exists and is not a directory, Rename replaces it.
// OS-specific restrictions may apply when oldpath and newpath are in different directories.
+// Even within the same directory, on non-Unix platforms Rename is not an atomic operation.
// If there is an error, it will be of type *LinkError.
func Rename(oldpath, newpath string) error {
return rename(oldpath, newpath)
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index 6a162eff0a..61ff17a934 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -339,8 +339,11 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
// the caller doesn't save LR on stack but passes it as a
// register (R5), and the unwinder currently doesn't understand.
// Make it SPWRITE to stop unwinding. (See issue 54332)
- MOVD R1, R1
+ // Use OR R0, R1 instead of MOVD R1, R1 as the MOVD instruction
+ // has a special affect on Power8,9,10 by lowering the thread
+ // priority and causing a slowdown in execution time
+ OR R0, R1
MOVD R0, R11
BR runtime·morestack(SB)
diff --git a/src/strings/clone_test.go b/src/strings/clone_test.go
index 77479cfacf..64f2760ee3 100644
--- a/src/strings/clone_test.go
+++ b/src/strings/clone_test.go
@@ -1,6 +1,6 @@
// 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.ß
+// license that can be found in the LICENSE file.
package strings_test
diff --git a/test/fixedbugs/issue57846.go b/test/fixedbugs/issue57846.go
new file mode 100644
index 0000000000..1aea97564e
--- /dev/null
+++ b/test/fixedbugs/issue57846.go
@@ -0,0 +1,33 @@
+// compile
+
+// Copyright 2023 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
+
+func Float64D3(list [][][]float64, value float64) int {
+ valueCount := 0
+ for _, listValue := range list {
+ valueCount += Float64D2(listValue, value)
+ }
+ return valueCount
+}
+
+func Float64(list []float64, value float64) int {
+ valueCount := 0
+ for _, listValue := range list {
+ if listValue == value {
+ valueCount++
+ }
+ }
+ return valueCount
+}
+
+func Float64D2(list [][]float64, value float64) int {
+ valueCount := 0
+ for _, listValue := range list {
+ valueCount += Float64(listValue, value)
+ }
+ return valueCount
+}