mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.simd] all: merge master (88cf0c5) into dev.simd
Merge List: + 2025-07-1188cf0c5d55cmd/link: do size fixups after symbol references are loaded + 2025-07-107a38975a48os: trivial comment fix + 2025-07-10aa5de9ebb5synctest: fix comments for time.Now() in synctests + 2025-07-1063ec70d4e1crypto/cipher: Fix comment punctuation + 2025-07-098131635e5aruntime: run TestSignalDuringExec in its own process group + 2025-07-0967c1704444crypto/tls: empty server_name conf. ext. from server + 2025-07-0854c9d77630cmd/go: disable support for multiple vcs in one module + 2025-07-08fca43a8436internal: make struct comment match struct name + 2025-07-08bb917bb030cmd/compile: document that nosplit directive is unsafe + 2025-07-08a5bda585d5cmd/compile: run fmt on ssa + 2025-07-0786b5ba7310internal/trace: only test for sync preemption if async preemption is off + 2025-07-07ef46e1b164cmd/internal/doc: fix GOROOT skew and path joining bugs + 2025-07-0775b43f9a97runtime: make traceStack testable and add a benchmark + 2025-07-0720978f46fdcrypto/rsa: remove another forgotten note to future self + 2025-07-0733fb4819f5cmd/compile/internal/ssa: skip EndSequence entries in TestStmtLines + 2025-07-07a995269a93sort: clarify Less doc + 2025-07-036c3b5a2798runtime: correct vdsoSP on S390X + 2025-07-03dd687c3860hash: document that Clone may only return ErrUnsupported or a nil error + 2025-07-02b325151453cmd/cgo/internal/testsanitizers: skip asan tests when FIPS140 mode is on + 2025-07-0215d9fe43d6testing/synctest: explicitly state Run will be removed in Go 1.26 + 2025-07-01de646d94f7cmd/go/internal/modindex: apply changes in CL 502615 to modindex package + 2025-07-012f653a5a9ecrypto/tls: ensure the ECDSA curve matches the signature algorithm + 2025-07-016e95fd96cccrypto/ecdsa: fix crypto/x509 godoc links + 2025-07-017755a05209Revert "crypto/internal/fips140/subtle: add assembly implementation of xorBytes for arm" + 2025-07-01d168ad18e1slices: update TestIssue68488 to avoid false positives + 2025-07-0127ad1f5013internal/abi: fix comment on NonEmptyInterface + 2025-06-3086fca3dcb6encoding/json/jsontext: use bytes.Buffer.AvailableBuffer + 2025-06-306bd9944c9aencoding/json/v2: avoid escaping jsonopts.Struct + 2025-06-30e46d586eddcmd/compile/internal/escape: add debug hash for literal allocation optimizations + 2025-06-30479b51ee1fcmd/compile/internal/escape: stop disabling literal allocation optimizations when coverage is enabled + 2025-06-308002d283e8crypto/tls: update bogo version + 2025-06-30fdd7713fe5internal/goexperiment: fix godoc formatting Change-Id: I074e6c75778890930975925c016004aabca2b9d1
This commit is contained in:
commit
21596f2f75
63 changed files with 672 additions and 498 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"`
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
54
src/cmd/go/testdata/script/test_multivcs.txt
vendored
Normal file
54
src/cmd/go/testdata/script/test_multivcs.txt
vendored
Normal 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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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():
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
136
src/crypto/tls/testdata/Server-TLSv12-SNI
vendored
136
src/crypto/tls/testdata/Server-TLSv12-SNI
vendored
|
|
@ -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|
|
||||||
|
|
|
||||||
|
|
@ -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....|
|
||||||
|
|
|
||||||
|
|
@ -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.|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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...)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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},
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
43
src/runtime/testdata/testprognet/signalexec.go
vendored
43
src/runtime/testdata/testprognet/signalexec.go
vendored
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
46
src/runtime/tracestack_test.go
Normal file
46
src/runtime/tracestack_test.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue