diff options
author | Michael Pratt <mpratt@google.com> | 2023-06-15 11:36:34 -0400 |
---|---|---|
committer | Michael Pratt <mpratt@google.com> | 2023-06-15 11:36:34 -0400 |
commit | b4a066526618371e48c68fcf6744aa0899949327 (patch) | |
tree | d6e824d21a0139bd74579e109f8b8ebd7646b50b | |
parent | 577e7b9bb957618002b5015a0017cbb7425fe54f (diff) | |
parent | b7e74678657680a0eb31679623f90b539666c5f4 (diff) | |
download | go-b4a066526618371e48c68fcf6744aa0899949327.tar.gz go-b4a066526618371e48c68fcf6744aa0899949327.zip |
[release-branch.go1.21] all: merge master (b7e7467) into release-branch.go1.21
Merge List:
+ 2023-06-15 b7e7467865 test/codegen: add fsqrt test for riscv64
+ 2023-06-15 befec5ddbb text/template: set variables correctly in range assignment
+ 2023-06-15 c5463218a2 cmd/api: skip TestIssue29837 when -short is set
+ 2023-06-15 9fc84363d1 cmd/asm: fix encoding errors for FMOVD and FMOVS instructions on arm64
+ 2023-06-14 da94586aa3 cmd/go: check for errors reading gccgo package list
+ 2023-06-14 b01cd41b46 cmd/go: use gover.Local for $goversion in TestScript
+ 2023-06-14 3aea422e2c crypto/x509: use synthetic root for platform testing
Change-Id: Icec55130749c52eef75c0e0325d889ff18b067f6
-rw-r--r-- | src/cmd/api/api_test.go | 30 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/arm64.s | 2 | ||||
-rw-r--r-- | src/cmd/go/internal/work/action.go | 25 | ||||
-rw-r--r-- | src/cmd/go/script_test.go | 20 | ||||
-rw-r--r-- | src/cmd/internal/obj/arm64/asm7.go | 2 | ||||
-rw-r--r-- | src/crypto/x509/platform_root_cert.pem | 13 | ||||
-rw-r--r-- | src/crypto/x509/platform_root_key.pem | 5 | ||||
-rw-r--r-- | src/crypto/x509/platform_test.go | 251 | ||||
-rw-r--r-- | src/text/template/exec.go | 16 | ||||
-rw-r--r-- | src/text/template/exec_test.go | 1 | ||||
-rw-r--r-- | test/codegen/math.go | 2 |
11 files changed, 325 insertions, 42 deletions
diff --git a/src/cmd/api/api_test.go b/src/cmd/api/api_test.go index 53ae6fd2c8..a5ac49ce2d 100644 --- a/src/cmd/api/api_test.go +++ b/src/cmd/api/api_test.go @@ -209,16 +209,7 @@ func BenchmarkAll(b *testing.B) { } } -func TestIssue21181(t *testing.T) { - if testing.Short() { - t.Skip("skipping with -short") - } - if *flagCheck { - // slow, not worth repeating in -check - t.Skip("skipping with -check set") - } - testenv.MustHaveGoBuild(t) - +var warmupCache = sync.OnceFunc(func() { // Warm up the import cache in parallel. var wg sync.WaitGroup for _, context := range contexts { @@ -230,6 +221,19 @@ func TestIssue21181(t *testing.T) { }() } wg.Wait() +}) + +func TestIssue21181(t *testing.T) { + if testing.Short() { + t.Skip("skipping with -short") + } + if *flagCheck { + // slow, not worth repeating in -check + t.Skip("skipping with -check set") + } + testenv.MustHaveGoBuild(t) + + warmupCache() for _, context := range contexts { w := NewWalker(context, "testdata/src/issue21181") @@ -243,11 +247,17 @@ func TestIssue21181(t *testing.T) { } func TestIssue29837(t *testing.T) { + if testing.Short() { + t.Skip("skipping with -short") + } if *flagCheck { // slow, not worth repeating in -check t.Skip("skipping with -check set") } testenv.MustHaveGoBuild(t) + + warmupCache() + for _, context := range contexts { w := NewWalker(context, "testdata/src/issue29837") _, err := w.ImportFrom("p", "", 0) diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 534a0b3e41..11bd678552 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -238,6 +238,8 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 FMOVS $0, F0 // e003271e FMOVD ZR, F0 // e003679e FMOVS ZR, F0 // e003271e + FMOVD F1, ZR // 3f00669e + FMOVS F1, ZR // 3f00261e VUADDW V9.B8, V12.H8, V14.H8 // 8e11292e VUADDW V13.H4, V10.S4, V11.S4 // 4b116d2e VUADDW V21.S2, V24.D2, V29.D2 // 1d13b52e diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go index 0fc85da006..d4d0a71e75 100644 --- a/src/cmd/go/internal/work/action.go +++ b/src/cmd/go/internal/work/action.go @@ -382,16 +382,23 @@ func (b *Builder) NewObjdir() string { func readpkglist(shlibpath string) (pkgs []*load.Package) { var stk load.ImportStack if cfg.BuildToolchainName == "gccgo" { - f, _ := elf.Open(shlibpath) + f, err := elf.Open(shlibpath) + if err != nil { + base.Fatal(fmt.Errorf("failed to open shared library: %v", err)) + } sect := f.Section(".go_export") - data, _ := sect.Data() - scanner := bufio.NewScanner(bytes.NewBuffer(data)) - for scanner.Scan() { - t := scanner.Text() - var found bool - if t, found = strings.CutPrefix(t, "pkgpath "); found { - t = strings.TrimSuffix(t, ";") - pkgs = append(pkgs, load.LoadPackageWithFlags(t, base.Cwd(), &stk, nil, 0)) + if sect == nil { + base.Fatal(fmt.Errorf("%s: missing .go_export section", shlibpath)) + } + data, err := sect.Data() + if err != nil { + base.Fatal(fmt.Errorf("%s: failed to read .go_export section: %v", shlibpath, err)) + } + pkgpath := []byte("pkgpath ") + for _, line := range bytes.Split(data, []byte{'\n'}) { + if path, found := bytes.CutPrefix(line, pkgpath); found { + path = bytes.TrimSuffix(path, []byte{';'}) + pkgs = append(pkgs, load.LoadPackageWithFlags(string(path), base.Cwd(), &stk, nil, 0)) } } } else { diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go index d0099888d9..624c5bf501 100644 --- a/src/cmd/go/script_test.go +++ b/src/cmd/go/script_test.go @@ -14,20 +14,18 @@ import ( "bytes" "context" "flag" - "fmt" - "go/build" "internal/testenv" "internal/txtar" "net/url" "os" "path/filepath" - "regexp" "runtime" "strings" "testing" "time" "cmd/go/internal/cfg" + "cmd/go/internal/gover" "cmd/go/internal/script" "cmd/go/internal/script/scripttest" "cmd/go/internal/vcweb/vcstest" @@ -209,10 +207,6 @@ func scriptEnv(srv *vcstest.Server, srvCertFile string) ([]string, error) { if err != nil { return nil, err } - version, err := goVersion() - if err != nil { - return nil, err - } env := []string{ pathEnvName() + "=" + testBin + string(filepath.ListSeparator) + os.Getenv(pathEnvName()), homeEnvName() + "=/no-home", @@ -243,7 +237,7 @@ func scriptEnv(srv *vcstest.Server, srvCertFile string) ([]string, error) { "GONOSUMDB=", "GOVCS=*:all", "devnull=" + os.DevNull, - "goversion=" + version, + "goversion=" + gover.Local(), "CMDGO_TEST_RUN_MAIN=true", "HGRCPATH=", "GOTOOLCHAIN=auto", @@ -281,16 +275,6 @@ func scriptEnv(srv *vcstest.Server, srvCertFile string) ([]string, error) { return env, nil } -// goVersion returns the current Go version. -func goVersion() (string, error) { - tags := build.Default.ReleaseTags - version := tags[len(tags)-1] - if !regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`).MatchString(version) { - return "", fmt.Errorf("invalid go version %q", version) - } - return version[2:], nil -} - var extraEnvKeys = []string{ "SYSTEMROOT", // must be preserved on Windows to find DLLs; golang.org/issue/25210 "WINDIR", // must be preserved on Windows to be able to run PowerShell command; golang.org/issue/30711 diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 77c60812ac..ff8daad857 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -3880,7 +3880,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { case 29: /* op Rn, Rd */ fc := c.aclass(&p.From) tc := c.aclass(&p.To) - if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZREG || tc == C_REG) { + if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZREG || tc == C_REG || tc == C_ZREG) { // FMOV Rx, Fy or FMOV Fy, Rx o1 = FPCVTI(0, 0, 0, 0, 6) if p.As == AFMOVD { diff --git a/src/crypto/x509/platform_root_cert.pem b/src/crypto/x509/platform_root_cert.pem new file mode 100644 index 0000000000..bef31f4c4e --- /dev/null +++ b/src/crypto/x509/platform_root_cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB/DCCAaOgAwIBAgICIzEwCgYIKoZIzj0EAwIwLDEqMCgGA1UEAxMhR28gcGxh +dGZvcm0gdmVyaWZpZXIgdGVzdGluZyByb290MB4XDTIzMDUyNjE3NDQwMVoXDTI4 +MDUyNDE4NDQwMVowLDEqMCgGA1UEAxMhR28gcGxhdGZvcm0gdmVyaWZpZXIgdGVz +dGluZyByb290MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5dNQY4FY29i2g3xx +7FyH4XiZz0C0AM4uyPUsXCZNb7CsctHDLhLtzABWSfFz76j+oVhq+qKrwIHsLX+7 +f6YTQqOBtDCBsTAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUEJInRbtQR6xTUSwvtdAe9A4XHwQw +WgYDVR0eAQH/BFAwTqAaMBiCFnRlc3RpbmcuZ29sYW5nLmludmFsaWShMDAKhwgA +AAAAAAAAADAihyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAKBggq +hkjOPQQDAgNHADBEAiBgzgLyQm4rK1AuIcElH3MdRqlteq3nzZCxKOI4xHXYjQIg +BCSzaCb1+/AK+mhRubrdebFYlUdveTH98wAfKQHaw64= +-----END CERTIFICATE----- diff --git a/src/crypto/x509/platform_root_key.pem b/src/crypto/x509/platform_root_key.pem new file mode 100644 index 0000000000..c0b6eeba8b --- /dev/null +++ b/src/crypto/x509/platform_root_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIHhv8LVzb9gqJzAY0P442+FW0oqbfBrLnfqxyyAujOFSoAoGCCqGSM49 +AwEHoUQDQgAE5dNQY4FY29i2g3xx7FyH4XiZz0C0AM4uyPUsXCZNb7CsctHDLhLt +zABWSfFz76j+oVhq+qKrwIHsLX+7f6YTQg== +-----END EC PRIVATE KEY----- diff --git a/src/crypto/x509/platform_test.go b/src/crypto/x509/platform_test.go new file mode 100644 index 0000000000..c35f0b448e --- /dev/null +++ b/src/crypto/x509/platform_test.go @@ -0,0 +1,251 @@ +// 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 x509 + +//go:generate go run gen_testing_root.go + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "encoding/pem" + "math/big" + "os" + "runtime" + "strings" + "testing" + "time" +) + +// In order to run this test suite locally, you need to insert the test root, at +// the path below, into your trust store. This root is constrained such that it +// should not be dangerous to local developers to trust, but care should be +// taken when inserting it into the trust store not to give it increased +// permissions. +// +// On macOS the certificate can be further constrained to only be valid for +// 'SSL' in the certificate properties pane of the 'Keychain Access' program. +// +// On Windows the certificate can also be constrained to only server +// authentication in the properties pane of the certificate in the +// "Certificates" snap-in of mmc.exe. + +const ( + rootCertPath = "platform_root_cert.pem" + rootKeyPath = "platform_root_key.pem" +) + +func TestPlatformVerifier(t *testing.T) { + if runtime.GOOS != "windows" && runtime.GOOS != "darwin" { + t.Skip("only tested on windows and darwin") + } + + der, err := os.ReadFile(rootCertPath) + if err != nil { + t.Fatalf("failed to read test root: %s", err) + } + b, _ := pem.Decode(der) + testRoot, err := ParseCertificate(b.Bytes) + if err != nil { + t.Fatalf("failed to parse test root: %s", err) + } + + der, err = os.ReadFile(rootKeyPath) + if err != nil { + t.Fatalf("failed to read test key: %s", err) + } + b, _ = pem.Decode(der) + testRootKey, err := ParseECPrivateKey(b.Bytes) + if err != nil { + t.Fatalf("failed to parse test key: %s", err) + } + + if _, err := testRoot.Verify(VerifyOptions{}); err != nil { + t.Skipf("test root is not in trust store, skipping (err: %q)", err) + } + + now := time.Now() + + tests := []struct { + name string + cert *Certificate + selfSigned bool + dnsName string + time time.Time + eku []ExtKeyUsage + + expectedErr string + windowsErr string + macosErr string + }{ + { + name: "valid", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + }, + { + name: "valid (with name)", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + dnsName: "valid.testing.golang.invalid", + }, + { + name: "valid (with time)", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + time: now.Add(time.Minute * 30), + }, + { + name: "valid (with eku)", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + eku: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + { + name: "wrong name", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + dnsName: "invalid.testing.golang.invalid", + expectedErr: "x509: certificate is valid for valid.testing.golang.invalid, not invalid.testing.golang.invalid", + }, + { + name: "expired (future)", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + time: now.Add(time.Hour * 2), + expectedErr: "x509: certificate has expired or is not yet valid", + }, + { + name: "expired (past)", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + time: now.Add(time.Hour * 2), + expectedErr: "x509: certificate has expired or is not yet valid", + }, + { + name: "self-signed", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + selfSigned: true, + macosErr: "x509: “valid.testing.golang.invalid” certificate is not trusted", + windowsErr: "x509: certificate signed by unknown authority", + }, + { + name: "non-specified KU", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + eku: []ExtKeyUsage{ExtKeyUsageEmailProtection}, + expectedErr: "x509: certificate specifies an incompatible key usage", + }, + { + name: "non-nested KU", + cert: &Certificate{ + SerialNumber: big.NewInt(1), + DNSNames: []string{"valid.testing.golang.invalid"}, + NotBefore: now.Add(-time.Hour), + NotAfter: now.Add(time.Hour), + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageEmailProtection}, + }, + macosErr: "x509: “valid.testing.golang.invalid” certificate is not permitted for this usage", + windowsErr: "x509: certificate specifies an incompatible key usage", + }, + } + + leafKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatalf("ecdsa.GenerateKey failed: %s", err) + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + parent := testRoot + if tc.selfSigned { + parent = tc.cert + } + certDER, err := CreateCertificate(rand.Reader, tc.cert, parent, leafKey.Public(), testRootKey) + if err != nil { + t.Fatalf("CreateCertificate failed: %s", err) + } + cert, err := ParseCertificate(certDER) + if err != nil { + t.Fatalf("ParseCertificate failed: %s", err) + } + + var opts VerifyOptions + if tc.dnsName != "" { + opts.DNSName = tc.dnsName + } + if !tc.time.IsZero() { + opts.CurrentTime = tc.time + } + if len(tc.eku) > 0 { + opts.KeyUsages = tc.eku + } + + expectedErr := tc.expectedErr + if runtime.GOOS == "darwin" && tc.macosErr != "" { + expectedErr = tc.macosErr + } else if runtime.GOOS == "windows" && tc.windowsErr != "" { + expectedErr = tc.windowsErr + } + + _, err = cert.Verify(opts) + if err != nil && expectedErr == "" { + t.Errorf("unexpected verification error: %s", err) + } else if err != nil && !strings.HasPrefix(err.Error(), expectedErr) { + t.Errorf("unexpected verification error: got %q, want %q", err.Error(), expectedErr) + } else if err == nil && expectedErr != "" { + t.Errorf("unexpected verification success: want %q", expectedErr) + } + }) + } +} diff --git a/src/text/template/exec.go b/src/text/template/exec.go index fb60c17931..fd7db657d3 100644 --- a/src/text/template/exec.go +++ b/src/text/template/exec.go @@ -361,19 +361,27 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { // mark top of stack before any variables in the body are pushed. mark := s.mark() oneIteration := func(index, elem reflect.Value) { - // Set top var (lexically the second if there are two) to the element. if len(r.Pipe.Decl) > 0 { if r.Pipe.IsAssign { - s.setVar(r.Pipe.Decl[0].Ident[0], elem) + // With two variables, index comes first. + // With one, we use the element. + if len(r.Pipe.Decl) > 1 { + s.setVar(r.Pipe.Decl[0].Ident[0], index) + } else { + s.setVar(r.Pipe.Decl[0].Ident[0], elem) + } } else { + // Set top var (lexically the second if there + // are two) to the element. s.setTopVar(1, elem) } } - // Set next var (lexically the first if there are two) to the index. if len(r.Pipe.Decl) > 1 { if r.Pipe.IsAssign { - s.setVar(r.Pipe.Decl[1].Ident[0], index) + s.setVar(r.Pipe.Decl[1].Ident[0], elem) } else { + // Set next var (lexically the first if there + // are two) to the index. s.setTopVar(2, index) } } diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index 40e3c5e0b4..6eb0d41a51 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -694,6 +694,7 @@ var execTests = []execTest{ {"bug18c", "{{eq . 'P'}}", "true", 'P', true}, {"issue56490", "{{$i := 0}}{{$x := 0}}{{range $i = .AI}}{{end}}{{$i}}", "5", tVal, true}, + {"issue60801", "{{$k := 0}}{{$v := 0}}{{range $k, $v = .AI}}{{$k}}={{$v}} {{end}}", "0=3 1=4 2=5 ", tVal, true}, } func zeroArgs() string { diff --git a/test/codegen/math.go b/test/codegen/math.go index e630530965..6a7d304afd 100644 --- a/test/codegen/math.go +++ b/test/codegen/math.go @@ -57,6 +57,7 @@ func sqrt(x float64) float64 { // mips64/hardfloat:"SQRTD" mips64/softfloat:-"SQRTD" // wasm:"F64Sqrt" // ppc64x:"FSQRT" + // riscv64: "FSQRTD" return math.Sqrt(x) } @@ -69,6 +70,7 @@ func sqrt32(x float32) float32 { // mips64/hardfloat:"SQRTF" mips64/softfloat:-"SQRTF" // wasm:"F32Sqrt" // ppc64x:"FSQRTS" + // riscv64: "FSQRTS" return float32(math.Sqrt(float64(x))) } |