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.

Runtime

-

- 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 GOEXPERIMENT=arenas, - which will make the arena package visible to your program. - Source files that import the arena package must require the - goexperiment.arenas build tag. -

-

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.

- 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.

Linker

@@ -398,13 +389,13 @@ Do not send CLs removing the interior tags from such phrases.

Go 1.20 adds a new crypto/ecdh 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.

- Programs should prefer to use crypto/ecdh - or crypto/ecdsa - instead of the lower-level functionality in crypto/elliptic. + Programs should use crypto/ecdh instead of the lower-level functionality in + crypto/elliptic for ECDH, and + third-party modules for more advanced use cases.

Wrapping multiple errors

@@ -592,6 +583,11 @@ proxyHandler := &httputil.ReverseProxy{
crypto/ecdsa
+

+ 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. +

+

The new PrivateKey.ECDH method converts an ecdsa.PrivateKey to an ecdh.PrivateKey. @@ -618,25 +614,21 @@ proxyHandler := &httputil.ReverseProxy{

-
crypto/elliptic
-
-

- Use of custom Curve implementations - not provided by this package (that is, curves other than - P224, - P256, - P384, and - P521) - is deprecated. -

-
-
-
crypto/rsa

The new field OAEPOptions.MGFHash - allows configuring the MGF1 hash separately for OAEP encryption. + allows configuring the MGF1 hash separately for OAEP decryption. +

+ +

+ 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 + PrecomputedValues.

@@ -652,9 +644,9 @@ proxyHandler := &httputil.ReverseProxy{
crypto/tls
-

- 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 +

+ 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.

@@ -669,22 +661,22 @@ proxyHandler := &httputil.ReverseProxy{
crypto/x509
-

- CreateCertificateRequest +

+ ParsePKCS8PrivateKey and MarshalPKCS8PrivateKey now support keys of type *crypto/ecdh.PrivateKey. - CreateCertificate + ParsePKIXPublicKey and MarshalPKIXPublicKey now support keys of type *crypto/ecdh.PublicKey. - X.509 unmarshaling continues to unmarshal elliptic curve keys into + Parsing NIST curve keys still returns values of type *ecdsa.PublicKey and *ecdsa.PrivateKey. - Use their new ECDH methods to convert to the crypto/ecdh form. + Use their new ECDH methods to convert to the crypto/ecdh types.

The new SetFallbackRoots - 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, golang.org/x/crypto/x509roots/fallback, which will provide an up to date root bundle. @@ -841,6 +833,20 @@ proxyHandler := &httputil.ReverseProxy{

+
math/big
+
+

+ The math/big 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 + Int 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. +

+
+
+
math/rand

@@ -1238,3 +1244,4 @@ proxyHandler := &httputil.ReverseProxy{ + 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 +}