[dev.simd] all: merge master (88cf0c5) into dev.simd

Merge List:

+ 2025-07-11 88cf0c5d55 cmd/link: do size fixups after symbol references are loaded
+ 2025-07-10 7a38975a48 os: trivial comment fix
+ 2025-07-10 aa5de9ebb5 synctest: fix comments for time.Now() in synctests
+ 2025-07-10 63ec70d4e1 crypto/cipher: Fix comment punctuation
+ 2025-07-09 8131635e5a runtime: run TestSignalDuringExec in its own process group
+ 2025-07-09 67c1704444 crypto/tls: empty server_name conf. ext. from server
+ 2025-07-08 54c9d77630 cmd/go: disable support for multiple vcs in one module
+ 2025-07-08 fca43a8436 internal: make struct comment match struct name
+ 2025-07-08 bb917bb030 cmd/compile: document that nosplit directive is unsafe
+ 2025-07-08 a5bda585d5 cmd/compile: run fmt on ssa
+ 2025-07-07 86b5ba7310 internal/trace: only test for sync preemption if async preemption is off
+ 2025-07-07 ef46e1b164 cmd/internal/doc: fix GOROOT skew and path joining bugs
+ 2025-07-07 75b43f9a97 runtime: make traceStack testable and add a benchmark
+ 2025-07-07 20978f46fd crypto/rsa: remove another forgotten note to future self
+ 2025-07-07 33fb4819f5 cmd/compile/internal/ssa: skip EndSequence entries in TestStmtLines
+ 2025-07-07 a995269a93 sort: clarify Less doc
+ 2025-07-03 6c3b5a2798 runtime: correct vdsoSP on S390X
+ 2025-07-03 dd687c3860 hash: document that Clone may only return ErrUnsupported or a nil error
+ 2025-07-02 b325151453 cmd/cgo/internal/testsanitizers: skip asan tests when FIPS140 mode is on
+ 2025-07-02 15d9fe43d6 testing/synctest: explicitly state Run will be removed in Go 1.26
+ 2025-07-01 de646d94f7 cmd/go/internal/modindex: apply changes in CL 502615 to modindex package
+ 2025-07-01 2f653a5a9e crypto/tls: ensure the ECDSA curve matches the signature algorithm
+ 2025-07-01 6e95fd96cc crypto/ecdsa: fix crypto/x509 godoc links
+ 2025-07-01 7755a05209 Revert "crypto/internal/fips140/subtle: add assembly implementation of xorBytes for arm"
+ 2025-07-01 d168ad18e1 slices: update TestIssue68488 to avoid false positives
+ 2025-07-01 27ad1f5013 internal/abi: fix comment on NonEmptyInterface
+ 2025-06-30 86fca3dcb6 encoding/json/jsontext: use bytes.Buffer.AvailableBuffer
+ 2025-06-30 6bd9944c9a encoding/json/v2: avoid escaping jsonopts.Struct
+ 2025-06-30 e46d586edd cmd/compile/internal/escape: add debug hash for literal allocation optimizations
+ 2025-06-30 479b51ee1f cmd/compile/internal/escape: stop disabling literal allocation optimizations when coverage is enabled
+ 2025-06-30 8002d283e8 crypto/tls: update bogo version
+ 2025-06-30 fdd7713fe5 internal/goexperiment: fix godoc formatting

Change-Id: I074e6c75778890930975925c016004aabca2b9d1
This commit is contained in:
Cherry Mui 2025-07-11 11:41:23 -04:00
commit 21596f2f75
63 changed files with 672 additions and 498 deletions

View file

@ -189,6 +189,11 @@ crypto/x509.CreateCertificate. The setting `x509sha256skid=0` reverts to SHA-1.
Go 1.25 corrected the semantics of contention reports for runtime-internal locks, Go 1.25 corrected the semantics of contention reports for runtime-internal locks,
and so removed the [`runtimecontentionstacks` setting](/pkg/runtime#hdr-Environment_Variables). and so removed the [`runtimecontentionstacks` setting](/pkg/runtime#hdr-Environment_Variables).
Go 1.25 (starting with Go 1.25 RC 2) disabled build information stamping when
multiple VCS are detected due to concerns around VCS injection attacks. This
behavior and setting was backported to Go 1.24.5 and Go 1.23.11. This behavior
can be renabled with the setting `allowmultiplevcs=1`.
### Go 1.24 ### Go 1.24
Go 1.24 added a new `fips140` setting that controls whether the Go Go 1.24 added a new `fips140` setting that controls whether the Go

View file

@ -8,6 +8,7 @@ package sanitizers_test
import ( import (
"bytes" "bytes"
"crypto/fips140"
"fmt" "fmt"
"internal/platform" "internal/platform"
"internal/testenv" "internal/testenv"
@ -157,6 +158,10 @@ func mustHaveASAN(t *testing.T) *config {
t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch) t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
} }
if fips140.Enabled() {
t.Skipf("skipping with FIPS 140 mode; -asan option is not supported.")
}
// The current implementation is only compatible with the ASan library from version // The current implementation is only compatible with the ASan library from version
// v7 to v9 (See the description in src/runtime/asan/asan.go). Therefore, using the // v7 to v9 (See the description in src/runtime/asan/asan.go). Therefore, using the
// -asan option must use a compatible version of ASan library, which requires that // -asan option must use a compatible version of ASan library, which requires that

View file

@ -253,6 +253,9 @@ The //go:nosplit directive must be followed by a function declaration.
It specifies that the function must omit its usual stack overflow check. It specifies that the function must omit its usual stack overflow check.
This is most commonly used by low-level runtime code invoked This is most commonly used by low-level runtime code invoked
at times when it is unsafe for the calling goroutine to be preempted. at times when it is unsafe for the calling goroutine to be preempted.
Using this directive outside of low-level runtime code is not safe,
because it permits the nosplit function to overwrite the end of stack,
leading to memory corruption and arbitrary program failure.
# Linkname Directive # Linkname Directive

View file

@ -40,6 +40,7 @@ type DebugFlags struct {
InlFuncsWithClosures int `help:"allow functions with closures to be inlined" concurrent:"ok"` InlFuncsWithClosures int `help:"allow functions with closures to be inlined" concurrent:"ok"`
InlStaticInit int `help:"allow static initialization of inlined calls" concurrent:"ok"` InlStaticInit int `help:"allow static initialization of inlined calls" concurrent:"ok"`
Libfuzzer int `help:"enable coverage instrumentation for libfuzzer"` Libfuzzer int `help:"enable coverage instrumentation for libfuzzer"`
LiteralAllocHash string `help:"hash value for use in debugging literal allocation optimizations" concurrent:"ok"`
LoopVar int `help:"shared (0, default), 1 (private loop variables), 2, private + log"` LoopVar int `help:"shared (0, default), 1 (private loop variables), 2, private + log"`
LoopVarHash string `help:"for debugging changes in loop behavior. Overrides experiment and loopvar flag."` LoopVarHash string `help:"for debugging changes in loop behavior. Overrides experiment and loopvar flag."`
LocationLists int `help:"print information about DWARF location list creation"` LocationLists int `help:"print information about DWARF location list creation"`

View file

@ -268,6 +268,10 @@ func ParseFlags() {
if Debug.PGOHash != "" { if Debug.PGOHash != "" {
PGOHash = NewHashDebug("pgohash", Debug.PGOHash, nil) PGOHash = NewHashDebug("pgohash", Debug.PGOHash, nil)
} }
if Debug.LiteralAllocHash != "" {
LiteralAllocHash = NewHashDebug("literalalloc", Debug.LiteralAllocHash, nil)
}
if Debug.MergeLocalsHash != "" { if Debug.MergeLocalsHash != "" {
MergeLocalsHash = NewHashDebug("mergelocals", Debug.MergeLocalsHash, nil) MergeLocalsHash = NewHashDebug("mergelocals", Debug.MergeLocalsHash, nil)
} }

View file

@ -56,6 +56,7 @@ var hashDebug *HashDebug
var FmaHash *HashDebug // for debugging fused-multiply-add floating point changes var FmaHash *HashDebug // for debugging fused-multiply-add floating point changes
var LoopVarHash *HashDebug // for debugging shared/private loop variable changes var LoopVarHash *HashDebug // for debugging shared/private loop variable changes
var PGOHash *HashDebug // for debugging PGO optimization decisions var PGOHash *HashDebug // for debugging PGO optimization decisions
var LiteralAllocHash *HashDebug // for debugging literal allocation optimizations
var MergeLocalsHash *HashDebug // for debugging local stack slot merging changes var MergeLocalsHash *HashDebug // for debugging local stack slot merging changes
var VariableMakeHash *HashDebug // for debugging variable-sized make optimizations var VariableMakeHash *HashDebug // for debugging variable-sized make optimizations

View file

@ -534,10 +534,6 @@ func (b *batch) rewriteWithLiterals(n ir.Node, fn *ir.Func) {
if n.Op() != ir.OMAKESLICE && n.Op() != ir.OCONVIFACE { if n.Op() != ir.OMAKESLICE && n.Op() != ir.OCONVIFACE {
return return
} }
if base.Flag.Cfg.CoverageInfo != nil {
// Avoid altering coverage results.
return
}
// Look up a cached ReassignOracle for the function, lazily computing one if needed. // Look up a cached ReassignOracle for the function, lazily computing one if needed.
ro := b.reassignOracle(fn) ro := b.reassignOracle(fn)
@ -571,6 +567,10 @@ func (b *batch) rewriteWithLiterals(n ir.Node, fn *ir.Func) {
base.Fatalf("unexpected BasicLit Kind") base.Fatalf("unexpected BasicLit Kind")
} }
if constant.Compare(lit.Val(), token.GEQ, constant.MakeInt64(0)) { if constant.Compare(lit.Val(), token.GEQ, constant.MakeInt64(0)) {
if !base.LiteralAllocHash.MatchPos(n.Pos(), nil) {
// De-selected by literal alloc optimizations debug hash.
return
}
// Preserve any side effects of the original expression, then replace it. // Preserve any side effects of the original expression, then replace it.
assignTemp(*r, n.PtrInit()) assignTemp(*r, n.PtrInit())
*r = lit *r = lit
@ -584,6 +584,10 @@ func (b *batch) rewriteWithLiterals(n ir.Node, fn *ir.Func) {
if conv.X.Op() != ir.OLITERAL && !conv.X.Type().IsInterface() { if conv.X.Op() != ir.OLITERAL && !conv.X.Type().IsInterface() {
v := ro.StaticValue(conv.X) v := ro.StaticValue(conv.X)
if v != nil && v.Op() == ir.OLITERAL && ir.ValidTypeForConst(conv.X.Type(), v.Val()) { if v != nil && v.Op() == ir.OLITERAL && ir.ValidTypeForConst(conv.X.Type(), v.Val()) {
if !base.LiteralAllocHash.MatchPos(n.Pos(), nil) {
// De-selected by literal alloc optimizations debug hash.
return
}
if base.Debug.EscapeDebug >= 3 { if base.Debug.EscapeDebug >= 3 {
base.WarnfAt(n.Pos(), "rewriting OCONVIFACE value from %v (%v) to %v (%v)", conv.X, conv.X.Type(), v, v.Type()) base.WarnfAt(n.Pos(), "rewriting OCONVIFACE value from %v (%v) to %v (%v)", conv.X, conv.X.Type(), v, v.Type())
} }

View file

@ -1917,15 +1917,22 @@ func (ft *factsTable) flowLimit(v *Value) bool {
// See if we can get any facts because v is the result of signed mod by a constant. // See if we can get any facts because v is the result of signed mod by a constant.
// The mod operation has already been rewritten, so we have to try and reconstruct it. // The mod operation has already been rewritten, so we have to try and reconstruct it.
// x % d //
// x % d
//
// is rewritten as // is rewritten as
// x - (x / d) * d //
// x - (x / d) * d
//
// furthermore, the divide itself gets rewritten. If d is a power of 2 (d == 1<<k), we do // furthermore, the divide itself gets rewritten. If d is a power of 2 (d == 1<<k), we do
// (x / d) * d = ((x + adj) >> k) << k //
// = (x + adj) & (-1<<k) // (x / d) * d = ((x + adj) >> k) << k
// = (x + adj) & (-1<<k)
//
// with adj being an adjustment in case x is negative (see below). // with adj being an adjustment in case x is negative (see below).
// if d is not a power of 2, we do // if d is not a power of 2, we do
// x / d = ... TODO ... //
// x / d = ... TODO ...
func (ft *factsTable) detectSignedMod(v *Value) bool { func (ft *factsTable) detectSignedMod(v *Value) bool {
if ft.detectSignedModByPowerOfTwo(v) { if ft.detectSignedModByPowerOfTwo(v) {
return true return true

View file

@ -120,6 +120,11 @@ func TestStmtLines(t *testing.T) {
break break
} }
must(err) must(err)
if le.EndSequence {
// When EndSequence is true only
// le.Address is meaningful, skip.
continue
}
fl := Line{le.File.Name, le.Line} fl := Line{le.File.Name, le.Line}
lines[fl] = lines[fl] || le.IsStmt lines[fl] = lines[fl] || le.IsStmt
} }

View file

@ -246,14 +246,18 @@ func (o *orderState) addrTemp(n ir.Node) ir.Node {
if v == nil { if v == nil {
v = n v = n
} }
optEnabled := func(n ir.Node) bool {
// Do this optimization only when enabled for this node.
return base.LiteralAllocHash.MatchPos(n.Pos(), nil)
}
if (v.Op() == ir.OSTRUCTLIT || v.Op() == ir.OARRAYLIT) && !base.Ctxt.IsFIPS() { if (v.Op() == ir.OSTRUCTLIT || v.Op() == ir.OARRAYLIT) && !base.Ctxt.IsFIPS() {
if ir.IsZero(v) && 0 < v.Type().Size() && v.Type().Size() <= abi.ZeroValSize { if ir.IsZero(v) && 0 < v.Type().Size() && v.Type().Size() <= abi.ZeroValSize && optEnabled(n) {
// This zero value can be represented by the read-only zeroVal. // This zero value can be represented by the read-only zeroVal.
zeroVal := ir.NewLinksymExpr(v.Pos(), ir.Syms.ZeroVal, n.Type()) zeroVal := ir.NewLinksymExpr(v.Pos(), ir.Syms.ZeroVal, n.Type())
vstat := typecheck.Expr(zeroVal).(*ir.LinksymOffsetExpr) vstat := typecheck.Expr(zeroVal).(*ir.LinksymOffsetExpr)
return vstat return vstat
} }
if isStaticCompositeLiteral(v) { if isStaticCompositeLiteral(v) && optEnabled(n) {
// v can be directly represented in the read-only data section. // v can be directly represented in the read-only data section.
lit := v.(*ir.CompLitExpr) lit := v.(*ir.CompLitExpr)
vstat := readonlystaticname(n.Type()) vstat := readonlystaticname(n.Type())

View file

@ -2496,7 +2496,6 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
var repoDir string var repoDir string
var vcsCmd *vcs.Cmd var vcsCmd *vcs.Cmd
var err error var err error
const allowNesting = true
wantVCS := false wantVCS := false
switch cfg.BuildBuildvcs { switch cfg.BuildBuildvcs {
@ -2516,7 +2515,7 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
// (so the bootstrap toolchain packages don't even appear to be in GOROOT). // (so the bootstrap toolchain packages don't even appear to be in GOROOT).
goto omitVCS goto omitVCS
} }
repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting) repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "")
if err != nil && !errors.Is(err, os.ErrNotExist) { if err != nil && !errors.Is(err, os.ErrNotExist) {
setVCSError(err) setVCSError(err)
return return
@ -2539,10 +2538,11 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
} }
if repoDir != "" && vcsCmd.Status != nil { if repoDir != "" && vcsCmd.Status != nil {
// Check that the current directory, package, and module are in the same // Check that the current directory, package, and module are in the same
// repository. vcs.FromDir allows nested Git repositories, but nesting // repository. vcs.FromDir disallows nested VCS and multiple VCS in the
// is not allowed for other VCS tools. The current directory may be outside // same repository, unless the GODEBUG allowmultiplevcs is set. The
// p.Module.Dir when a workspace is used. // current directory may be outside p.Module.Dir when a workspace is
pkgRepoDir, _, err := vcs.FromDir(p.Dir, "", allowNesting) // used.
pkgRepoDir, _, err := vcs.FromDir(p.Dir, "")
if err != nil { if err != nil {
setVCSError(err) setVCSError(err)
return return
@ -2554,7 +2554,7 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
} }
goto omitVCS goto omitVCS
} }
modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "", allowNesting) modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "")
if err != nil { if err != nil {
setVCSError(err) setVCSError(err)
return return

View file

@ -235,7 +235,7 @@ func LookupLocal(ctx context.Context, codeRoot string, path string, dir string)
return lookupLocalCache.Do(path, func() Repo { return lookupLocalCache.Do(path, func() Repo {
return newCachingRepo(ctx, path, func(ctx context.Context) (Repo, error) { return newCachingRepo(ctx, path, func(ctx context.Context) (Repo, error) {
repoDir, vcsCmd, err := vcs.FromDir(dir, "", true) repoDir, vcsCmd, err := vcs.FromDir(dir, "")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -15,6 +15,7 @@ import (
"go/ast" "go/ast"
"go/build" "go/build"
"go/parser" "go/parser"
"go/scanner"
"go/token" "go/token"
"io" "io"
"strconv" "strconv"
@ -463,6 +464,13 @@ func readGoInfo(f io.Reader, info *fileInfo) error {
if err != nil { if err != nil {
return fmt.Errorf("parser returned invalid quoted string: <%s>", quoted) return fmt.Errorf("parser returned invalid quoted string: <%s>", quoted)
} }
if !isValidImport(path) {
// The parser used to return a parse error for invalid import paths, but
// no longer does, so check for and create the error here instead.
info.parseErr = scanner.Error{Pos: info.fset.Position(spec.Pos()), Msg: "invalid import path: " + path}
info.imports = nil
return nil
}
if path == "embed" { if path == "embed" {
hasEmbed = true hasEmbed = true
} }
@ -520,6 +528,20 @@ func readGoInfo(f io.Reader, info *fileInfo) error {
return nil return nil
} }
// isValidImport checks if the import is a valid import using the more strict
// checks allowed by the implementation restriction in https://go.dev/ref/spec#Import_declarations.
// It was ported from the function of the same name that was removed from the
// parser in CL 424855, when the parser stopped doing these checks.
func isValidImport(s string) bool {
const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
for _, r := range s {
if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
return false
}
}
return s != ""
}
// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns. // parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings. // It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
// This is based on a similar function in cmd/compile/internal/gc/noder.go; // This is based on a similar function in cmd/compile/internal/gc/noder.go;

View file

@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"internal/godebug"
"internal/lazyregexp" "internal/lazyregexp"
"internal/singleflight" "internal/singleflight"
"io/fs" "io/fs"
@ -869,11 +870,13 @@ type vcsPath struct {
schemelessRepo bool // if true, the repo pattern lacks a scheme schemelessRepo bool // if true, the repo pattern lacks a scheme
} }
var allowmultiplevcs = godebug.New("allowmultiplevcs")
// FromDir inspects dir and its parents to determine the // FromDir inspects dir and its parents to determine the
// version control system and code repository to use. // version control system and code repository to use.
// If no repository is found, FromDir returns an error // If no repository is found, FromDir returns an error
// equivalent to os.ErrNotExist. // equivalent to os.ErrNotExist.
func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cmd, err error) { func FromDir(dir, srcRoot string) (repoDir string, vcsCmd *Cmd, err error) {
// Clean and double-check that dir is in (a subdirectory of) srcRoot. // Clean and double-check that dir is in (a subdirectory of) srcRoot.
dir = filepath.Clean(dir) dir = filepath.Clean(dir)
if srcRoot != "" { if srcRoot != "" {
@ -887,21 +890,28 @@ func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cm
for len(dir) > len(srcRoot) { for len(dir) > len(srcRoot) {
for _, vcs := range vcsList { for _, vcs := range vcsList {
if isVCSRoot(dir, vcs.RootNames) { if isVCSRoot(dir, vcs.RootNames) {
// Record first VCS we find.
// If allowNesting is false (as it is in GOPATH), keep looking for
// repositories in parent directories and report an error if one is
// found to mitigate VCS injection attacks.
if vcsCmd == nil { if vcsCmd == nil {
// Record first VCS we find.
vcsCmd = vcs vcsCmd = vcs
repoDir = dir repoDir = dir
if allowNesting { if allowmultiplevcs.Value() == "1" {
allowmultiplevcs.IncNonDefault()
return repoDir, vcsCmd, nil return repoDir, vcsCmd, nil
} }
// If allowmultiplevcs is not set, keep looking for
// repositories in current and parent directories and report
// an error if one is found to mitigate VCS injection
// attacks.
continue continue
} }
// Otherwise, we have one VCS inside a different VCS. if vcsCmd == vcsGit && vcs == vcsGit {
return "", nil, fmt.Errorf("directory %q uses %s, but parent %q uses %s", // Nested Git is allowed, as this is how things like
repoDir, vcsCmd.Cmd, dir, vcs.Cmd) // submodules work. Git explicitly protects against
// injection against itself.
continue
}
return "", nil, fmt.Errorf("multiple VCS detected: %s in %q, and %s in %q",
vcsCmd.Cmd, repoDir, vcs.Cmd, dir)
} }
} }

View file

@ -239,7 +239,7 @@ func TestFromDir(t *testing.T) {
} }
wantRepoDir := filepath.Dir(dir) wantRepoDir := filepath.Dir(dir)
gotRepoDir, gotVCS, err := FromDir(dir, tempDir, false) gotRepoDir, gotVCS, err := FromDir(dir, tempDir)
if err != nil { if err != nil {
t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err) t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err)
continue continue

View file

@ -0,0 +1,54 @@
# To avoid VCS injection attacks, we should not accept multiple different VCS metadata
# folders within a single module (either in the same directory, or nested in different
# directories.)
#
# This behavior should be disabled by setting the allowmultiplevcs GODEBUG.
[short] skip
[!git] skip
cd samedir
exec git init .
# Without explicitly requesting buildvcs, the go command should silently continue
# without determining the correct VCS.
go test -c -o $devnull .
# If buildvcs is explicitly requested, we expect the go command to fail
! go test -buildvcs -c -o $devnull .
stderr '^error obtaining VCS status: multiple VCS detected:'
env GODEBUG=allowmultiplevcs=1
go test -buildvcs -c -o $devnull .
env GODEBUG=
cd ../nested
exec git init .
# cd a
go test -c -o $devnull ./a
! go test -buildvcs -c -o $devnull ./a
stderr '^error obtaining VCS status: multiple VCS detected:'
# allowmultiplevcs doesn't disable the check that the current directory, package, and
# module are in the same repository.
env GODEBUG=allowmultiplevcs=1
! go test -buildvcs -c -o $devnull ./a
stderr '^error obtaining VCS status: main package is in repository'
-- samedir/go.mod --
module example
go 1.18
-- samedir/example.go --
package main
-- samedir/.bzr/test --
hello
-- nested/go.mod --
module example
go 1.18
-- nested/a/example.go --
package main
-- nested/a/.bzr/test --
hello

View file

@ -9,25 +9,35 @@ cd root
go mod init example.com/root go mod init example.com/root
exec git init exec git init
# Nesting repositories in parent directories are ignored, as the current
# directory main package, and containing main module are in the same repository. # Nesting repositories in parent directories are an error, to prevent VCS injection.
# This is an error in GOPATH mode (to prevent VCS injection), but for modules, # This can be disabled with the allowmultiplevcs GODEBUG.
# we assume users have control over repositories they've checked out.
mkdir hgsub mkdir hgsub
cd hgsub cd hgsub
exec hg init exec hg init
cp ../../main.go main.go cp ../../main.go main.go
! go build ! go build
stderr '^error obtaining VCS status: multiple VCS detected: hg in ".*hgsub", and git in ".*root"$'
stderr '^\tUse -buildvcs=false to disable VCS stamping.$'
env GODEBUG=allowmultiplevcs=1
! go build
stderr '^error obtaining VCS status: main module is in repository ".*root" but current directory is in repository ".*hgsub"$' stderr '^error obtaining VCS status: main module is in repository ".*root" but current directory is in repository ".*hgsub"$'
stderr '^\tUse -buildvcs=false to disable VCS stamping.$' stderr '^\tUse -buildvcs=false to disable VCS stamping.$'
go build -buildvcs=false go build -buildvcs=false
env GODEBUG=
go mod init example.com/root/hgsub go mod init example.com/root/hgsub
! go build
stderr '^error obtaining VCS status: multiple VCS detected: hg in ".*hgsub", and git in ".*root"$'
stderr '^\tUse -buildvcs=false to disable VCS stamping.$'
env GODEBUG=allowmultiplevcs=1
go build go build
env GODEBUG=
cd .. cd ..
# It's an error to build a package from a nested Git repository if the package # It's an error to build a package from a nested Git repository if the package
# is in a separate repository from the current directory or from the module # is in a separate repository from the current directory or from the module
# root directory. # root directory. Otherwise nested Git repositories are allowed, as this is
# how Git implements submodules (and protects against Git based VCS injection.)
mkdir gitsub mkdir gitsub
cd gitsub cd gitsub
exec git init exec git init

View file

@ -15,6 +15,7 @@ import (
"io" "io"
"log" "log"
"net" "net"
"net/url"
"os" "os"
"os/exec" "os/exec"
"os/signal" "os/signal"
@ -214,7 +215,10 @@ func doPkgsite(urlPath string) error {
return fmt.Errorf("failed to find port for documentation server: %v", err) return fmt.Errorf("failed to find port for documentation server: %v", err)
} }
addr := fmt.Sprintf("localhost:%d", port) addr := fmt.Sprintf("localhost:%d", port)
path := path.Join("http://"+addr, urlPath) path, err := url.JoinPath("http://"+addr, urlPath)
if err != nil {
return fmt.Errorf("internal error: failed to construct url: %v", err)
}
// Turn off the default signal handler for SIGINT (and SIGQUIT on Unix) // Turn off the default signal handler for SIGINT (and SIGQUIT on Unix)
// and instead wait for the child process to handle the signal and // and instead wait for the child process to handle the signal and
@ -223,7 +227,7 @@ func doPkgsite(urlPath string) error {
// Prepend the local download cache to GOPROXY to get around deprecation checks. // Prepend the local download cache to GOPROXY to get around deprecation checks.
env := os.Environ() env := os.Environ()
vars, err := runCmd(nil, "go", "env", "GOPROXY", "GOMODCACHE") vars, err := runCmd(env, goCmd(), "env", "GOPROXY", "GOMODCACHE")
fields := strings.Fields(vars) fields := strings.Fields(vars)
if err == nil && len(fields) == 2 { if err == nil && len(fields) == 2 {
goproxy, gomodcache := fields[0], fields[1] goproxy, gomodcache := fields[0], fields[1]
@ -240,7 +244,7 @@ func doPkgsite(urlPath string) error {
} }
const version = "v0.0.0-20250608123103-82c52f1754cd" const version = "v0.0.0-20250608123103-82c52f1754cd"
cmd := exec.Command("go", "run", "golang.org/x/pkgsite/cmd/internal/doc@"+version, cmd := exec.Command(goCmd(), "run", "golang.org/x/pkgsite/cmd/internal/doc@"+version,
"-gorepo", buildCtx.GOROOT, "-gorepo", buildCtx.GOROOT,
"-http", addr, "-http", addr,
"-open", path) "-open", path)

View file

@ -2298,10 +2298,6 @@ func (l *Loader) LoadSyms(arch *sys.Arch) {
st.preloadSyms(r, hashedDef) st.preloadSyms(r, hashedDef)
st.preloadSyms(r, nonPkgDef) st.preloadSyms(r, nonPkgDef)
} }
for _, sf := range l.sizeFixups {
pp := l.cloneToExternal(sf.sym)
pp.size = int64(sf.size)
}
for _, vr := range st.linknameVarRefs { for _, vr := range st.linknameVarRefs {
l.checkLinkname(vr.pkg, vr.name, vr.sym) l.checkLinkname(vr.pkg, vr.name, vr.sym)
} }
@ -2309,6 +2305,10 @@ func (l *Loader) LoadSyms(arch *sys.Arch) {
for _, r := range l.objs[goObjStart:] { for _, r := range l.objs[goObjStart:] {
loadObjRefs(l, r, arch) loadObjRefs(l, r, arch)
} }
for _, sf := range l.sizeFixups {
pp := l.cloneToExternal(sf.sym)
pp.size = int64(sf.size)
}
l.values = make([]int64, l.NSym(), l.NSym()+1000) // +1000 make some room for external symbols l.values = make([]int64, l.NSym(), l.NSym()+1000) // +1000 make some room for external symbols
l.outer = make([]Sym, l.NSym(), l.NSym()+1000) l.outer = make([]Sym, l.NSym(), l.NSym()+1000)
} }

View file

@ -86,7 +86,7 @@ func NewCFBDecrypter(block Block, iv []byte) Stream {
func newCFB(block Block, iv []byte, decrypt bool) Stream { func newCFB(block Block, iv []byte, decrypt bool) Stream {
blockSize := block.BlockSize() blockSize := block.BlockSize()
if len(iv) != blockSize { if len(iv) != blockSize {
// stack trace will indicate whether it was de or encryption // Stack trace will indicate whether it was de- or en-cryption.
panic("cipher.newCFB: IV length must equal block size") panic("cipher.newCFB: IV length must equal block size")
} }
x := &cfb{ x := &cfb{

View file

@ -48,9 +48,9 @@ type PublicKey struct {
// invalidate internal optimizations; moreover, [big.Int] methods are not // invalidate internal optimizations; moreover, [big.Int] methods are not
// suitable for operating on cryptographic values. To encode and decode // suitable for operating on cryptographic values. To encode and decode
// PublicKey values, use [PublicKey.Bytes] and [ParseUncompressedPublicKey] // PublicKey values, use [PublicKey.Bytes] and [ParseUncompressedPublicKey]
// or [x509.MarshalPKIXPublicKey] and [x509.ParsePKIXPublicKey]. For ECDH, // or [crypto/x509.MarshalPKIXPublicKey] and [crypto/x509.ParsePKIXPublicKey].
// use [crypto/ecdh]. For lower-level elliptic curve operations, use a // For ECDH, use [crypto/ecdh]. For lower-level elliptic curve operations,
// third-party module like filippo.io/nistec. // use a third-party module like filippo.io/nistec.
// //
// These fields will be deprecated in Go 1.26. // These fields will be deprecated in Go 1.26.
X, Y *big.Int X, Y *big.Int
@ -104,7 +104,7 @@ func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
// instead of an [ecdh.PublicKey]. // instead of an [ecdh.PublicKey].
// //
// Note that public keys are more commonly encoded in DER (or PEM) format, which // Note that public keys are more commonly encoded in DER (or PEM) format, which
// can be parsed with [x509.ParsePKIXPublicKey] (and [encoding/pem]). // can be parsed with [crypto/x509.ParsePKIXPublicKey] (and [encoding/pem]).
func ParseUncompressedPublicKey(curve elliptic.Curve, data []byte) (*PublicKey, error) { func ParseUncompressedPublicKey(curve elliptic.Curve, data []byte) (*PublicKey, error) {
if len(data) < 1 || data[0] != 4 { if len(data) < 1 || data[0] != 4 {
return nil, errors.New("ecdsa: invalid uncompressed public key") return nil, errors.New("ecdsa: invalid uncompressed public key")
@ -141,7 +141,7 @@ func parseUncompressedPublicKey[P ecdsa.Point[P]](c *ecdsa.Curve[P], curve ellip
// Bytes returns the same format as [ecdh.PublicKey.Bytes] does for NIST curves. // Bytes returns the same format as [ecdh.PublicKey.Bytes] does for NIST curves.
// //
// Note that public keys are more commonly encoded in DER (or PEM) format, which // Note that public keys are more commonly encoded in DER (or PEM) format, which
// can be generated with [x509.MarshalPKIXPublicKey] (and [encoding/pem]). // can be generated with [crypto/x509.MarshalPKIXPublicKey] (and [encoding/pem]).
func (pub *PublicKey) Bytes() ([]byte, error) { func (pub *PublicKey) Bytes() ([]byte, error) {
switch pub.Curve { switch pub.Curve {
case elliptic.P224(): case elliptic.P224():
@ -174,8 +174,8 @@ type PrivateKey struct {
// Modifying the raw value can produce invalid keys, and may // Modifying the raw value can produce invalid keys, and may
// invalidate internal optimizations; moreover, [big.Int] methods are not // invalidate internal optimizations; moreover, [big.Int] methods are not
// suitable for operating on cryptographic values. To encode and decode // suitable for operating on cryptographic values. To encode and decode
// PrivateKey values, use [PrivateKey.Bytes] and [ParseRawPrivateKey] // PrivateKey values, use [PrivateKey.Bytes] and [ParseRawPrivateKey] or
// or [x509.MarshalPKCS8PrivateKey] and [x509.ParsePKCS8PrivateKey]. // [crypto/x509.MarshalPKCS8PrivateKey] and [crypto/x509.ParsePKCS8PrivateKey].
// For ECDH, use [crypto/ecdh]. // For ECDH, use [crypto/ecdh].
// //
// This field will be deprecated in Go 1.26. // This field will be deprecated in Go 1.26.
@ -244,8 +244,8 @@ func bigIntEqual(a, b *big.Int) bool {
// for NIST curves, but returns a [PrivateKey] instead of an [ecdh.PrivateKey]. // for NIST curves, but returns a [PrivateKey] instead of an [ecdh.PrivateKey].
// //
// Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format, // Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format,
// which can be parsed with [x509.ParseECPrivateKey] or // which can be parsed with [crypto/x509.ParseECPrivateKey] or
// [x509.ParsePKCS8PrivateKey] (and [encoding/pem]). // [crypto/x509.ParsePKCS8PrivateKey] (and [encoding/pem]).
func ParseRawPrivateKey(curve elliptic.Curve, data []byte) (*PrivateKey, error) { func ParseRawPrivateKey(curve elliptic.Curve, data []byte) (*PrivateKey, error) {
switch curve { switch curve {
case elliptic.P224(): case elliptic.P224():
@ -283,8 +283,8 @@ func parseRawPrivateKey[P ecdsa.Point[P]](c *ecdsa.Curve[P], newPoint func() P,
// Bytes returns the same format as [ecdh.PrivateKey.Bytes] does for NIST curves. // Bytes returns the same format as [ecdh.PrivateKey.Bytes] does for NIST curves.
// //
// Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format, // Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format,
// which can be generated with [x509.MarshalECPrivateKey] or // which can be generated with [crypto/x509.MarshalECPrivateKey] or
// [x509.MarshalPKCS8PrivateKey] (and [encoding/pem]). // [crypto/x509.MarshalPKCS8PrivateKey] (and [encoding/pem]).
func (priv *PrivateKey) Bytes() ([]byte, error) { func (priv *PrivateKey) Bytes() ([]byte, error) {
switch priv.Curve { switch priv.Curve {
case elliptic.P224(): case elliptic.P224():

View file

@ -243,7 +243,7 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
h0 := hash.Sum(nil) h0 := hash.Sum(nil)
// 14. If H = H', output "consistent." Otherwise, output "inconsistent." // 14. If H = H', output "consistent." Otherwise, output "inconsistent."
if !bytes.Equal(h0, h) { // TODO: constant time? if !bytes.Equal(h0, h) {
return ErrVerification return ErrVerification
} }
return nil return nil

View file

@ -1,149 +0,0 @@
// Copyright 2025 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.
//go:build !purego
#include "textflag.h"
// func xorBytes(dst, a, b *byte, n int)
TEXT ·xorBytes(SB), NOSPLIT|NOFRAME, $0
MOVW dst+0(FP), R0
MOVW a+4(FP), R1
MOVW b+8(FP), R2
MOVW n+12(FP), R3
xor_32_check:
CMP $32, R3
BLT xor_16_check
xor_32_loop:
MOVW (R1), R4
MOVW 4(R1), R5
MOVW 8(R1), R6
MOVW (R2), R7
MOVW 4(R2), R8
MOVW 8(R2), R9
EOR R4, R7
EOR R5, R8
EOR R6, R9
MOVW R7, (R0)
MOVW R8, 4(R0)
MOVW R9, 8(R0)
MOVW 12(R1), R4
MOVW 16(R1), R5
MOVW 20(R1), R6
MOVW 12(R2), R7
MOVW 16(R2), R8
MOVW 20(R2), R9
EOR R4, R7
EOR R5, R8
EOR R6, R9
MOVW R7, 12(R0)
MOVW R8, 16(R0)
MOVW R9, 20(R0)
MOVW 24(R1), R4
MOVW 28(R1), R5
MOVW 24(R2), R6
MOVW 28(R2), R7
EOR R4, R6
EOR R5, R7
MOVW R6, 24(R0)
MOVW R7, 28(R0)
ADD $32, R1
ADD $32, R2
ADD $32, R0
SUB $32, R3
CMP $32, R3
BGE xor_32_loop
CMP $0, R3
BEQ end
xor_16_check:
CMP $16, R3
BLT xor_8_check
xor_16:
MOVW (R1), R4
MOVW 4(R1), R5
MOVW (R2), R6
MOVW 4(R2), R7
EOR R4, R6
EOR R5, R7
MOVW R6, (R0)
MOVW R7, 4(R0)
MOVW 8(R1), R4
MOVW 12(R1), R5
MOVW 8(R2), R6
MOVW 12(R2), R7
EOR R4, R6
EOR R5, R7
MOVW R6, 8(R0)
MOVW R7, 12(R0)
ADD $16, R1
ADD $16, R2
ADD $16, R0
SUB $16, R3
CMP $0, R3
BEQ end
xor_8_check:
CMP $8, R3
BLT xor_4_check
xor_8:
MOVW (R1), R4
MOVW 4(R1), R5
MOVW (R2), R6
MOVW 4(R2), R7
EOR R4, R6
EOR R5, R7
MOVW R6, (R0)
MOVW R7, 4(R0)
ADD $8, R0
ADD $8, R1
ADD $8, R2
SUB $8, R3
CMP $0, R3
BEQ end
xor_4_check:
CMP $4, R3
BLT xor_2_check
xor_4:
MOVW (R1), R4
MOVW (R2), R5
EOR R4, R5
MOVW R5, (R0)
ADD $4, R1
ADD $4, R2
ADD $4, R0
SUB $4, R3
CMP $0, R3
BEQ end
xor_2_check:
CMP $2, R3
BLT xor_1
xor_2:
MOVH (R1), R4
MOVH (R2), R5
EOR R4, R5
MOVH R5, (R0)
ADD $2, R1
ADD $2, R2
ADD $2, R0
SUB $2, R3
CMP $0, R3
BEQ end
xor_1:
MOVB (R1), R4
MOVB (R2), R5
EOR R4, R5
MOVB R5, (R0)
end:
RET

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // 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.
//go:build (amd64 || arm || arm64 || mips || mipsle || mips64 || mips64le || ppc64 || ppc64le || riscv64) && !purego //go:build (amd64 || arm64 || mips || mipsle || mips64 || mips64le || ppc64 || ppc64le || riscv64) && !purego
package subtle package subtle

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // 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.
//go:build (!amd64 && !arm && !arm64 && !loong64 && !mips && !mipsle && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64) || purego //go:build (!amd64 && !arm64 && !loong64 && !mips && !mipsle && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64) || purego
package subtle package subtle

View file

@ -163,73 +163,64 @@ var rsaSignatureSchemes = []struct {
{PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11}, {PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11},
} }
// signatureSchemesForCertificate returns the list of supported SignatureSchemes func signatureSchemesForPublicKey(version uint16, pub crypto.PublicKey) []SignatureScheme {
// for a given certificate, based on the public key and the protocol version, switch pub := pub.(type) {
// and optionally filtered by its explicit SupportedSignatureAlgorithms.
func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
priv, ok := cert.PrivateKey.(crypto.Signer)
if !ok {
return nil
}
var sigAlgs []SignatureScheme
switch pub := priv.Public().(type) {
case *ecdsa.PublicKey: case *ecdsa.PublicKey:
if version != VersionTLS13 { if version < VersionTLS13 {
// In TLS 1.2 and earlier, ECDSA algorithms are not // In TLS 1.2 and earlier, ECDSA algorithms are not
// constrained to a single curve. // constrained to a single curve.
sigAlgs = []SignatureScheme{ return []SignatureScheme{
ECDSAWithP256AndSHA256, ECDSAWithP256AndSHA256,
ECDSAWithP384AndSHA384, ECDSAWithP384AndSHA384,
ECDSAWithP521AndSHA512, ECDSAWithP521AndSHA512,
ECDSAWithSHA1, ECDSAWithSHA1,
} }
break
} }
switch pub.Curve { switch pub.Curve {
case elliptic.P256(): case elliptic.P256():
sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256} return []SignatureScheme{ECDSAWithP256AndSHA256}
case elliptic.P384(): case elliptic.P384():
sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384} return []SignatureScheme{ECDSAWithP384AndSHA384}
case elliptic.P521(): case elliptic.P521():
sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512} return []SignatureScheme{ECDSAWithP521AndSHA512}
default: default:
return nil return nil
} }
case *rsa.PublicKey: case *rsa.PublicKey:
size := pub.Size() size := pub.Size()
sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes)) sigAlgs := make([]SignatureScheme, 0, len(rsaSignatureSchemes))
for _, candidate := range rsaSignatureSchemes { for _, candidate := range rsaSignatureSchemes {
if size >= candidate.minModulusBytes { if size >= candidate.minModulusBytes {
sigAlgs = append(sigAlgs, candidate.scheme) sigAlgs = append(sigAlgs, candidate.scheme)
} }
} }
return sigAlgs
case ed25519.PublicKey: case ed25519.PublicKey:
sigAlgs = []SignatureScheme{Ed25519} return []SignatureScheme{Ed25519}
default: default:
return nil return nil
} }
if cert.SupportedSignatureAlgorithms != nil {
sigAlgs = slices.DeleteFunc(sigAlgs, func(sigAlg SignatureScheme) bool {
return !isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms)
})
}
// Filter out any unsupported signature algorithms, for example due to
// FIPS 140-3 policy, tlssha1=0, or protocol version.
sigAlgs = slices.DeleteFunc(sigAlgs, func(sigAlg SignatureScheme) bool {
return isDisabledSignatureAlgorithm(version, sigAlg, false)
})
return sigAlgs
} }
// selectSignatureScheme picks a SignatureScheme from the peer's preference list // selectSignatureScheme picks a SignatureScheme from the peer's preference list
// that works with the selected certificate. It's only called for protocol // that works with the selected certificate. It's only called for protocol
// versions that support signature algorithms, so TLS 1.2 and 1.3. // versions that support signature algorithms, so TLS 1.2 and 1.3.
func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) { func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
supportedAlgs := signatureSchemesForCertificate(vers, c) priv, ok := c.PrivateKey.(crypto.Signer)
if !ok {
return 0, unsupportedCertificateError(c)
}
supportedAlgs := signatureSchemesForPublicKey(vers, priv.Public())
if c.SupportedSignatureAlgorithms != nil {
supportedAlgs = slices.DeleteFunc(supportedAlgs, func(sigAlg SignatureScheme) bool {
return !isSupportedSignatureAlgorithm(sigAlg, c.SupportedSignatureAlgorithms)
})
}
// Filter out any unsupported signature algorithms, for example due to
// FIPS 140-3 policy, tlssha1=0, or protocol version.
supportedAlgs = slices.DeleteFunc(supportedAlgs, func(sigAlg SignatureScheme) bool {
return isDisabledSignatureAlgorithm(vers, sigAlg, false)
})
if len(supportedAlgs) == 0 { if len(supportedAlgs) == 0 {
return 0, unsupportedCertificateError(c) return 0, unsupportedCertificateError(c)
} }

View file

@ -49,8 +49,6 @@
"ServerAuth-SHA1-Fallback*": "We don't support SHA-1 in TLS 1.2 (without tlssha1=1), so we fail if there are no signature_algorithms", "ServerAuth-SHA1-Fallback*": "We don't support SHA-1 in TLS 1.2 (without tlssha1=1), so we fail if there are no signature_algorithms",
"Agree-Digest-SHA256": "We select signature algorithms in peer preference order. We should consider changing this.", "Agree-Digest-SHA256": "We select signature algorithms in peer preference order. We should consider changing this.",
"ECDSACurveMismatch-Verify-TLS13": "We don't enforce the curve when verifying. This is a bug. We need to fix this.",
"*-Verify-ECDSA_P224_SHA256-TLS13": "Side effect of the bug above. BoGo sends a P-256 sigAlg with a P-224 key, and we allow it.",
"V2ClientHello-*": "We don't support SSLv2", "V2ClientHello-*": "We don't support SSLv2",
"SendV2ClientHello*": "We don't support SSLv2", "SendV2ClientHello*": "We don't support SSLv2",
@ -74,6 +72,9 @@
"BadRSAClientKeyExchange-5": "crypto/tls doesn't check the version number in the premaster secret - see processClientKeyExchange comment", "BadRSAClientKeyExchange-5": "crypto/tls doesn't check the version number in the premaster secret - see processClientKeyExchange comment",
"SupportTicketsWithSessionID": "We don't support session ID resumption", "SupportTicketsWithSessionID": "We don't support session ID resumption",
"ResumeTLS12SessionID-TLS13": "We don't support session ID resumption", "ResumeTLS12SessionID-TLS13": "We don't support session ID resumption",
"TrustAnchors-*": "We don't support draft-beck-tls-trust-anchor-ids",
"PAKE-Extension-*": "We don't support PAKE",
"*TicketFlags": "We don't support draft-ietf-tls-tlsflags",
"CheckLeafCurve": "TODO: first pass, this should be fixed", "CheckLeafCurve": "TODO: first pass, this should be fixed",
"KeyUpdate-RequestACK": "TODO: first pass, this should be fixed", "KeyUpdate-RequestACK": "TODO: first pass, this should be fixed",
@ -206,7 +207,12 @@
"EarlyData-Server-BadFinished-TLS13": "TODO: first pass, this should be fixed", "EarlyData-Server-BadFinished-TLS13": "TODO: first pass, this should be fixed",
"EarlyData-UnexpectedHandshake-Server-TLS13": "TODO: first pass, this should be fixed", "EarlyData-UnexpectedHandshake-Server-TLS13": "TODO: first pass, this should be fixed",
"EarlyData-CipherMismatch-Client-TLS13": "TODO: first pass, this should be fixed", "EarlyData-CipherMismatch-Client-TLS13": "TODO: first pass, this should be fixed",
"Resume-Server-UnofferedCipher-TLS13": "TODO: first pass, this should be fixed"
"Resume-Server-UnofferedCipher-TLS13": "TODO: first pass, this should be fixed",
"GarbageCertificate-Server-TLS13": "TODO: 2025/06 BoGo update, should be fixed",
"WrongMessageType-TLS13-ClientCertificate-TLS": "TODO: 2025/06 BoGo update, should be fixed",
"KeyUpdate-Requested": "TODO: 2025/06 BoGo update, should be fixed",
"AppDataBeforeTLS13KeyChange-*": "TODO: 2025/06 BoGo update, should be fixed"
}, },
"AllCurves": [ "AllCurves": [
23, 23,
@ -216,6 +222,6 @@
4588 4588
], ],
"ErrorMap": { "ErrorMap": {
":ECH_REJECTED:": "tls: server rejected ECH" ":ECH_REJECTED:": ["tls: server rejected ECH"]
} }
} }

View file

@ -420,6 +420,12 @@ func bogoShim() {
} }
} }
if err != io.EOF { if err != io.EOF {
// Flush the TLS conn and then perform a graceful shutdown of the
// TCP connection to avoid the runner side hitting an unexpected
// write error before it has processed the alert we may have
// generated for the error condition.
orderlyShutdown(tlsConn)
retryErr, ok := err.(*ECHRejectionError) retryErr, ok := err.(*ECHRejectionError)
if !ok { if !ok {
log.Fatal(err) log.Fatal(err)
@ -505,6 +511,31 @@ func bogoShim() {
} }
} }
// If the test case produces an error, we don't want to immediately close the
// TCP connection after generating an alert. The runner side may try to write
// additional data to the connection before it reads the alert. If the conn
// has already been torn down, then these writes will produce an unexpected
// broken pipe err and fail the test.
func orderlyShutdown(tlsConn *Conn) {
// Flush any pending alert data
tlsConn.flush()
netConn := tlsConn.NetConn()
tcpConn := netConn.(*net.TCPConn)
tcpConn.CloseWrite()
// Read and discard any data that was sent by the peer.
buf := make([]byte, maxPlaintext)
for {
n, err := tcpConn.Read(buf)
if n == 0 || err != nil {
break
}
}
tcpConn.CloseRead()
}
func TestBogoSuite(t *testing.T) { func TestBogoSuite(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("skipping in short mode") t.Skip("skipping in short mode")
@ -526,7 +557,7 @@ func TestBogoSuite(t *testing.T) {
if *bogoLocalDir != "" { if *bogoLocalDir != "" {
bogoDir = *bogoLocalDir bogoDir = *bogoLocalDir
} else { } else {
const boringsslModVer = "v0.0.0-20241120195446-5cce3fbd23e1" const boringsslModVer = "v0.0.0-20250620172916-f51d8b099832"
bogoDir = cryptotest.FetchModule(t, "boringssl.googlesource.com/boringssl.git", boringsslModVer) bogoDir = cryptotest.FetchModule(t, "boringssl.googlesource.com/boringssl.git", boringsslModVer)
} }

View file

@ -677,7 +677,8 @@ func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
// See RFC 8446, Section 4.4.3. // See RFC 8446, Section 4.4.3.
// We don't use hs.hello.supportedSignatureAlgorithms because it might // We don't use hs.hello.supportedSignatureAlgorithms because it might
// include PKCS#1 v1.5 and SHA-1 if the ClientHello also supported TLS 1.2. // include PKCS#1 v1.5 and SHA-1 if the ClientHello also supported TLS 1.2.
if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms(c.vers)) { if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms(c.vers)) ||
!isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, signatureSchemesForPublicKey(c.vers, c.peerCertificates[0].PublicKey)) {
c.sendAlert(alertIllegalParameter) c.sendAlert(alertIllegalParameter)
return errors.New("tls: certificate used with invalid signature algorithm") return errors.New("tls: certificate used with invalid signature algorithm")
} }

View file

@ -1005,6 +1005,7 @@ type encryptedExtensionsMsg struct {
quicTransportParameters []byte quicTransportParameters []byte
earlyData bool earlyData bool
echRetryConfigs []byte echRetryConfigs []byte
serverNameAck bool
} }
func (m *encryptedExtensionsMsg) marshal() ([]byte, error) { func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
@ -1040,6 +1041,10 @@ func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
b.AddBytes(m.echRetryConfigs) b.AddBytes(m.echRetryConfigs)
}) })
} }
if m.serverNameAck {
b.AddUint16(extensionServerName)
b.AddUint16(0) // empty extension_data
}
}) })
}) })
@ -1095,6 +1100,11 @@ func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
if !extData.CopyBytes(m.echRetryConfigs) { if !extData.CopyBytes(m.echRetryConfigs) {
return false return false
} }
case extensionServerName:
if len(extData) != 0 {
return false
}
m.serverNameAck = true
default: default:
// Ignore unknown extensions. // Ignore unknown extensions.
continue continue

View file

@ -594,6 +594,10 @@ func (hs *serverHandshakeState) doFullHandshake() error {
hs.hello.ocspStapling = true hs.hello.ocspStapling = true
} }
if hs.clientHello.serverName != "" {
hs.hello.serverNameAck = true
}
hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
hs.hello.cipherSuite = hs.suite.id hs.hello.cipherSuite = hs.suite.id

View file

@ -802,6 +802,10 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
encryptedExtensions.earlyData = hs.earlyData encryptedExtensions.earlyData = hs.earlyData
} }
if !hs.c.didResume && hs.clientHello.serverName != "" {
encryptedExtensions.serverNameAck = true
}
// If client sent ECH extension, but we didn't accept it, // If client sent ECH extension, but we didn't accept it,
// send retry configs, if available. // send retry configs, if available.
echKeys := hs.c.config.EncryptedClientHelloKeys echKeys := hs.c.config.EncryptedClientHelloKeys
@ -1098,7 +1102,8 @@ func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
// See RFC 8446, Section 4.4.3. // See RFC 8446, Section 4.4.3.
// We don't use certReq.supportedSignatureAlgorithms because it would // We don't use certReq.supportedSignatureAlgorithms because it would
// require keeping the certificateRequestMsgTLS13 around in the hs. // require keeping the certificateRequestMsgTLS13 around in the hs.
if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms(c.vers)) { if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms(c.vers)) ||
!isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, signatureSchemesForPublicKey(c.vers, c.peerCertificates[0].PublicKey)) {
c.sendAlert(alertIllegalParameter) c.sendAlert(alertIllegalParameter)
return errors.New("tls: client certificate used with invalid signature algorithm") return errors.New("tls: client certificate used with invalid signature algorithm")
} }

View file

@ -1,7 +1,7 @@
>>> Flow 1 (client to server) >>> Flow 1 (client to server)
00000000 16 03 01 00 81 01 00 00 7d 03 03 cc a1 7b c4 56 |........}....{.V| 00000000 16 03 01 00 81 01 00 00 7d 03 03 5b 8e 50 b3 0e |........}..[.P..|
00000010 9f 65 31 01 b0 23 09 18 10 50 7c 1e 14 7b b5 dd |.e1..#...P|..{..| 00000010 1f d7 4f a4 0f 53 de 37 1a c6 86 2f 01 c0 0b 15 |..O..S.7.../....|
00000020 d4 70 07 3e 0b 19 19 31 6b f7 4d 00 00 04 00 2f |.p.>...1k.M..../| 00000020 cf a9 f4 f5 30 c0 aa 7e cc 5b 4e 00 00 04 00 2f |....0..~.[N..../|
00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s| 00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s|
00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......| 00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......|
00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| 00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
@ -9,75 +9,75 @@
00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| 00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
00000080 04 02 05 02 06 02 |......| 00000080 04 02 05 02 06 02 |......|
>>> Flow 2 (server to client) >>> Flow 2 (server to client)
00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| 00000000 16 03 03 00 39 02 00 00 35 03 03 00 00 00 00 00 |....9...5.......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 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 00 2f 00 00 |...DOWNGRD.../..| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.| 00000030 0d ff 01 00 01 00 00 17 00 00 00 00 00 00 16 03 |................|
00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| 00000040 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| 00000050 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| 00000060 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| 00000070 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| 00000080 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| 00000090 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| 000000a0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| 000000b0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| 000000c0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| 000000d0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| 000000e0 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| 000000f0 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| 00000100 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| 00000110 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| 00000120 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| 00000130 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| 00000140 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| 00000150 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| 00000160 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| 00000170 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| 00000180 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| 00000190 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| 000001a0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| 000001b0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| 000001c0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| 000001d0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| 000001e0 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| 000001f0 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| 00000200 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| 00000210 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| 00000220 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| 00000230 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | 00000240 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| 00000250 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| 00000260 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| 00000270 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| 00000280 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| 00000290 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
000002a0 00 |.| 000002a0 04 0e 00 00 00 |.....|
>>> Flow 3 (client to server) >>> Flow 3 (client to server)
00000000 16 03 03 00 86 10 00 00 82 00 80 04 36 4c 25 96 |............6L%.| 00000000 16 03 03 00 86 10 00 00 82 00 80 25 3d 8b d1 c0 |...........%=...|
00000010 b0 1a 33 80 88 98 4f 2a c8 93 24 81 0a 78 6c 85 |..3...O*..$..xl.| 00000010 ef 86 34 20 a5 4b 4b 94 d9 c8 04 ff 02 13 24 57 |..4 .KK.......$W|
00000020 06 4d f1 cf 25 18 e0 f0 61 50 c5 45 c1 24 1b b3 |.M..%...aP.E.$..| 00000020 21 7f f1 c1 06 0b ea 1f b1 06 e8 fa 9b 5c 34 96 |!............\4.|
00000030 d6 3c d3 49 a6 40 81 2c bb ef 49 76 c0 10 4c ad |.<.I.@.,..Iv..L.| 00000030 23 2a 4b ef cb d7 47 75 05 74 f3 7f ed fb 28 6a |#*K...Gu.t....(j|
00000040 2e 7d 4d f4 0b 96 bc 1c eb 3d 1d 7d 18 25 34 14 |.}M......=.}.%4.| 00000040 cd b8 16 12 96 4b b7 cf 0c c3 b0 93 c3 ea b0 78 |.....K.........x|
00000050 ed 76 f2 a1 17 aa 87 1b ef ff 11 93 a7 44 0c 33 |.v...........D.3| 00000050 65 93 9d 6d a9 d5 b7 ed be 8b 3a f6 12 bb 5d ae |e..m......:...].|
00000060 86 27 38 3d 5d 3f bb f1 8d a9 f5 44 28 d1 28 41 |.'8=]?.....D(.(A| 00000060 2b 17 2f 62 ca 21 68 7d 12 52 e3 2c cc 32 4b 94 |+./b.!h}.R.,.2K.|
00000070 bb b7 9a fb 83 81 91 92 4e 7d 71 55 43 ed 42 12 |........N}qUC.B.| 00000070 4b 1d 73 9a 2e 60 60 da e6 32 dd d3 4d 39 69 c8 |K.s..``..2..M9i.|
00000080 86 5f de 02 13 1f c4 63 08 87 db 14 03 03 00 01 |._.....c........| 00000080 b7 9d 8a 1d d8 57 90 13 4c 2a a9 14 03 03 00 01 |.....W..L*......|
00000090 01 16 03 03 00 40 32 01 5f a2 e1 08 cf 6b ce 11 |.....@2._....k..| 00000090 01 16 03 03 00 40 c4 71 f6 06 63 08 15 02 63 0a |.....@.q..c...c.|
000000a0 db 82 94 c5 f1 12 9a ac 68 dc f9 c8 2c 00 a5 dd |........h...,...| 000000a0 59 40 55 52 28 17 3f 16 c8 48 93 af 80 87 e6 a8 |Y@UR(.?..H......|
000000b0 6b 49 c8 8b b7 9f e3 90 27 a5 c2 45 fc 75 e5 ac |kI......'..E.u..| 000000b0 37 a4 4f 20 f0 37 88 5b 55 f3 32 60 c7 c4 1d ce |7.O .7.[U.2`....|
000000c0 77 0c 80 bd 43 41 d4 00 c0 fb 8d 08 a6 f4 f7 63 |w...CA.........c| 000000c0 b2 b8 d1 2d 8b fb a6 87 39 c8 75 31 22 77 33 82 |...-....9.u1"w3.|
000000d0 07 01 09 06 e5 fc |......| 000000d0 64 0f f2 10 9d ee |d.....|
>>> Flow 4 (server to client) >>> Flow 4 (server to client)
00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
00000010 00 00 00 00 00 00 00 00 00 00 00 6d 31 fe 01 3d |...........m1..=| 00000010 00 00 00 00 00 00 00 00 00 00 00 f2 12 bf 38 31 |..............81|
00000020 2a c3 97 67 9f 08 f8 c9 ce 57 5c 4a e6 da 17 f2 |*..g.....W\J....| 00000020 ee c9 9a 6a 8d fb 1c 53 41 f1 06 3a 44 9c 31 31 |...j...SA..:D.11|
00000030 f8 47 2b d9 9d 7e af 59 b8 a9 23 9d 7e d5 ed 77 |.G+..~.Y..#.~..w| 00000030 25 7b 28 08 f5 3a 85 84 f1 83 61 9b 8c e3 cf 79 |%{(..:....a....y|
00000040 3b cd d4 b7 76 5b 6f 6d 09 bd 0c 17 03 03 00 40 |;...v[om.......@| 00000040 3a c2 ce e2 9c b8 52 ca 4f 5c b1 17 03 03 00 40 |:.....R.O\.....@|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 d2 8c 47 46 36 47 fa d8 f8 1c b4 fc f6 fd fb 4b |..GF6G.........K| 00000060 56 57 a0 ee c3 3e 4a 13 70 d5 05 2a 7d ed 49 81 |VW...>J.p..*}.I.|
00000070 79 e1 a3 39 df ac 6c 94 61 dd 20 1a e7 c0 4c 9c |y..9..l.a. ...L.| 00000070 52 37 e0 dc bd d0 e3 de f8 8e 18 a2 8b f8 62 71 |R7............bq|
00000080 45 69 69 cf 73 cb b1 6c fc 71 49 de 41 ca 4d 4f |Eii.s..l.qI.A.MO| 00000080 7f a9 35 50 91 81 6f 33 63 e3 c5 ec cf fa 1b 05 |..5P..o3c.......|
00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
000000a0 00 00 00 00 00 d1 66 64 ce 59 eb 23 13 e9 92 28 |......fd.Y.#...(| 000000a0 00 00 00 00 00 e5 05 33 38 e8 33 35 a3 f0 aa f8 |.......38.35....|
000000b0 a4 2a 7a b0 e1 79 ce 92 34 77 6e b3 8d d3 bb e6 |.*z..y..4wn.....| 000000b0 8c b7 c5 2b 8c d0 9e 40 57 c5 c9 52 61 ae 5e c7 |...+...@W..Ra.^.|
000000c0 ad 90 e8 a2 1a |.....| 000000c0 50 f1 5a 28 50 |P.Z(P|

View file

@ -1,7 +1,7 @@
>>> Flow 1 (client to server) >>> Flow 1 (client to server)
00000000 16 03 01 00 81 01 00 00 7d 03 03 02 34 82 a7 1a |........}...4...| 00000000 16 03 01 00 81 01 00 00 7d 03 03 37 94 a0 f3 65 |........}..7...e|
00000010 fe 81 b0 1c 2e df cc 04 2d f7 22 39 34 95 c7 c1 |........-."94...| 00000010 7b 07 88 ab 9f 29 dd 9a 56 a8 27 84 75 29 4f 24 |{....)..V.'.u)O$|
00000020 b2 92 a2 d2 aa ca 57 0f 9c be b4 00 00 04 00 2f |......W......../| 00000020 ce a2 ef 9b 34 ff 69 06 4c c8 e5 00 00 04 00 2f |....4.i.L....../|
00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s| 00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s|
00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......| 00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......|
00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| 00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
@ -9,75 +9,75 @@
00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| 00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
00000080 04 02 05 02 06 02 |......| 00000080 04 02 05 02 06 02 |......|
>>> Flow 2 (server to client) >>> Flow 2 (server to client)
00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| 00000000 16 03 03 00 39 02 00 00 35 03 03 00 00 00 00 00 |....9...5.......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 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 00 2f 00 00 |...DOWNGRD.../..| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.| 00000030 0d ff 01 00 01 00 00 17 00 00 00 00 00 00 16 03 |................|
00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| 00000040 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| 00000050 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| 00000060 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| 00000070 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| 00000080 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| 00000090 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| 000000a0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| 000000b0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| 000000c0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| 000000d0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| 000000e0 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| 000000f0 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| 00000100 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| 00000110 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| 00000120 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| 00000130 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| 00000140 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| 00000150 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| 00000160 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| 00000170 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| 00000180 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| 00000190 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| 000001a0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| 000001b0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| 000001c0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| 000001d0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| 000001e0 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| 000001f0 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| 00000200 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| 00000210 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| 00000220 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| 00000230 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | 00000240 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| 00000250 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| 00000260 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| 00000270 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| 00000280 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| 00000290 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
000002a0 00 |.| 000002a0 04 0e 00 00 00 |.....|
>>> Flow 3 (client to server) >>> Flow 3 (client to server)
00000000 16 03 03 00 86 10 00 00 82 00 80 d9 90 3c 11 be |.............<..| 00000000 16 03 03 00 86 10 00 00 82 00 80 1f fb a2 ec cf |................|
00000010 f3 48 de f0 8f 9e 12 ca e0 ab 86 e0 7e e7 8b ea |.H..........~...| 00000010 39 a3 cd db ee 86 8e 22 91 e1 47 5b ac 3b c0 f6 |9......"..G[.;..|
00000020 1a 76 3e 65 8d 7a d6 1c 72 2a f7 1e aa 0a 12 8f |.v>e.z..r*......| 00000020 37 0f d0 b6 19 c5 a4 4c 1a 8f 8b 67 8a 20 0e 06 |7......L...g. ..|
00000030 54 ac 33 95 9d 00 a9 a6 94 54 7b 6a d9 e3 f4 67 |T.3......T{j...g| 00000030 6a 25 d9 13 58 37 cb dc 9b 3a 0f 9d 12 02 45 3f |j%..X7...:....E?|
00000040 a6 d3 b1 c1 5d 86 51 aa 63 67 6b 6e cb 3b 5e 59 |....].Q.cgkn.;^Y| 00000040 2d 51 f5 cd 9f 45 be 5e f9 af 13 53 c2 15 a6 ca |-Q...E.^...S....|
00000050 02 c2 57 fd 37 39 1b 73 9a 61 b0 78 de e8 cc f8 |..W.79.s.a.x....| 00000050 8a cb 27 e0 d1 23 7a 19 06 26 d6 86 de 76 e7 9c |..'..#z..&...v..|
00000060 b3 01 11 e5 e9 31 85 4d fe 60 d4 12 70 71 64 45 |.....1.M.`..pqdE| 00000060 eb f8 15 1d 85 3f be 38 c4 bc 48 c3 74 d4 10 9b |.....?.8..H.t...|
00000070 e8 7d fb be 5b 82 c0 c4 e1 57 09 2c f2 d7 a3 79 |.}..[....W.,...y| 00000070 9e 97 4c 1c 56 18 9d 65 1c be 33 3c 4c 90 e0 e4 |..L.V..e..3<L...|
00000080 1c 40 08 e1 e6 cd e2 3e e7 55 da 14 03 03 00 01 |.@.....>.U......| 00000080 28 7e d3 ed 2e 88 0c df 0e 2d d9 14 03 03 00 01 |(~.......-......|
00000090 01 16 03 03 00 40 29 9e b7 cf 5e 7c e9 40 91 5f |.....@)...^|.@._| 00000090 01 16 03 03 00 40 d6 d8 b3 f2 b8 46 5f 86 69 fa |.....@.....F_.i.|
000000a0 b6 12 d4 42 ec 6a bc 03 d9 fa e4 d8 bf c7 2c c5 |...B.j........,.| 000000a0 66 1a c5 d8 d8 28 35 54 dd c9 1a b6 25 3e dc 5d |f....(5T....%>.]|
000000b0 52 74 17 77 b1 aa 13 87 f0 81 da 0d ca 7f d9 ca |Rt.w............| 000000b0 3e c1 c2 0c c5 20 eb 76 e1 14 16 95 9c 56 10 67 |>.... .v.....V.g|
000000c0 18 46 55 62 3f 90 21 60 fa 85 8c 80 6b 23 45 e7 |.FUb?.!`....k#E.| 000000c0 02 61 2f a6 af 01 b3 64 73 4a 80 53 4a 94 b3 a0 |.a/....dsJ.SJ...|
000000d0 0b 6e 8c e2 c3 f6 |.n....| 000000d0 ee b5 95 b6 6a 20 |....j |
>>> Flow 4 (server to client) >>> Flow 4 (server to client)
00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
00000010 00 00 00 00 00 00 00 00 00 00 00 ee 8d 0f cd 15 |................| 00000010 00 00 00 00 00 00 00 00 00 00 00 0e 0d f6 1c 84 |................|
00000020 db b4 cd 25 27 b6 7e 9b 82 91 2f 01 e1 4f f9 0c |...%'.~.../..O..| 00000020 d7 1a 4b 45 a1 9b e1 22 78 31 89 0c 4d f3 5b b8 |..KE..."x1..M.[.|
00000030 68 4c bf 26 2b 4b 49 f5 0a 67 8a 4f 12 35 37 75 |hL.&+KI..g.O.57u| 00000030 41 22 4f b2 aa 99 9e 5c 7c ff 2d ca db 32 01 eb |A"O....\|.-..2..|
00000040 16 fe cc 26 35 66 60 8c ed 42 40 17 03 03 00 40 |...&5f`..B@....@| 00000040 55 2a f4 66 58 4a c2 fd 9f e5 7e 17 03 03 00 40 |U*.fXJ....~....@|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 f5 7a ee 53 aa 85 bb 81 c4 57 68 12 f1 40 4c 20 |.z.S.....Wh..@L | 00000060 6c e0 c3 a0 c9 bd 12 83 58 56 e7 f4 cf 31 8f 1d |l.......XV...1..|
00000070 2a ff fc 6c dd 73 65 fc 41 e6 5b 96 6b 35 2f 8a |*..l.se.A.[.k5/.| 00000070 02 17 ce 2b 24 1c 2f 04 11 cc b2 15 38 62 d2 7d |...+$./.....8b.}|
00000080 62 49 4a da f4 df 93 a0 ab e1 12 4d 8d 34 2c 6a |bIJ........M.4,j| 00000080 1b 75 bc 20 a6 3a 65 48 2e 47 14 17 19 51 aa 71 |.u. .:eH.G...Q.q|
00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
000000a0 00 00 00 00 00 1c 08 e5 52 29 79 d6 15 07 10 44 |........R)y....D| 000000a0 00 00 00 00 00 34 81 ed 3f e0 b9 5d 01 6e d7 e8 |.....4..?..].n..|
000000b0 95 07 07 cb 3b 2b 37 2f e3 dc 17 f9 27 b6 5d 44 |....;+7/....'.]D| 000000b0 45 9f 2c 93 27 28 11 34 b4 a9 32 d5 97 9f ea 05 |E.,.'(.4..2.....|
000000c0 d0 30 4b 2e 21 |.0K.!| 000000c0 39 90 90 dc e5 |9....|

View file

@ -1,7 +1,7 @@
>>> Flow 1 (client to server) >>> Flow 1 (client to server)
00000000 16 03 01 00 81 01 00 00 7d 03 03 77 e7 c3 97 fa |........}..w....| 00000000 16 03 01 00 81 01 00 00 7d 03 03 7a 13 72 a9 8d |........}..z.r..|
00000010 59 80 de d1 f5 9f ce e5 a5 38 60 2c 30 b2 64 5b |Y........8`,0.d[| 00000010 6d 7e 8e 9c ba c1 9d 5c 09 87 9e 2f 7b e1 ba 39 |m~.....\.../{..9|
00000020 6c 0a 56 49 1d 6f 19 57 5a ac 05 00 00 04 00 2f |l.VI.o.WZ....../| 00000020 f8 ee fd 1c a7 08 61 73 b9 d7 be 00 00 04 00 2f |......as......./|
00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s| 00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s|
00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......| 00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......|
00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| 00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
@ -9,75 +9,75 @@
00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| 00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
00000080 04 02 05 02 06 02 |......| 00000080 04 02 05 02 06 02 |......|
>>> Flow 2 (server to client) >>> Flow 2 (server to client)
00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| 00000000 16 03 03 00 39 02 00 00 35 03 03 00 00 00 00 00 |....9...5.......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 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 00 2f 00 00 |...DOWNGRD.../..| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.| 00000030 0d ff 01 00 01 00 00 17 00 00 00 00 00 00 16 03 |................|
00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| 00000040 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| 00000050 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| 00000060 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| 00000070 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| 00000080 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| 00000090 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| 000000a0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| 000000b0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| 000000c0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| 000000d0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| 000000e0 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| 000000f0 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| 00000100 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| 00000110 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| 00000120 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| 00000130 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| 00000140 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| 00000150 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| 00000160 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| 00000170 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| 00000180 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| 00000190 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| 000001a0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| 000001b0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| 000001c0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| 000001d0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| 000001e0 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| 000001f0 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| 00000200 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| 00000210 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| 00000220 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| 00000230 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | 00000240 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| 00000250 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| 00000260 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| 00000270 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| 00000280 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| 00000290 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
000002a0 00 |.| 000002a0 04 0e 00 00 00 |.....|
>>> Flow 3 (client to server) >>> Flow 3 (client to server)
00000000 16 03 03 00 86 10 00 00 82 00 80 67 0c a0 f8 da |...........g....| 00000000 16 03 03 00 86 10 00 00 82 00 80 6a be 75 35 e3 |...........j.u5.|
00000010 2e d9 9e 9d ef c8 9b 77 f5 fe 25 32 74 49 1d a7 |.......w..%2tI..| 00000010 38 f9 8e b5 c3 64 bb 5f 95 95 5e 2c 6a 61 84 8d |8....d._..^,ja..|
00000020 7d 69 37 2a 94 07 5a 15 e8 f1 1d 36 25 ae 32 e4 |}i7*..Z....6%.2.| 00000020 aa 41 88 de 30 55 ba ae 38 48 e5 d9 19 fa ad 09 |.A..0U..8H......|
00000030 9c f5 35 fb 54 81 f2 19 4f 8d 6b 64 1a b2 a2 2e |..5.T...O.kd....| 00000030 94 16 93 df 08 4a a6 0b 0b 53 2a 2a 37 65 cb ed |.....J...S**7e..|
00000040 c4 cb 5b 73 9d 46 97 01 33 d3 b8 a9 18 39 2c ad |..[s.F..3....9,.| 00000040 2c 07 6b 7d 99 6e 14 1d 9b de 60 e8 25 da 0d c5 |,.k}.n....`.%...|
00000050 f2 eb 6b 02 38 44 f8 cf ae ac a6 e6 54 92 29 ae |..k.8D......T.).| 00000050 73 e5 a9 87 25 ce c7 8f 68 88 c5 68 14 ee ac 91 |s...%...h..h....|
00000060 a6 8a 4e 82 99 f3 77 8c b6 3a a1 5c 4f 25 3b 7f |..N...w..:.\O%;.| 00000060 ab 44 fe 31 e0 b5 e1 cd 9b 56 b7 0a 5a d6 b3 54 |.D.1.....V..Z..T|
00000070 39 2f cd 51 dc e3 fc 7c 5a 5a 33 e4 af 43 d0 d3 |9/.Q...|ZZ3..C..| 00000070 9c aa 30 17 ea e2 8c b5 61 89 a7 b1 96 d6 25 0f |..0.....a.....%.|
00000080 eb 3b 86 71 af 92 53 6e 02 b9 59 14 03 03 00 01 |.;.q..Sn..Y.....| 00000080 30 91 ba 95 2e a8 c0 53 ad 18 e4 14 03 03 00 01 |0......S........|
00000090 01 16 03 03 00 40 8b e4 6f d3 88 e7 6a e9 aa f2 |.....@..o...j...| 00000090 01 16 03 03 00 40 b1 5f 16 fb 6e 9d 3b 05 20 be |.....@._..n.;. .|
000000a0 4f 67 69 80 bc f1 78 ca a9 f9 29 ce 44 93 81 46 |Ogi...x...).D..F| 000000a0 19 0e 6d 74 c1 4a aa 00 db af 58 92 4a 83 f3 23 |..mt.J....X.J..#|
000000b0 0e 18 d1 2a 14 8b 3b b5 15 e4 b5 2a bb 88 d4 80 |...*..;....*....| 000000b0 e2 6c 0f f2 00 08 0f fd f4 f8 71 b3 c3 8e 8c 57 |.l........q....W|
000000c0 7b 2f 03 c7 83 7c 61 24 29 fe dd bc 49 8a b1 88 |{/...|a$)...I...| 000000c0 db 98 ff d6 7c f9 26 0b 13 8c 83 36 32 9a 5a 58 |....|.&....62.ZX|
000000d0 41 ac 8a 12 f8 d6 |A.....| 000000d0 0a 41 7d 3f 30 c0 |.A}?0.|
>>> Flow 4 (server to client) >>> Flow 4 (server to client)
00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
00000010 00 00 00 00 00 00 00 00 00 00 00 e7 d3 34 46 88 |.............4F.| 00000010 00 00 00 00 00 00 00 00 00 00 00 88 5b 28 f3 14 |............[(..|
00000020 0e 7f ae 5b d6 e5 70 d2 7d 99 25 1b 27 89 8a a4 |...[..p.}.%.'...| 00000020 18 d4 cd f1 1b b8 4b 47 50 0c 76 07 8a f9 ad 9d |......KGP.v.....|
00000030 02 03 01 a4 e1 d6 72 af c3 5a 55 f7 56 69 60 91 |......r..ZU.Vi`.| 00000030 ba 87 e7 69 cf 47 d7 79 2f 45 55 74 e8 2a 8f d3 |...i.G.y/EUt.*..|
00000040 49 29 68 36 99 e5 09 ac 7a e3 4f 17 03 03 00 40 |I)h6....z.O....@| 00000040 02 10 ee d8 80 a0 36 9a 5b 70 4d 17 03 03 00 40 |......6.[pM....@|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 71 d0 36 7d 2c 3b 40 e3 a9 3f c1 d0 5e 3a ee d2 |q.6},;@..?..^:..| 00000060 43 e0 95 80 4c ce 68 fb 8c ad a8 77 99 d7 53 7f |C...L.h....w..S.|
00000070 4d 0d b7 f4 83 3e 75 e0 ed 8a fc b2 9b ed 98 a8 |M....>u.........| 00000070 b7 bf 03 59 23 f1 b4 3c d8 db 38 f4 b5 9b f5 3f |...Y#..<..8....?|
00000080 ec 49 65 83 53 e0 79 52 03 2b 78 8a 64 3e 4c 5e |.Ie.S.yR.+x.d>L^| 00000080 12 b6 f3 2a f5 f8 66 57 0c 03 7b 00 16 01 8a 70 |...*..fW..{....p|
00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
000000a0 00 00 00 00 00 76 38 c3 3d 86 d8 58 f2 16 48 94 |.....v8.=..X..H.| 000000a0 00 00 00 00 00 3a fa 64 7c f3 25 08 c6 06 fb 02 |.....:.d|.%.....|
000000b0 46 65 ea 80 46 74 fe 66 7c 72 99 30 b3 05 08 14 |Fe..Ft.f|r.0....| 000000b0 ce a0 97 81 c9 ea 53 fc cf 39 b9 8a f7 0c df 2f |......S..9...../|
000000c0 19 e3 ee 6f cf |...o.| 000000c0 5f 56 62 78 86 |_Vbx.|

View file

@ -65,7 +65,7 @@ func (*Struct) JSONOptions(internal.NotForPublicUse) {}
// GetUnknownOption is injected by the "json" package to handle Options // GetUnknownOption is injected by the "json" package to handle Options
// declared in that package so that "jsonopts" can handle them. // declared in that package so that "jsonopts" can handle them.
var GetUnknownOption = func(*Struct, Options) (any, bool) { panic("unknown option") } var GetUnknownOption = func(Struct, Options) (any, bool) { panic("unknown option") }
func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { func GetOption[T any](opts Options, setter func(T) Options) (T, bool) {
// Collapse the options to *Struct to simplify lookup. // Collapse the options to *Struct to simplify lookup.
@ -104,14 +104,14 @@ func GetOption[T any](opts Options, setter func(T) Options) (T, bool) {
} }
return any(structOpts.DepthLimit).(T), true return any(structOpts.DepthLimit).(T), true
default: default:
v, ok := GetUnknownOption(structOpts, opt) v, ok := GetUnknownOption(*structOpts, opt)
return v.(T), ok return v.(T), ok
} }
} }
// JoinUnknownOption is injected by the "json" package to handle Options // JoinUnknownOption is injected by the "json" package to handle Options
// declared in that package so that "jsonopts" can handle them. // declared in that package so that "jsonopts" can handle them.
var JoinUnknownOption = func(*Struct, Options) { panic("unknown option") } var JoinUnknownOption = func(Struct, Options) Struct { panic("unknown option") }
func (dst *Struct) Join(srcs ...Options) { func (dst *Struct) Join(srcs ...Options) {
dst.join(false, srcs...) dst.join(false, srcs...)
@ -182,7 +182,7 @@ func (dst *Struct) join(excludeCoderOptions bool, srcs ...Options) {
} }
} }
default: default:
JoinUnknownOption(dst, src) *dst = JoinUnknownOption(*dst, src)
} }
} }
} }

View file

@ -114,7 +114,7 @@ func (e *encoderState) reset(b []byte, w io.Writer, opts ...Options) {
e.state.reset() e.state.reset()
e.encodeBuffer = encodeBuffer{Buf: b, wr: w, bufStats: e.bufStats} e.encodeBuffer = encodeBuffer{Buf: b, wr: w, bufStats: e.bufStats}
if bb, ok := w.(*bytes.Buffer); ok && bb != nil { if bb, ok := w.(*bytes.Buffer); ok && bb != nil {
e.Buf = bb.Bytes()[bb.Len():] // alias the unused buffer of bb e.Buf = bb.AvailableBuffer() // alias the unused buffer of bb
} }
opts2 := jsonopts.Struct{} // avoid mutating e.Struct in case it is part of opts opts2 := jsonopts.Struct{} // avoid mutating e.Struct in case it is part of opts
opts2.Join(opts...) opts2.Join(opts...)

View file

@ -257,7 +257,7 @@ func (*unmarshalersOption) JSONOptions(internal.NotForPublicUse) {}
// Inject support into "jsonopts" to handle these types. // Inject support into "jsonopts" to handle these types.
func init() { func init() {
jsonopts.GetUnknownOption = func(src *jsonopts.Struct, zero jsonopts.Options) (any, bool) { jsonopts.GetUnknownOption = func(src jsonopts.Struct, zero jsonopts.Options) (any, bool) {
switch zero.(type) { switch zero.(type) {
case *marshalersOption: case *marshalersOption:
if !src.Flags.Has(jsonflags.Marshalers) { if !src.Flags.Has(jsonflags.Marshalers) {
@ -273,7 +273,7 @@ func init() {
panic(fmt.Sprintf("unknown option %T", zero)) panic(fmt.Sprintf("unknown option %T", zero))
} }
} }
jsonopts.JoinUnknownOption = func(dst *jsonopts.Struct, src jsonopts.Options) { jsonopts.JoinUnknownOption = func(dst jsonopts.Struct, src jsonopts.Options) jsonopts.Struct {
switch src := src.(type) { switch src := src.(type) {
case *marshalersOption: case *marshalersOption:
dst.Flags.Set(jsonflags.Marshalers | 1) dst.Flags.Set(jsonflags.Marshalers | 1)
@ -284,5 +284,6 @@ func init() {
default: default:
panic(fmt.Sprintf("unknown option %T", src)) panic(fmt.Sprintf("unknown option %T", src))
} }
return dst
} }
} }

View file

@ -64,7 +64,8 @@ type Hash64 interface {
// unless GOFIPS140=v1.0.0 is set. // unless GOFIPS140=v1.0.0 is set.
// //
// If a hash can only determine at runtime if it can be cloned (e.g. if it wraps // If a hash can only determine at runtime if it can be cloned (e.g. if it wraps
// another hash), it may return an error wrapping [errors.ErrUnsupported]. // another hash), Clone may return an error wrapping [errors.ErrUnsupported].
// Otherwise, Clone must always return a nil error.
type Cloner interface { type Cloner interface {
Hash Hash
Clone() (Cloner, error) Clone() (Cloner, error)

View file

@ -26,7 +26,7 @@ type EmptyInterface struct {
Data unsafe.Pointer Data unsafe.Pointer
} }
// EmptyInterface describes the layout of an interface that contains any methods. // NonEmptyInterface describes the layout of an interface that contains any methods.
type NonEmptyInterface struct { type NonEmptyInterface struct {
ITab *ITab ITab *ITab
Data unsafe.Pointer Data unsafe.Pointer

View file

@ -483,7 +483,7 @@ type SliceType struct {
Elem *Type // slice element type Elem *Type // slice element type
} }
// funcType represents a function type. // FuncType represents a function type.
// //
// A *Type for each in and out parameter is stored in an array that // A *Type for each in and out parameter is stored in an array that
// directly follows the funcType (and possibly its uncommonType). So // directly follows the funcType (and possibly its uncommonType). So

View file

@ -25,7 +25,7 @@ type ExperimentFlags struct {
// (This is not necessarily the set of experiments the compiler itself // (This is not necessarily the set of experiments the compiler itself
// was built with.) // was built with.)
// //
// experimentBaseline specifies the experiment flags that are enabled by // Experiment.baseline specifies the experiment flags that are enabled by
// default in the current toolchain. This is, in effect, the "control" // default in the current toolchain. This is, in effect, the "control"
// configuration and any variation from this is an experiment. // configuration and any variation from this is an experiment.
var Experiment ExperimentFlags = func() ExperimentFlags { var Experiment ExperimentFlags = func() ExperimentFlags {
@ -54,7 +54,7 @@ var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
// configuration tuple and returns the enabled and baseline experiment // configuration tuple and returns the enabled and baseline experiment
// flag sets. // flag sets.
// //
// TODO(mdempsky): Move to internal/goexperiment. // TODO(mdempsky): Move to [internal/goexperiment].
func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) { func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) {
// regabiSupported is set to true on platforms where register ABI is // regabiSupported is set to true on platforms where register ABI is
// supported and enabled by default. // supported and enabled by default.

View file

@ -26,6 +26,7 @@ type Info struct {
// Note: After adding entries to this table, update the list in doc/godebug.md as well. // Note: After adding entries to this table, update the list in doc/godebug.md as well.
// (Otherwise the test in this package will fail.) // (Otherwise the test in this package will fail.)
var All = []Info{ var All = []Info{
{Name: "allowmultiplevcs", Package: "cmd/go"},
{Name: "asynctimerchan", Package: "time", Changed: 23, Old: "1"}, {Name: "asynctimerchan", Package: "time", Changed: 23, Old: "1"},
{Name: "containermaxprocs", Package: "runtime", Changed: 25, Old: "0"}, {Name: "containermaxprocs", Package: "runtime", Changed: 25, Old: "0"},
{Name: "dataindependenttiming", Package: "crypto/subtle", Opaque: true}, {Name: "dataindependenttiming", Package: "crypto/subtle", Opaque: true},

View file

@ -14,32 +14,32 @@
// //
// Experiments are exposed to the build in the following ways: // Experiments are exposed to the build in the following ways:
// //
// - Build tag goexperiment.x is set if experiment x (lower case) is // - Build tag goexperiment.x is set if experiment x (lower case) is
// enabled. // enabled.
// //
// - For each experiment x (in camel case), this package contains a // - For each experiment x (in camel case), this package contains a
// boolean constant x and an integer constant xInt. // boolean constant x and an integer constant xInt.
// //
// - In runtime assembly, the macro GOEXPERIMENT_x is defined if // - In runtime assembly, the macro GOEXPERIMENT_x is defined if
// experiment x (lower case) is enabled. // experiment x (lower case) is enabled.
// //
// In the toolchain, the set of experiments enabled for the current // In the toolchain, the set of experiments enabled for the current
// build should be accessed via objabi.Experiment. // build should be accessed via objabi.Experiment.
// //
// The set of experiments is included in the output of runtime.Version() // The set of experiments is included in the output of [runtime.Version]()
// and "go version <binary>" if it differs from the default experiments. // and "go version <binary>" if it differs from the default experiments.
// //
// For the set of experiments supported by the current toolchain, see // For the set of experiments supported by the current toolchain, see
// "go doc goexperiment.Flags". // "go doc goexperiment.Flags".
// //
// Note that this package defines the set of experiments (in Flags) // Note that this package defines the set of experiments (in [Flags])
// and records the experiments that were enabled when the package // and records the experiments that were enabled when the package
// was compiled (as boolean and integer constants). // was compiled (as boolean and integer constants).
// //
// Note especially that this package does not itself change behavior // Note especially that this package does not itself change behavior
// at run time based on the GOEXPERIMENT variable. // at run time based on the GOEXPERIMENT variable.
// The code used in builds to interpret the GOEXPERIMENT variable // The code used in builds to interpret the GOEXPERIMENT variable
// is in the separate package internal/buildcfg. // is in the separate package [internal/buildcfg].
package goexperiment package goexperiment
//go:generate go run mkconsts.go //go:generate go run mkconsts.go
@ -51,7 +51,7 @@ package goexperiment
// tags, experiments use the strings.ToLower of their field name. // tags, experiments use the strings.ToLower of their field name.
// //
// For the baseline experimental configuration, see // For the baseline experimental configuration, see
// [internal/buildcfg.ParseGOEXPERIMENT]. // [internal/buildcfg.Experiment].
// //
// If you change this struct definition, run "go generate". // If you change this struct definition, run "go generate".
type Flags struct { type Flags struct {

View file

@ -37,7 +37,7 @@ func IsStandardPackage(goroot, compiler, path string) bool {
} }
} }
// gccgoSearch holds the gccgo search directories. // gccgoDirs holds the gccgo search directories.
type gccgoDirs struct { type gccgoDirs struct {
once sync.Once once sync.Once
dirs []string dirs []string

View file

@ -23,7 +23,7 @@ import (
) )
func TestTraceAnnotations(t *testing.T) { func TestTraceAnnotations(t *testing.T) {
testTraceProg(t, "annotations.go", func(t *testing.T, tb, _ []byte, _ bool) { testTraceProg(t, "annotations.go", func(t *testing.T, tb, _ []byte, _ string) {
type evDesc struct { type evDesc struct {
kind trace.EventKind kind trace.EventKind
task trace.TaskID task trace.TaskID
@ -98,7 +98,7 @@ func TestTraceCgoCallback(t *testing.T) {
} }
func TestTraceCPUProfile(t *testing.T) { func TestTraceCPUProfile(t *testing.T) {
testTraceProg(t, "cpu-profile.go", func(t *testing.T, tb, stderr []byte, _ bool) { testTraceProg(t, "cpu-profile.go", func(t *testing.T, tb, stderr []byte, _ string) {
// Parse stderr which has a CPU profile summary, if everything went well. // Parse stderr which has a CPU profile summary, if everything went well.
// (If it didn't, we shouldn't even make it here.) // (If it didn't, we shouldn't even make it here.)
scanner := bufio.NewScanner(bytes.NewReader(stderr)) scanner := bufio.NewScanner(bytes.NewReader(stderr))
@ -211,7 +211,7 @@ func TestTraceCPUProfile(t *testing.T) {
} }
func TestTraceFutileWakeup(t *testing.T) { func TestTraceFutileWakeup(t *testing.T) {
testTraceProg(t, "futile-wakeup.go", func(t *testing.T, tb, _ []byte, _ bool) { testTraceProg(t, "futile-wakeup.go", func(t *testing.T, tb, _ []byte, _ string) {
// Check to make sure that no goroutine in the "special" trace region // Check to make sure that no goroutine in the "special" trace region
// ends up blocking, unblocking, then immediately blocking again. // ends up blocking, unblocking, then immediately blocking again.
// //
@ -312,7 +312,7 @@ func TestTraceGOMAXPROCS(t *testing.T) {
} }
func TestTraceStacks(t *testing.T) { func TestTraceStacks(t *testing.T) {
testTraceProg(t, "stacks.go", func(t *testing.T, tb, _ []byte, stress bool) { testTraceProg(t, "stacks.go", func(t *testing.T, tb, _ []byte, godebug string) {
type frame struct { type frame struct {
fn string fn string
line int line int
@ -403,11 +403,19 @@ func TestTraceStacks(t *testing.T) {
{"runtime.GOMAXPROCS", 0}, {"runtime.GOMAXPROCS", 0},
{"main.main", 0}, {"main.main", 0},
}}, }},
{trace.EventStateTransition, "Goroutine Running->Runnable", []frame{ }
asyncPreemptOff := strings.Contains(godebug, "asyncpreemptoff=1")
if asyncPreemptOff {
// Only check for syncPreemptPoint if asynchronous preemption is disabled.
// Otherwise, the syncPreemptPoint goroutine might be exclusively async
// preempted, causing this test to flake.
syncPreemptEv := evDesc{trace.EventStateTransition, "Goroutine Running->Runnable", []frame{
{"main.syncPreemptPoint", 0}, {"main.syncPreemptPoint", 0},
{"main.main.func12", 0}, {"main.main.func12", 0},
}}, }}
want = append(want, syncPreemptEv)
} }
stress := strings.Contains(godebug, "traceadvanceperiod=0")
if !stress { if !stress {
// Only check for this stack if !stress because traceAdvance alone could // Only check for this stack if !stress because traceAdvance alone could
// allocate enough memory to trigger a GC if called frequently enough. // allocate enough memory to trigger a GC if called frequently enough.
@ -535,7 +543,7 @@ func TestTraceIterPull(t *testing.T) {
testTraceProg(t, "iter-pull.go", nil) testTraceProg(t, "iter-pull.go", nil)
} }
func checkReaderDeterminism(t *testing.T, tb, _ []byte, _ bool) { func checkReaderDeterminism(t *testing.T, tb, _ []byte, _ string) {
events := func() []trace.Event { events := func() []trace.Event {
var evs []trace.Event var evs []trace.Event
@ -572,7 +580,7 @@ func checkReaderDeterminism(t *testing.T, tb, _ []byte, _ bool) {
} }
} }
func testTraceProg(t *testing.T, progName string, extra func(t *testing.T, trace, stderr []byte, stress bool)) { func testTraceProg(t *testing.T, progName string, extra func(t *testing.T, trace, stderr []byte, godebug string)) {
testenv.MustHaveGoRun(t) testenv.MustHaveGoRun(t)
// Check if we're on a builder. // Check if we're on a builder.
@ -657,7 +665,7 @@ func testTraceProg(t *testing.T, progName string, extra func(t *testing.T, trace
// Run some extra validation. // Run some extra validation.
if !t.Failed() && extra != nil { if !t.Failed() && extra != nil {
extra(t, tb, errBuf.Bytes(), stress) extra(t, tb, errBuf.Bytes(), godebug)
} }
// Dump some more information on failure. // Dump some more information on failure.
@ -686,6 +694,9 @@ func testTraceProg(t *testing.T, progName string, extra func(t *testing.T, trace
t.Run("Default", func(t *testing.T) { t.Run("Default", func(t *testing.T) {
runTest(t, false, "") runTest(t, false, "")
}) })
t.Run("AsyncPreemptOff", func(t *testing.T) {
runTest(t, false, "asyncpreemptoff=1")
})
t.Run("Stress", func(t *testing.T) { t.Run("Stress", func(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("skipping trace stress tests in short mode") t.Skip("skipping trace stress tests in short mode")

View file

@ -616,7 +616,7 @@ func UserHomeDir() (string, error) {
if v := Getenv(env); v != "" { if v := Getenv(env); v != "" {
return v, nil return v, nil
} }
// On some geese the home directory is not always defined. // On some operating systems the home directory is not always defined.
switch runtime.GOOS { switch runtime.GOOS {
case "android": case "android":
return "/sdcard", nil return "/sdcard", nil

View file

@ -1919,3 +1919,13 @@ const (
BubbleAssocCurrentBubble = bubbleAssocCurrentBubble BubbleAssocCurrentBubble = bubbleAssocCurrentBubble
BubbleAssocOtherBubble = bubbleAssocOtherBubble BubbleAssocOtherBubble = bubbleAssocOtherBubble
) )
type TraceStackTable traceStackTable
func (t *TraceStackTable) Reset() {
t.tab.reset()
}
func TraceStack(gp *G, tab *TraceStackTable) {
traceStack(0, gp, (*traceStackTable)(tab))
}

View file

@ -230,6 +230,11 @@ Below is the full list of supported metrics, ordered lexicographically.
/gc/stack/starting-size:bytes /gc/stack/starting-size:bytes
The stack size of new goroutines. The stack size of new goroutines.
/godebug/non-default-behavior/allowmultiplevcs:events
The number of non-default behaviors executed by the cmd/go
package due to a non-default GODEBUG=allowmultiplevcs=...
setting.
/godebug/non-default-behavior/asynctimerchan:events /godebug/non-default-behavior/asynctimerchan:events
The number of non-default behaviors executed by the time package The number of non-default behaviors executed by the time package
due to a non-default GODEBUG=asynctimerchan=... setting. due to a non-default GODEBUG=asynctimerchan=... setting.

View file

@ -78,6 +78,9 @@ func checkGdbVersion(t *testing.T) {
if major < 10 { if major < 10 {
t.Skipf("skipping: gdb version %d.%d too old", major, minor) t.Skipf("skipping: gdb version %d.%d too old", major, minor)
} }
if major < 12 || (major == 12 && minor < 1) {
t.Logf("gdb version <12.1 is known to crash due to a SIGWINCH recieved in non-interactive mode; if you see a crash, some test may be sending SIGWINCH to the whole process group. See go.dev/issue/58932.")
}
t.Logf("gdb version %d.%d", major, minor) t.Logf("gdb version %d.%d", major, minor)
} }

View file

@ -981,6 +981,9 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, strict bool) (int32, uint
// matches the cached contents. // matches the cached contents.
const debugCheckCache = false const debugCheckCache = false
// If true, skip checking the cache entirely.
const skipCache = false
if off == 0 { if off == 0 {
return -1, 0 return -1, 0
} }
@ -991,7 +994,7 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, strict bool) (int32, uint
var checkVal int32 var checkVal int32
var checkPC uintptr var checkPC uintptr
ck := pcvalueCacheKey(targetpc) ck := pcvalueCacheKey(targetpc)
{ if !skipCache {
mp := acquirem() mp := acquirem()
cache := &mp.pcvalueCache cache := &mp.pcvalueCache
// The cache can be used by the signal handler on this M. Avoid // The cache can be used by the signal handler on this M. Avoid

View file

@ -226,7 +226,7 @@ TEXT runtime·walltime(SB),NOSPLIT,$32-12
MOVD R4, 24(R15) MOVD R4, 24(R15)
MOVD R14, R8 // Backup return address MOVD R14, R8 // Backup return address
MOVD $sec+0(FP), R4 // return parameter caller MOVD $ret-8(FP), R4 // caller's SP
MOVD R8, m_vdsoPC(R6) MOVD R8, m_vdsoPC(R6)
MOVD R4, m_vdsoSP(R6) MOVD R4, m_vdsoSP(R6)
@ -312,7 +312,7 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$32-8
MOVD R4, 24(R15) MOVD R4, 24(R15)
MOVD R14, R8 // Backup return address MOVD R14, R8 // Backup return address
MOVD $ret+0(FP), R4 // caller's SP MOVD $ret-8(FP), R4 // caller's SP
MOVD R8, m_vdsoPC(R6) MOVD R8, m_vdsoPC(R6)
MOVD R4, m_vdsoSP(R6) MOVD R4, m_vdsoSP(R6)

View file

@ -13,9 +13,11 @@ package main
import ( import (
"fmt" "fmt"
"io"
"os" "os"
"os/exec" "os/exec"
"os/signal" "os/signal"
"runtime"
"sync" "sync"
"syscall" "syscall"
"time" "time"
@ -23,10 +25,51 @@ import (
func init() { func init() {
register("SignalDuringExec", SignalDuringExec) register("SignalDuringExec", SignalDuringExec)
register("SignalDuringExecPgrp", SignalDuringExecPgrp)
register("Nop", Nop) register("Nop", Nop)
} }
func SignalDuringExec() { func SignalDuringExec() {
// Re-launch ourselves in a new process group.
cmd := exec.Command(os.Args[0], "SignalDuringExecPgrp")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
// Start the new process with an extra pipe. It will
// exit if the pipe is closed.
rp, wp, err := os.Pipe()
if err != nil {
fmt.Printf("Failed to create pipe: %v", err)
return
}
cmd.ExtraFiles = []*os.File{rp}
// Run the command.
if err := cmd.Run(); err != nil {
fmt.Printf("Run failed: %v", err)
}
// We don't actually need to write to the pipe, it just
// needs to get closed, which will happen on process
// exit.
runtime.KeepAlive(wp)
}
func SignalDuringExecPgrp() {
// Grab fd 3 which is a pipe we need to read on.
f := os.NewFile(3, "pipe")
go func() {
// Nothing will ever get written to the pipe, so we'll
// just block on it. If it closes, ReadAll will return
// one way or another, at which point we'll exit.
io.ReadAll(f)
os.Exit(1)
}()
// This is just for SignalDuringExec.
pgrp := syscall.Getpgrp() pgrp := syscall.Getpgrp()
const tries = 10 const tries = 10

View file

@ -396,7 +396,7 @@ func traceAdvance(stopTrace bool) {
ug.status = readgstatus(s.g) &^ _Gscan ug.status = readgstatus(s.g) &^ _Gscan
ug.waitreason = s.g.waitreason ug.waitreason = s.g.waitreason
ug.inMarkAssist = s.g.inMarkAssist ug.inMarkAssist = s.g.inMarkAssist
ug.stackID = traceStack(0, gp, gen) ug.stackID = traceStack(0, gp, &trace.stackTab[gen%2])
} }
resumeG(s) resumeG(s)
casgstatus(me, _Gwaiting, _Grunning) casgstatus(me, _Gwaiting, _Grunning)

View file

@ -56,7 +56,7 @@ func (e traceEventWriter) event(ev tracev2.EventType, args ...traceArg) {
// It then returns a traceArg representing that stack which may be // It then returns a traceArg representing that stack which may be
// passed to write. // passed to write.
func (tl traceLocker) stack(skip int) traceArg { func (tl traceLocker) stack(skip int) traceArg {
return traceArg(traceStack(skip, nil, tl.gen)) return traceArg(traceStack(skip, nil, &trace.stackTab[tl.gen%2]))
} }
// startPC takes a start PC for a goroutine and produces a unique // startPC takes a start PC for a goroutine and produces a unique

View file

@ -28,10 +28,8 @@ const (
// skip controls the number of leaf frames to omit in order to hide tracer internals // skip controls the number of leaf frames to omit in order to hide tracer internals
// from stack traces, see CL 5523. // from stack traces, see CL 5523.
// //
// Avoid calling this function directly. gen needs to be the current generation // Avoid calling this function directly. Prefer traceEventWriter.stack.
// that this stack trace is being written out for, which needs to be synchronized with func traceStack(skip int, gp *g, tab *traceStackTable) uint64 {
// generations moving forward. Prefer traceEventWriter.stack.
func traceStack(skip int, gp *g, gen uintptr) uint64 {
var pcBuf [tracev2.MaxFramesPerStack]uintptr var pcBuf [tracev2.MaxFramesPerStack]uintptr
// Figure out gp and mp for the backtrace. // Figure out gp and mp for the backtrace.
@ -134,7 +132,7 @@ func traceStack(skip int, gp *g, gen uintptr) uint64 {
if nstk > 0 && gp.goid == 1 { if nstk > 0 && gp.goid == 1 {
nstk-- // skip runtime.main nstk-- // skip runtime.main
} }
id := trace.stackTab[gen%2].put(pcBuf[:nstk]) id := tab.put(pcBuf[:nstk])
return id return id
} }

View file

@ -0,0 +1,46 @@
// Copyright 2025 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 runtime_test
import (
"runtime"
"strconv"
"testing"
)
func BenchmarkTraceStack(b *testing.B) {
for _, stackDepth := range []int{1, 10, 100} {
b.Run("stackDepth="+strconv.Itoa(stackDepth), func(b *testing.B) {
benchmarkTraceStack(b, stackDepth)
})
}
}
func benchmarkTraceStack(b *testing.B, stackDepth int) {
var tab runtime.TraceStackTable
defer tab.Reset()
wait := make(chan struct{})
ready := make(chan struct{})
done := make(chan struct{})
var gp *runtime.G
go func() {
gp = runtime.Getg()
useStackAndCall(stackDepth, func() {
ready <- struct{}{}
<-wait
})
done <- struct{}{}
}()
<-ready
for b.Loop() {
runtime.TraceStack(gp, &tab)
}
// Clean up.
wait <- struct{}{}
<-done
}

View file

@ -1454,6 +1454,8 @@ func TestRepeatPanics(t *testing.T) {
} }
} }
var leak *int
func TestIssue68488(t *testing.T) { func TestIssue68488(t *testing.T) {
s := make([]int, 3) s := make([]int, 3)
clone := Clone(s[1:1]) clone := Clone(s[1:1])
@ -1461,6 +1463,7 @@ func TestIssue68488(t *testing.T) {
case &s[0], &s[1], &s[2]: case &s[0], &s[1], &s[2]:
t.Error("clone keeps alive s due to array overlap") t.Error("clone keeps alive s due to array overlap")
} }
leak = &s[1] // see go.dev/issue/74387
} }
// This test asserts the behavior when the primary slice operand is nil. // This test asserts the behavior when the primary slice operand is nil.

View file

@ -26,13 +26,15 @@ type Interface interface {
// Sort may place equal elements in any order in the final result, // Sort may place equal elements in any order in the final result,
// while Stable preserves the original input order of equal elements. // while Stable preserves the original input order of equal elements.
// //
// Less must describe a transitive ordering: // Less must describe a [Strict Weak Ordering]. For example:
// - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well. // - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.
// - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well. // - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.
// //
// Note that floating-point comparison (the < operator on float32 or float64 values) // Note that floating-point comparison (the < operator on float32 or float64 values)
// is not a transitive ordering when not-a-number (NaN) values are involved. // is not a strict weak ordering when not-a-number (NaN) values are involved.
// See Float64Slice.Less for a correct implementation for floating-point values. // See Float64Slice.Less for a correct implementation for floating-point values.
//
// [Strict Weak Ordering]: https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings
Less(i, j int) bool Less(i, j int) bool
// Swap swaps the elements with indexes i and j. // Swap swaps the elements with indexes i and j.

View file

@ -21,7 +21,7 @@ import (
func TestTime(t *testing.T) { func TestTime(t *testing.T) {
synctest.Test(t, func(t *testing.T) { synctest.Test(t, func(t *testing.T) {
start := time.Now() // always midnight UTC 2001-01-01 start := time.Now() // always midnight UTC 2000-01-01
go func() { go func() {
time.Sleep(1 * time.Nanosecond) time.Sleep(1 * time.Nanosecond)
t.Log(time.Since(start)) // always logs "1ns" t.Log(time.Since(start)) // always logs "1ns"

View file

@ -10,7 +10,7 @@ import "internal/synctest"
// Run is deprecated. // Run is deprecated.
// //
// Deprecated: Use Test instead. // Deprecated: Use Test instead. Run will be removed in Go 1.26.
func Run(f func()) { func Run(f func()) {
synctest.Run(f) synctest.Run(f)
} }

View file

@ -22,7 +22,7 @@
// //
// func TestTime(t *testing.T) { // func TestTime(t *testing.T) {
// synctest.Test(t, func(t *testing.T) { // synctest.Test(t, func(t *testing.T) {
// start := time.Now() // always midnight UTC 2001-01-01 // start := time.Now() // always midnight UTC 2000-01-01
// go func() { // go func() {
// time.Sleep(1 * time.Second) // time.Sleep(1 * time.Second)
// t.Log(time.Since(start)) // always logs "1s" // t.Log(time.Since(start)) // always logs "1s"

View file

@ -11,6 +11,7 @@ import (
"regexp" "regexp"
"testing" "testing"
"testing/synctest" "testing/synctest"
"time"
) )
// Tests for interactions between synctest bubbles and the testing package. // Tests for interactions between synctest bubbles and the testing package.
@ -179,3 +180,11 @@ func runTest(t *testing.T, args []string, f func(), pattern string) {
t.Errorf("got output:\n%s\nwant matching:\n%s", out, pattern) t.Errorf("got output:\n%s\nwant matching:\n%s", out, pattern)
} }
} }
func TestNow(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
if got, want := time.Now(), time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC); !got.Equal(want) {
t.Errorf("time.Now() = %v, want %v", got, want)
}
})
}