On 2023-02-15 11:58:54 +0800, Shengjing Zhu wrote:
> Package: release.debian.org
> Severity: normal
> User: release.debian....@packages.debian.org
> Usertags: unblock
> X-Debbugs-Cc: golang-1...@packages.debian.org, z...@debian.org
> Control: affects -1 + src:golang-1.19
> 
> Please unblock package golang-1.19

Please go ahead with the upload.

> 
> [ Reason ]
> A new upstream release that addresses 4 CVE in Go standard library.
> 
> [ Impact ]
> CVE in Go standard library and the Go packages that have statically
> linked with it.
> 
> [ Tests ]
> The fixes are covered by new unit tests.
> 
> [ Risks ]
> The package is in the toolchain set.
> 
> [ Checklist ]
>   [x] all changes are documented in the d/changelog
>   [x] I reviewed all changes and I approve them
>   [x] attach debdiff against the package in testing
> 
>       The diff is for golang-1.19/1.19.6-1, which I have uploaded to
>       experimental first. -2 should be no-change rebuild on unstable.
> 
> [ Other info ]
> So same as previous unblock request #1028452
> + This package doesn't have autopkgtest.
> + The upload will trigger Release Team to perform a new round of rebuilding
>   outdated Built-Using for all Go packages.
> 
> The Go upstream usually has one minor version (may or may not carry CVE
> fixes) release every month.
> I'm wondering what Release Team thinks how often we should update
> during the freeze periods. Some options are:
> + Only ask pre-approval for minor versions with CVE
> + Don't update any (probably at late freeze period, like hard/full-freeze).

I would suggest to stick to versions fixing CVEs for now. If there is a
no-CVE releases between the last update and the start of the hard
freeze, we can revisit a final update and rebuild of the golang-world.

Cheers

> 
> The package currently FTBFS on i386/experimental but it won't be problem on
> unstable.
> The dep-resolver (aspcud) in experimental chooses gccgo to bootstrap,
> which has a bug https://github.com/golang/go/issues/51850.
> But on unstable the dep-resolver is apt, and will choose old golang-go to
> bootstrap.
> 
> unblock golang-1.19/1.19.6-2

> diff -Nru golang-1.19-1.19.5/debian/changelog 
> golang-1.19-1.19.6/debian/changelog
> --- golang-1.19-1.19.5/debian/changelog       2023-01-11 15:35:00.000000000 
> +0800
> +++ golang-1.19-1.19.6/debian/changelog       2023-02-15 10:09:02.000000000 
> +0800
> @@ -1,3 +1,16 @@
> +golang-1.19 (1.19.6-1) experimental; urgency=medium
> +
> +  * Team upload
> +  * New upstream version 1.19.6
> +    + CVE-2022-41722: path/filepath: path traversal in filepath.Clean on
> +      Windows
> +    + CVE-2022-41725: net/http, mime/multipart: denial of service from
> +      excessive resource consumption
> +    + CVE-2022-41724: crypto/tls: large handshake records may cause panics
> +    + CVE-2022-41723: net/http: avoid quadratic complexity in HPACK decoding
> +
> + -- Shengjing Zhu <z...@debian.org>  Wed, 15 Feb 2023 10:09:02 +0800
> +
>  golang-1.19 (1.19.5-1) unstable; urgency=medium
>  
>    * Team upload
> diff -Nru golang-1.19-1.19.5/src/cmd/go/internal/modfetch/coderepo_test.go 
> golang-1.19-1.19.6/src/cmd/go/internal/modfetch/coderepo_test.go
> --- golang-1.19-1.19.5/src/cmd/go/internal/modfetch/coderepo_test.go  
> 2023-01-10 06:38:03.000000000 +0800
> +++ golang-1.19-1.19.6/src/cmd/go/internal/modfetch/coderepo_test.go  
> 2023-02-14 01:38:43.000000000 +0800
> @@ -379,18 +379,6 @@
>               zipFileHash: 
> "c15e49d58b7a4c37966cbe5bc01a0330cd5f2927e990e1839bda1d407766d9c5",
>       },
>       {
> -             vcs:         "git",
> -             path:        "gopkg.in/natefinch/lumberjack.v2",
> -             rev:         "latest",
> -             version:     "v2.0.0-20170531160350-a96e63847dc3",
> -             name:        "a96e63847dc3c67d17befa69c303767e2f84e54f",
> -             short:       "a96e63847dc3",
> -             time:        time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
> -             gomod:       "module gopkg.in/natefinch/lumberjack.v2\n",
> -             zipSum:      "h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI=",
> -             zipFileHash: 
> "b5de0da7bbbec76709eef1ac71b6c9ff423b9fbf3bb97b56743450d4937b06d5",
> -     },
> -     {
>               vcs:  "git",
>               path: "gopkg.in/natefinch/lumberjack.v2",
>               // This repo has a v2.1 tag.
> @@ -578,6 +566,10 @@
>       for _, tt := range codeRepoTests {
>               f := func(tt codeRepoTest) func(t *testing.T) {
>                       return func(t *testing.T) {
> +                             if strings.Contains(tt.path, "gopkg.in") {
> +                                     testenv.SkipFlaky(t, 54503)
> +                             }
> +
>                               t.Parallel()
>                               if tt.vcs != "mod" {
>                                       testenv.MustHaveExecPath(t, tt.vcs)
> @@ -790,11 +782,6 @@
>       },
>       {
>               vcs:      "git",
> -             path:     "gopkg.in/natefinch/lumberjack.v2",
> -             versions: []string{"v2.0.0"},
> -     },
> -     {
> -             vcs:      "git",
>               path:     "vcs-test.golang.org/git/odd-tags.git",
>               versions: nil,
>       },
> @@ -811,8 +798,12 @@
>  
>       t.Run("parallel", func(t *testing.T) {
>               for _, tt := range codeRepoVersionsTests {
> +                     tt := tt
>                       t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t 
> *testing.T) {
> -                             tt := tt
> +                             if strings.Contains(tt.path, "gopkg.in") {
> +                                     testenv.SkipFlaky(t, 54503)
> +                             }
> +
>                               t.Parallel()
>                               if tt.vcs != "mod" {
>                                       testenv.MustHaveExecPath(t, tt.vcs)
> diff -Nru 
> golang-1.19-1.19.5/src/cmd/go/testdata/script/mod_gopkg_unstable.txt 
> golang-1.19-1.19.6/src/cmd/go/testdata/script/mod_gopkg_unstable.txt
> --- golang-1.19-1.19.5/src/cmd/go/testdata/script/mod_gopkg_unstable.txt      
> 2023-01-10 06:38:05.000000000 +0800
> +++ golang-1.19-1.19.6/src/cmd/go/testdata/script/mod_gopkg_unstable.txt      
> 2023-02-14 01:38:43.000000000 +0800
> @@ -10,6 +10,8 @@
>  [!net] skip
>  [!exec:git] skip
>  
> +skip  # TODO(#54503): redirect gopkg.in requests to a local server and 
> re-enable.
> +
>  env GOPROXY=direct
>  env GOSUMDB=off
>  go get gopkg.in/macaroon-bakery.v2-unstable/bakery
> diff -Nru 
> golang-1.19-1.19.5/src/cmd/go/testdata/script/version_gc_sections.txt 
> golang-1.19-1.19.6/src/cmd/go/testdata/script/version_gc_sections.txt
> --- golang-1.19-1.19.5/src/cmd/go/testdata/script/version_gc_sections.txt     
> 1970-01-01 08:00:00.000000000 +0800
> +++ golang-1.19-1.19.6/src/cmd/go/testdata/script/version_gc_sections.txt     
> 2023-02-14 01:38:43.000000000 +0800
> @@ -0,0 +1,24 @@
> +# This test checks that external linking with --gc-sections does not strip 
> version information.
> +
> +[short] skip
> +[!cgo] skip
> +[aix] skip  # no --gc-sections
> +[darwin] skip  # no --gc-sections
> +
> +go build -ldflags='-linkmode=external -extldflags=-Wl,--gc-sections'
> +go version hello$GOEXE
> +! stdout 'not a Go executable'
> +! stderr 'not a Go executable'
> +
> +-- go.mod --
> +module hello
> +-- hello.go --
> +package main
> +
> +/*
> +*/
> +import "C"
> +
> +func main() {
> +     println("hello")
> +}
> diff -Nru golang-1.19-1.19.5/src/cmd/internal/moddeps/moddeps_test.go 
> golang-1.19-1.19.6/src/cmd/internal/moddeps/moddeps_test.go
> --- golang-1.19-1.19.5/src/cmd/internal/moddeps/moddeps_test.go       
> 2023-01-10 06:38:05.000000000 +0800
> +++ golang-1.19-1.19.6/src/cmd/internal/moddeps/moddeps_test.go       
> 2023-02-14 01:38:43.000000000 +0800
> @@ -33,7 +33,7 @@
>  // See issues 36852, 41409, and 43687.
>  // (Also see golang.org/issue/27348.)
>  func TestAllDependencies(t *testing.T) {
> -     t.Skip("TODO(#57009): 1.19.4 contains unreleased changes from vendored 
> modules")
> +     t.Skip("TODO(#58355): 1.19.4 contains unreleased changes from vendored 
> modules")
>  
>       goBin := testenv.GoToolPath(t)
>  
> diff -Nru golang-1.19-1.19.5/src/cmd/link/internal/ld/data.go 
> golang-1.19-1.19.6/src/cmd/link/internal/ld/data.go
> --- golang-1.19-1.19.5/src/cmd/link/internal/ld/data.go       2023-01-10 
> 06:38:05.000000000 +0800
> +++ golang-1.19-1.19.6/src/cmd/link/internal/ld/data.go       2023-02-14 
> 01:38:43.000000000 +0800
> @@ -1601,6 +1601,9 @@
>  func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s 
> loader.Sym, rwx int) *sym.Section {
>       ldr := state.ctxt.loader
>       sname := ldr.SymName(s)
> +     if sname == "go.buildinfo" { // clumsy hack for Go 1.19 builders
> +             sname = ".go.buildinfo"
> +     }
>       sect := addsection(ldr, state.ctxt.Arch, seg, sname, rwx)
>       sect.Align = symalign(ldr, s)
>       state.datsize = Rnd(state.datsize, int64(sect.Align))
> @@ -2177,7 +2180,7 @@
>       // Write the buildinfo symbol, which go version looks for.
>       // The code reading this data is in package debug/buildinfo.
>       ldr := ctxt.loader
> -     s := ldr.CreateSymForUpdate(".go.buildinfo", 0)
> +     s := ldr.CreateSymForUpdate("go.buildinfo", 0)
>       s.SetType(sym.SBUILDINFO)
>       s.SetAlign(16)
>       // The \xff is invalid UTF-8, meant to make it less likely
> @@ -2199,6 +2202,14 @@
>       }
>       s.SetData(data)
>       s.SetSize(int64(len(data)))
> +
> +     // Add reference to go:buildinfo from the rodata section,
> +     // so that external linking with -Wl,--gc-sections does not
> +     // delete the build info.
> +     sr := ldr.CreateSymForUpdate("go.buildinfo.ref", 0)
> +     sr.SetType(sym.SRODATA)
> +     sr.SetAlign(int32(ctxt.Arch.PtrSize))
> +     sr.AddAddr(ctxt.Arch, s.Sym())
>  }
>  
>  // appendString appends s to data, prefixed by its varint-encoded length.
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/boring_test.go 
> golang-1.19-1.19.6/src/crypto/tls/boring_test.go
> --- golang-1.19-1.19.5/src/crypto/tls/boring_test.go  2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/boring_test.go  2023-02-14 
> 01:38:45.000000000 +0800
> @@ -269,7 +269,7 @@
>  
>       go Client(c, clientConfig).Handshake()
>       srv := Server(s, testConfig)
> -     msg, err := srv.readHandshake()
> +     msg, err := srv.readHandshake(nil)
>       if err != nil {
>               t.Fatal(err)
>       }
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/common.go 
> golang-1.19-1.19.6/src/crypto/tls/common.go
> --- golang-1.19-1.19.5/src/crypto/tls/common.go       2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/common.go       2023-02-14 
> 01:38:45.000000000 +0800
> @@ -1384,7 +1384,7 @@
>  }
>  
>  type handshakeMessage interface {
> -     marshal() []byte
> +     marshal() ([]byte, error)
>       unmarshal([]byte) bool
>  }
>  
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/conn.go 
> golang-1.19-1.19.6/src/crypto/tls/conn.go
> --- golang-1.19-1.19.5/src/crypto/tls/conn.go 2023-01-10 06:38:14.000000000 
> +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/conn.go 2023-02-14 01:38:45.000000000 
> +0800
> @@ -1003,18 +1003,37 @@
>       return n, nil
>  }
>  
> -// writeRecord writes a TLS record with the given type and payload to the
> -// connection and updates the record layer state.
> -func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) {
> +// writeHandshakeRecord writes a handshake message to the connection and 
> updates
> +// the record layer state. If transcript is non-nil the marshalled message is
> +// written to it.
> +func (c *Conn) writeHandshakeRecord(msg handshakeMessage, transcript 
> transcriptHash) (int, error) {
>       c.out.Lock()
>       defer c.out.Unlock()
>  
> -     return c.writeRecordLocked(typ, data)
> +     data, err := msg.marshal()
> +     if err != nil {
> +             return 0, err
> +     }
> +     if transcript != nil {
> +             transcript.Write(data)
> +     }
> +
> +     return c.writeRecordLocked(recordTypeHandshake, data)
> +}
> +
> +// writeChangeCipherRecord writes a ChangeCipherSpec message to the 
> connection and
> +// updates the record layer state.
> +func (c *Conn) writeChangeCipherRecord() error {
> +     c.out.Lock()
> +     defer c.out.Unlock()
> +     _, err := c.writeRecordLocked(recordTypeChangeCipherSpec, []byte{1})
> +     return err
>  }
>  
>  // readHandshake reads the next handshake message from
> -// the record layer.
> -func (c *Conn) readHandshake() (any, error) {
> +// the record layer. If transcript is non-nil, the message
> +// is written to the passed transcriptHash.
> +func (c *Conn) readHandshake(transcript transcriptHash) (any, error) {
>       for c.hand.Len() < 4 {
>               if err := c.readRecord(); err != nil {
>                       return nil, err
> @@ -1093,6 +1112,11 @@
>       if !m.unmarshal(data) {
>               return nil, 
> c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
>       }
> +
> +     if transcript != nil {
> +             transcript.Write(data)
> +     }
> +
>       return m, nil
>  }
>  
> @@ -1168,7 +1192,7 @@
>               return errors.New("tls: internal error: unexpected 
> renegotiation")
>       }
>  
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -1214,7 +1238,7 @@
>               return c.handleRenegotiation()
>       }
>  
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -1250,7 +1274,11 @@
>               defer c.out.Unlock()
>  
>               msg := &keyUpdateMsg{}
> -             _, err := c.writeRecordLocked(recordTypeHandshake, 
> msg.marshal())
> +             msgBytes, err := msg.marshal()
> +             if err != nil {
> +                     return err
> +             }
> +             _, err = c.writeRecordLocked(recordTypeHandshake, msgBytes)
>               if err != nil {
>                       // Surface the error at the next write.
>                       c.out.setErrorLocked(err)
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_client.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_client.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_client.go     2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_client.go     2023-02-14 
> 01:38:45.000000000 +0800
> @@ -162,7 +162,10 @@
>       }
>       c.serverName = hello.serverName
>  
> -     cacheKey, session, earlySecret, binderKey := c.loadSession(hello)
> +     cacheKey, session, earlySecret, binderKey, err := c.loadSession(hello)
> +     if err != nil {
> +             return err
> +     }
>       if cacheKey != "" && session != nil {
>               defer func() {
>                       // If we got a handshake failure when resuming a 
> session, throw away
> @@ -177,11 +180,12 @@
>               }()
>       }
>  
> -     if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err 
> != nil {
> +     if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
>               return err
>       }
>  
> -     msg, err := c.readHandshake()
> +     // serverHelloMsg is not included in the transcript
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -246,9 +250,9 @@
>  }
>  
>  func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
> -     session *ClientSessionState, earlySecret, binderKey []byte) {
> +     session *ClientSessionState, earlySecret, binderKey []byte, err error) {
>       if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == 
> nil {
> -             return "", nil, nil, nil
> +             return "", nil, nil, nil, nil
>       }
>  
>       hello.ticketSupported = true
> @@ -263,14 +267,14 @@
>       // renegotiation is primarily used to allow a client to send a client
>       // certificate, which would be skipped if session resumption occurred.
>       if c.handshakes != 0 {
> -             return "", nil, nil, nil
> +             return "", nil, nil, nil, nil
>       }
>  
>       // Try to resume a previously negotiated TLS session, if available.
>       cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
>       session, ok := c.config.ClientSessionCache.Get(cacheKey)
>       if !ok || session == nil {
> -             return cacheKey, nil, nil, nil
> +             return cacheKey, nil, nil, nil, nil
>       }
>  
>       // Check that version used for the previous session is still valid.
> @@ -282,7 +286,7 @@
>               }
>       }
>       if !versOk {
> -             return cacheKey, nil, nil, nil
> +             return cacheKey, nil, nil, nil, nil
>       }
>  
>       // Check that the cached server certificate is not expired, and that 
> it's
> @@ -291,16 +295,16 @@
>       if !c.config.InsecureSkipVerify {
>               if len(session.verifiedChains) == 0 {
>                       // The original connection had InsecureSkipVerify, 
> while this doesn't.
> -                     return cacheKey, nil, nil, nil
> +                     return cacheKey, nil, nil, nil, nil
>               }
>               serverCert := session.serverCertificates[0]
>               if c.config.time().After(serverCert.NotAfter) {
>                       // Expired certificate, delete the entry.
>                       c.config.ClientSessionCache.Put(cacheKey, nil)
> -                     return cacheKey, nil, nil, nil
> +                     return cacheKey, nil, nil, nil, nil
>               }
>               if err := serverCert.VerifyHostname(c.config.ServerName); err 
> != nil {
> -                     return cacheKey, nil, nil, nil
> +                     return cacheKey, nil, nil, nil, nil
>               }
>       }
>  
> @@ -308,7 +312,7 @@
>               // In TLS 1.2 the cipher suite must match the resumed session. 
> Ensure we
>               // are still offering it.
>               if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) 
> == nil {
> -                     return cacheKey, nil, nil, nil
> +                     return cacheKey, nil, nil, nil, nil
>               }
>  
>               hello.sessionTicket = session.sessionTicket
> @@ -318,14 +322,14 @@
>       // Check that the session ticket is not expired.
>       if c.config.time().After(session.useBy) {
>               c.config.ClientSessionCache.Put(cacheKey, nil)
> -             return cacheKey, nil, nil, nil
> +             return cacheKey, nil, nil, nil, nil
>       }
>  
>       // In TLS 1.3 the KDF hash must match the resumed session. Ensure we
>       // offer at least one cipher suite with that hash.
>       cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite)
>       if cipherSuite == nil {
> -             return cacheKey, nil, nil, nil
> +             return cacheKey, nil, nil, nil, nil
>       }
>       cipherSuiteOk := false
>       for _, offeredID := range hello.cipherSuites {
> @@ -336,7 +340,7 @@
>               }
>       }
>       if !cipherSuiteOk {
> -             return cacheKey, nil, nil, nil
> +             return cacheKey, nil, nil, nil, nil
>       }
>  
>       // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
> @@ -354,9 +358,15 @@
>       earlySecret = cipherSuite.extract(psk, nil)
>       binderKey = cipherSuite.deriveSecret(earlySecret, 
> resumptionBinderLabel, nil)
>       transcript := cipherSuite.hash.New()
> -     transcript.Write(hello.marshalWithoutBinders())
> +     helloBytes, err := hello.marshalWithoutBinders()
> +     if err != nil {
> +             return "", nil, nil, nil, err
> +     }
> +     transcript.Write(helloBytes)
>       pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)}
> -     hello.updateBinders(pskBinders)
> +     if err := hello.updateBinders(pskBinders); err != nil {
> +             return "", nil, nil, nil, err
> +     }
>  
>       return
>  }
> @@ -401,8 +411,12 @@
>               hs.finishedHash.discardHandshakeBuffer()
>       }
>  
> -     hs.finishedHash.Write(hs.hello.marshal())
> -     hs.finishedHash.Write(hs.serverHello.marshal())
> +     if err := transcriptMsg(hs.hello, &hs.finishedHash); err != nil {
> +             return err
> +     }
> +     if err := transcriptMsg(hs.serverHello, &hs.finishedHash); err != nil {
> +             return err
> +     }
>  
>       c.buffering = true
>       c.didResume = isResume
> @@ -473,7 +487,7 @@
>  func (hs *clientHandshakeState) doFullHandshake() error {
>       c := hs.c
>  
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(&hs.finishedHash)
>       if err != nil {
>               return err
>       }
> @@ -482,9 +496,8 @@
>               c.sendAlert(alertUnexpectedMessage)
>               return unexpectedMessageError(certMsg, msg)
>       }
> -     hs.finishedHash.Write(certMsg.marshal())
>  
> -     msg, err = c.readHandshake()
> +     msg, err = c.readHandshake(&hs.finishedHash)
>       if err != nil {
>               return err
>       }
> @@ -502,11 +515,10 @@
>                       c.sendAlert(alertUnexpectedMessage)
>                       return errors.New("tls: received unexpected 
> CertificateStatus message")
>               }
> -             hs.finishedHash.Write(cs.marshal())
>  
>               c.ocspResponse = cs.response
>  
> -             msg, err = c.readHandshake()
> +             msg, err = c.readHandshake(&hs.finishedHash)
>               if err != nil {
>                       return err
>               }
> @@ -535,14 +547,13 @@
>  
>       skx, ok := msg.(*serverKeyExchangeMsg)
>       if ok {
> -             hs.finishedHash.Write(skx.marshal())
>               err = keyAgreement.processServerKeyExchange(c.config, hs.hello, 
> hs.serverHello, c.peerCertificates[0], skx)
>               if err != nil {
>                       c.sendAlert(alertUnexpectedMessage)
>                       return err
>               }
>  
> -             msg, err = c.readHandshake()
> +             msg, err = c.readHandshake(&hs.finishedHash)
>               if err != nil {
>                       return err
>               }
> @@ -553,7 +564,6 @@
>       certReq, ok := msg.(*certificateRequestMsg)
>       if ok {
>               certRequested = true
> -             hs.finishedHash.Write(certReq.marshal())
>  
>               cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
>               if chainToSend, err = c.getClientCertificate(cri); err != nil {
> @@ -561,7 +571,7 @@
>                       return err
>               }
>  
> -             msg, err = c.readHandshake()
> +             msg, err = c.readHandshake(&hs.finishedHash)
>               if err != nil {
>                       return err
>               }
> @@ -572,7 +582,6 @@
>               c.sendAlert(alertUnexpectedMessage)
>               return unexpectedMessageError(shd, msg)
>       }
> -     hs.finishedHash.Write(shd.marshal())
>  
>       // If the server requested a certificate then we have to send a
>       // Certificate message, even if it's empty because we don't have a
> @@ -580,8 +589,7 @@
>       if certRequested {
>               certMsg = new(certificateMsg)
>               certMsg.certificates = chainToSend.Certificate
> -             hs.finishedHash.Write(certMsg.marshal())
> -             if _, err := c.writeRecord(recordTypeHandshake, 
> certMsg.marshal()); err != nil {
> +             if _, err := hs.c.writeHandshakeRecord(certMsg, 
> &hs.finishedHash); err != nil {
>                       return err
>               }
>       }
> @@ -592,8 +600,7 @@
>               return err
>       }
>       if ckx != nil {
> -             hs.finishedHash.Write(ckx.marshal())
> -             if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); 
> err != nil {
> +             if _, err := hs.c.writeHandshakeRecord(ckx, &hs.finishedHash); 
> err != nil {
>                       return err
>               }
>       }
> @@ -640,8 +647,7 @@
>                       return err
>               }
>  
> -             hs.finishedHash.Write(certVerify.marshal())
> -             if _, err := c.writeRecord(recordTypeHandshake, 
> certVerify.marshal()); err != nil {
> +             if _, err := hs.c.writeHandshakeRecord(certVerify, 
> &hs.finishedHash); err != nil {
>                       return err
>               }
>       }
> @@ -776,7 +782,10 @@
>               return err
>       }
>  
> -     msg, err := c.readHandshake()
> +     // finishedMsg is included in the transcript, but not until after we
> +     // check the client version, since the state before this message was
> +     // sent is used during verification.
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -792,7 +801,11 @@
>               c.sendAlert(alertHandshakeFailure)
>               return errors.New("tls: server's Finished message was 
> incorrect")
>       }
> -     hs.finishedHash.Write(serverFinished.marshal())
> +
> +     if err := transcriptMsg(serverFinished, &hs.finishedHash); err != nil {
> +             return err
> +     }
> +
>       copy(out, verify)
>       return nil
>  }
> @@ -803,7 +816,7 @@
>       }
>  
>       c := hs.c
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(&hs.finishedHash)
>       if err != nil {
>               return err
>       }
> @@ -812,7 +825,6 @@
>               c.sendAlert(alertUnexpectedMessage)
>               return unexpectedMessageError(sessionTicketMsg, msg)
>       }
> -     hs.finishedHash.Write(sessionTicketMsg.marshal())
>  
>       hs.session = &ClientSessionState{
>               sessionTicket:      sessionTicketMsg.ticket,
> @@ -832,14 +844,13 @@
>  func (hs *clientHandshakeState) sendFinished(out []byte) error {
>       c := hs.c
>  
> -     if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err 
> != nil {
> +     if err := c.writeChangeCipherRecord(); err != nil {
>               return err
>       }
>  
>       finished := new(finishedMsg)
>       finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
> -     hs.finishedHash.Write(finished.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); 
> err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err 
> != nil {
>               return err
>       }
>       copy(out, finished.verifyData)
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_client_test.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_client_test.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_client_test.go        
> 2023-01-10 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_client_test.go        
> 2023-02-14 01:38:45.000000000 +0800
> @@ -1257,7 +1257,7 @@
>               cipherSuite:  TLS_RSA_WITH_AES_128_GCM_SHA256,
>               alpnProtocol: "how-about-this",
>       }
> -     serverHelloBytes := serverHello.marshal()
> +     serverHelloBytes := mustMarshal(t, serverHello)
>  
>       s.Write([]byte{
>               byte(recordTypeHandshake),
> @@ -1500,7 +1500,7 @@
>               random:      make([]byte, 32),
>               cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384,
>       }
> -     serverHelloBytes := serverHello.marshal()
> +     serverHelloBytes := mustMarshal(t, serverHello)
>  
>       s.Write([]byte{
>               byte(recordTypeHandshake),
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_client_tls13.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_client_tls13.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_client_tls13.go       
> 2023-01-10 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_client_tls13.go       
> 2023-02-14 01:38:45.000000000 +0800
> @@ -62,7 +62,10 @@
>       }
>  
>       hs.transcript = hs.suite.hash.New()
> -     hs.transcript.Write(hs.hello.marshal())
> +
> +     if err := transcriptMsg(hs.hello, hs.transcript); err != nil {
> +             return err
> +     }
>  
>       if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
>               if err := hs.sendDummyChangeCipherSpec(); err != nil {
> @@ -73,7 +76,9 @@
>               }
>       }
>  
> -     hs.transcript.Write(hs.serverHello.marshal())
> +     if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
> +             return err
> +     }
>  
>       c.buffering = true
>       if err := hs.processServerHello(); err != nil {
> @@ -172,8 +177,7 @@
>       }
>       hs.sentDummyCCS = true
>  
> -     _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
> -     return err
> +     return hs.c.writeChangeCipherRecord()
>  }
>  
>  // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
> @@ -188,7 +192,9 @@
>       hs.transcript.Reset()
>       hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
>       hs.transcript.Write(chHash)
> -     hs.transcript.Write(hs.serverHello.marshal())
> +     if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
> +             return err
> +     }
>  
>       // The only HelloRetryRequest extensions we support are key_share and
>       // cookie, and clients must abort the handshake if the HRR would not 
> result
> @@ -253,10 +259,18 @@
>                       transcript := hs.suite.hash.New()
>                       transcript.Write([]byte{typeMessageHash, 0, 0, 
> uint8(len(chHash))})
>                       transcript.Write(chHash)
> -                     transcript.Write(hs.serverHello.marshal())
> -                     transcript.Write(hs.hello.marshalWithoutBinders())
> +                     if err := transcriptMsg(hs.serverHello, hs.transcript); 
> err != nil {
> +                             return err
> +                     }
> +                     helloBytes, err := hs.hello.marshalWithoutBinders()
> +                     if err != nil {
> +                             return err
> +                     }
> +                     transcript.Write(helloBytes)
>                       pskBinders := 
> [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
> -                     hs.hello.updateBinders(pskBinders)
> +                     if err := hs.hello.updateBinders(pskBinders); err != 
> nil {
> +                             return err
> +                     }
>               } else {
>                       // Server selected a cipher suite incompatible with the 
> PSK.
>                       hs.hello.pskIdentities = nil
> @@ -264,12 +278,12 @@
>               }
>       }
>  
> -     hs.transcript.Write(hs.hello.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); 
> err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != 
> nil {
>               return err
>       }
>  
> -     msg, err := c.readHandshake()
> +     // serverHelloMsg is not included in the transcript
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -358,6 +372,7 @@
>       if !hs.usingPSK {
>               earlySecret = hs.suite.extract(nil, nil)
>       }
> +
>       handshakeSecret := hs.suite.extract(sharedKey,
>               hs.suite.deriveSecret(earlySecret, "derived", nil))
>  
> @@ -388,7 +403,7 @@
>  func (hs *clientHandshakeStateTLS13) readServerParameters() error {
>       c := hs.c
>  
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(hs.transcript)
>       if err != nil {
>               return err
>       }
> @@ -398,7 +413,6 @@
>               c.sendAlert(alertUnexpectedMessage)
>               return unexpectedMessageError(encryptedExtensions, msg)
>       }
> -     hs.transcript.Write(encryptedExtensions.marshal())
>  
>       if err := checkALPN(hs.hello.alpnProtocols, 
> encryptedExtensions.alpnProtocol); err != nil {
>               c.sendAlert(alertUnsupportedExtension)
> @@ -427,18 +441,16 @@
>               return nil
>       }
>  
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(hs.transcript)
>       if err != nil {
>               return err
>       }
>  
>       certReq, ok := msg.(*certificateRequestMsgTLS13)
>       if ok {
> -             hs.transcript.Write(certReq.marshal())
> -
>               hs.certReq = certReq
>  
> -             msg, err = c.readHandshake()
> +             msg, err = c.readHandshake(hs.transcript)
>               if err != nil {
>                       return err
>               }
> @@ -453,7 +465,6 @@
>               c.sendAlert(alertDecodeError)
>               return errors.New("tls: received empty certificates message")
>       }
> -     hs.transcript.Write(certMsg.marshal())
>  
>       c.scts = certMsg.certificate.SignedCertificateTimestamps
>       c.ocspResponse = certMsg.certificate.OCSPStaple
> @@ -462,7 +473,10 @@
>               return err
>       }
>  
> -     msg, err = c.readHandshake()
> +     // certificateVerifyMsg is included in the transcript, but not until
> +     // after we verify the handshake signature, since the state before
> +     // this message was sent is used.
> +     msg, err = c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -493,7 +507,9 @@
>               return errors.New("tls: invalid signature by the server 
> certificate: " + err.Error())
>       }
>  
> -     hs.transcript.Write(certVerify.marshal())
> +     if err := transcriptMsg(certVerify, hs.transcript); err != nil {
> +             return err
> +     }
>  
>       return nil
>  }
> @@ -501,7 +517,10 @@
>  func (hs *clientHandshakeStateTLS13) readServerFinished() error {
>       c := hs.c
>  
> -     msg, err := c.readHandshake()
> +     // finishedMsg is included in the transcript, but not until after we
> +     // check the client version, since the state before this message was
> +     // sent is used during verification.
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -518,7 +537,9 @@
>               return errors.New("tls: invalid server finished hash")
>       }
>  
> -     hs.transcript.Write(finished.marshal())
> +     if err := transcriptMsg(finished, hs.transcript); err != nil {
> +             return err
> +     }
>  
>       // Derive secrets that take context through the server Finished.
>  
> @@ -567,8 +588,7 @@
>       certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) 
> > 0
>       certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) 
> > 0
>  
> -     hs.transcript.Write(certMsg.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err 
> != nil {
> +     if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != 
> nil {
>               return err
>       }
>  
> @@ -605,8 +625,7 @@
>       }
>       certVerifyMsg.signature = sig
>  
> -     hs.transcript.Write(certVerifyMsg.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, 
> certVerifyMsg.marshal()); err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); 
> err != nil {
>               return err
>       }
>  
> @@ -620,8 +639,7 @@
>               verifyData: hs.suite.finishedHash(c.out.trafficSecret, 
> hs.transcript),
>       }
>  
> -     hs.transcript.Write(finished.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); 
> err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != 
> nil {
>               return err
>       }
>  
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_messages.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_messages.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_messages.go   2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_messages.go   2023-02-14 
> 01:38:45.000000000 +0800
> @@ -5,6 +5,7 @@
>  package tls
>  
>  import (
> +     "errors"
>       "fmt"
>       "strings"
>  
> @@ -94,9 +95,181 @@
>       pskBinders                       [][]byte
>  }
>  
> -func (m *clientHelloMsg) marshal() []byte {
> +func (m *clientHelloMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
> +     }
> +
> +     var exts cryptobyte.Builder
> +     if len(m.serverName) > 0 {
> +             // RFC 6066, Section 3
> +             exts.AddUint16(extensionServerName)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddUint8(0) // name_type = host_name
> +                             exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                                     exts.AddBytes([]byte(m.serverName))
> +                             })
> +                     })
> +             })
> +     }
> +     if m.ocspStapling {
> +             // RFC 4366, Section 3.6
> +             exts.AddUint16(extensionStatusRequest)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint8(1)  // status_type = ocsp
> +                     exts.AddUint16(0) // empty responder_id_list
> +                     exts.AddUint16(0) // empty request_extensions
> +             })
> +     }
> +     if len(m.supportedCurves) > 0 {
> +             // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
> +             exts.AddUint16(extensionSupportedCurves)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, curve := range m.supportedCurves {
> +                                     exts.AddUint16(uint16(curve))
> +                             }
> +                     })
> +             })
> +     }
> +     if len(m.supportedPoints) > 0 {
> +             // RFC 4492, Section 5.1.2
> +             exts.AddUint16(extensionSupportedPoints)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.supportedPoints)
> +                     })
> +             })
> +     }
> +     if m.ticketSupported {
> +             // RFC 5077, Section 3.2
> +             exts.AddUint16(extensionSessionTicket)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddBytes(m.sessionTicket)
> +             })
> +     }
> +     if len(m.supportedSignatureAlgorithms) > 0 {
> +             // RFC 5246, Section 7.4.1.4.1
> +             exts.AddUint16(extensionSignatureAlgorithms)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, sigAlgo := range 
> m.supportedSignatureAlgorithms {
> +                                     exts.AddUint16(uint16(sigAlgo))
> +                             }
> +                     })
> +             })
> +     }
> +     if len(m.supportedSignatureAlgorithmsCert) > 0 {
> +             // RFC 8446, Section 4.2.3
> +             exts.AddUint16(extensionSignatureAlgorithmsCert)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, sigAlgo := range 
> m.supportedSignatureAlgorithmsCert {
> +                                     exts.AddUint16(uint16(sigAlgo))
> +                             }
> +                     })
> +             })
> +     }
> +     if m.secureRenegotiationSupported {
> +             // RFC 5746, Section 3.2
> +             exts.AddUint16(extensionRenegotiationInfo)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.secureRenegotiation)
> +                     })
> +             })
> +     }
> +     if len(m.alpnProtocols) > 0 {
> +             // RFC 7301, Section 3.1
> +             exts.AddUint16(extensionALPN)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, proto := range m.alpnProtocols {
> +                                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                                             exts.AddBytes([]byte(proto))
> +                                     })
> +                             }
> +                     })
> +             })
> +     }
> +     if m.scts {
> +             // RFC 6962, Section 3.3.1
> +             exts.AddUint16(extensionSCT)
> +             exts.AddUint16(0) // empty extension_data
> +     }
> +     if len(m.supportedVersions) > 0 {
> +             // RFC 8446, Section 4.2.1
> +             exts.AddUint16(extensionSupportedVersions)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, vers := range m.supportedVersions {
> +                                     exts.AddUint16(vers)
> +                             }
> +                     })
> +             })
> +     }
> +     if len(m.cookie) > 0 {
> +             // RFC 8446, Section 4.2.2
> +             exts.AddUint16(extensionCookie)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.cookie)
> +                     })
> +             })
> +     }
> +     if len(m.keyShares) > 0 {
> +             // RFC 8446, Section 4.2.8
> +             exts.AddUint16(extensionKeyShare)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, ks := range m.keyShares {
> +                                     exts.AddUint16(uint16(ks.group))
> +                                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                                             exts.AddBytes(ks.data)
> +                                     })
> +                             }
> +                     })
> +             })
> +     }
> +     if m.earlyData {
> +             // RFC 8446, Section 4.2.10
> +             exts.AddUint16(extensionEarlyData)
> +             exts.AddUint16(0) // empty extension_data
> +     }
> +     if len(m.pskModes) > 0 {
> +             // RFC 8446, Section 4.2.9
> +             exts.AddUint16(extensionPSKModes)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.pskModes)
> +                     })
> +             })
> +     }
> +     if len(m.pskIdentities) > 0 { // pre_shared_key must be the last 
> extension
> +             // RFC 8446, Section 4.2.11
> +             exts.AddUint16(extensionPreSharedKey)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, psk := range m.pskIdentities {
> +                                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                                             exts.AddBytes(psk.label)
> +                                     })
> +                                     exts.AddUint32(psk.obfuscatedTicketAge)
> +                             }
> +                     })
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, binder := range m.pskBinders {
> +                                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                                             exts.AddBytes(binder)
> +                                     })
> +                             }
> +                     })
> +             })
> +     }
> +     extBytes, err := exts.Bytes()
> +     if err != nil {
> +             return nil, err
>       }
>  
>       var b cryptobyte.Builder
> @@ -116,219 +289,53 @@
>                       b.AddBytes(m.compressionMethods)
>               })
>  
> -             // If extensions aren't present, omit them.
> -             var extensionsPresent bool
> -             bWithoutExtensions := *b
> -
> -             b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> -                     if len(m.serverName) > 0 {
> -                             // RFC 6066, Section 3
> -                             b.AddUint16(extensionServerName)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddUint8(0) // name_type = 
> host_name
> -                                             
> b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> -                                                     
> b.AddBytes([]byte(m.serverName))
> -                                             })
> -                                     })
> -                             })
> -                     }
> -                     if m.ocspStapling {
> -                             // RFC 4366, Section 3.6
> -                             b.AddUint16(extensionStatusRequest)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint8(1)  // status_type = ocsp
> -                                     b.AddUint16(0) // empty 
> responder_id_list
> -                                     b.AddUint16(0) // empty 
> request_extensions
> -                             })
> -                     }
> -                     if len(m.supportedCurves) > 0 {
> -                             // RFC 4492, sections 5.1.1 and RFC 8446, 
> Section 4.2.7
> -                             b.AddUint16(extensionSupportedCurves)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, curve := range 
> m.supportedCurves {
> -                                                     
> b.AddUint16(uint16(curve))
> -                                             }
> -                                     })
> -                             })
> -                     }
> -                     if len(m.supportedPoints) > 0 {
> -                             // RFC 4492, Section 5.1.2
> -                             b.AddUint16(extensionSupportedPoints)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint8LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddBytes(m.supportedPoints)
> -                                     })
> -                             })
> -                     }
> -                     if m.ticketSupported {
> -                             // RFC 5077, Section 3.2
> -                             b.AddUint16(extensionSessionTicket)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddBytes(m.sessionTicket)
> -                             })
> -                     }
> -                     if len(m.supportedSignatureAlgorithms) > 0 {
> -                             // RFC 5246, Section 7.4.1.4.1
> -                             b.AddUint16(extensionSignatureAlgorithms)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, sigAlgo := range 
> m.supportedSignatureAlgorithms {
> -                                                     
> b.AddUint16(uint16(sigAlgo))
> -                                             }
> -                                     })
> -                             })
> -                     }
> -                     if len(m.supportedSignatureAlgorithmsCert) > 0 {
> -                             // RFC 8446, Section 4.2.3
> -                             b.AddUint16(extensionSignatureAlgorithmsCert)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, sigAlgo := range 
> m.supportedSignatureAlgorithmsCert {
> -                                                     
> b.AddUint16(uint16(sigAlgo))
> -                                             }
> -                                     })
> -                             })
> -                     }
> -                     if m.secureRenegotiationSupported {
> -                             // RFC 5746, Section 3.2
> -                             b.AddUint16(extensionRenegotiationInfo)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint8LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             
> b.AddBytes(m.secureRenegotiation)
> -                                     })
> -                             })
> -                     }
> -                     if len(m.alpnProtocols) > 0 {
> -                             // RFC 7301, Section 3.1
> -                             b.AddUint16(extensionALPN)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, proto := range 
> m.alpnProtocols {
> -                                                     
> b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
> -                                                             
> b.AddBytes([]byte(proto))
> -                                                     })
> -                                             }
> -                                     })
> -                             })
> -                     }
> -                     if m.scts {
> -                             // RFC 6962, Section 3.3.1
> -                             b.AddUint16(extensionSCT)
> -                             b.AddUint16(0) // empty extension_data
> -                     }
> -                     if len(m.supportedVersions) > 0 {
> -                             // RFC 8446, Section 4.2.1
> -                             b.AddUint16(extensionSupportedVersions)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint8LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, vers := range 
> m.supportedVersions {
> -                                                     b.AddUint16(vers)
> -                                             }
> -                                     })
> -                             })
> -                     }
> -                     if len(m.cookie) > 0 {
> -                             // RFC 8446, Section 4.2.2
> -                             b.AddUint16(extensionCookie)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddBytes(m.cookie)
> -                                     })
> -                             })
> -                     }
> -                     if len(m.keyShares) > 0 {
> -                             // RFC 8446, Section 4.2.8
> -                             b.AddUint16(extensionKeyShare)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, ks := range m.keyShares {
> -                                                     
> b.AddUint16(uint16(ks.group))
> -                                                     
> b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> -                                                             
> b.AddBytes(ks.data)
> -                                                     })
> -                                             }
> -                                     })
> -                             })
> -                     }
> -                     if m.earlyData {
> -                             // RFC 8446, Section 4.2.10
> -                             b.AddUint16(extensionEarlyData)
> -                             b.AddUint16(0) // empty extension_data
> -                     }
> -                     if len(m.pskModes) > 0 {
> -                             // RFC 8446, Section 4.2.9
> -                             b.AddUint16(extensionPSKModes)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint8LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddBytes(m.pskModes)
> -                                     })
> -                             })
> -                     }
> -                     if len(m.pskIdentities) > 0 { // pre_shared_key must be 
> the last extension
> -                             // RFC 8446, Section 4.2.11
> -                             b.AddUint16(extensionPreSharedKey)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, psk := range 
> m.pskIdentities {
> -                                                     
> b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> -                                                             
> b.AddBytes(psk.label)
> -                                                     })
> -                                                     
> b.AddUint32(psk.obfuscatedTicketAge)
> -                                             }
> -                                     })
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, binder := range 
> m.pskBinders {
> -                                                     
> b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
> -                                                             
> b.AddBytes(binder)
> -                                                     })
> -                                             }
> -                                     })
> -                             })
> -                     }
> -
> -                     extensionsPresent = len(b.BytesOrPanic()) > 2
> -             })
> -
> -             if !extensionsPresent {
> -                     *b = bWithoutExtensions
> +             if len(extBytes) > 0 {
> +                     b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> +                             b.AddBytes(extBytes)
> +                     })
>               }
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  // marshalWithoutBinders returns the ClientHello through the
>  // PreSharedKeyExtension.identities field, according to RFC 8446, Section
>  // 4.2.11.2. Note that m.pskBinders must be set to slices of the correct 
> length.
> -func (m *clientHelloMsg) marshalWithoutBinders() []byte {
> +func (m *clientHelloMsg) marshalWithoutBinders() ([]byte, error) {
>       bindersLen := 2 // uint16 length prefix
>       for _, binder := range m.pskBinders {
>               bindersLen += 1 // uint8 length prefix
>               bindersLen += len(binder)
>       }
>  
> -     fullMessage := m.marshal()
> -     return fullMessage[:len(fullMessage)-bindersLen]
> +     fullMessage, err := m.marshal()
> +     if err != nil {
> +             return nil, err
> +     }
> +     return fullMessage[:len(fullMessage)-bindersLen], nil
>  }
>  
>  // updateBinders updates the m.pskBinders field, if necessary updating the
>  // cached marshaled representation. The supplied binders must have the same
>  // length as the current m.pskBinders.
> -func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {
> +func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) error {
>       if len(pskBinders) != len(m.pskBinders) {
> -             panic("tls: internal error: pskBinders length mismatch")
> +             return errors.New("tls: internal error: pskBinders length 
> mismatch")
>       }
>       for i := range m.pskBinders {
>               if len(pskBinders[i]) != len(m.pskBinders[i]) {
> -                     panic("tls: internal error: pskBinders length mismatch")
> +                     return errors.New("tls: internal error: pskBinders 
> length mismatch")
>               }
>       }
>       m.pskBinders = pskBinders
>       if m.raw != nil {
> -             lenWithoutBinders := len(m.marshalWithoutBinders())
> +             helloBytes, err := m.marshalWithoutBinders()
> +             if err != nil {
> +                     return err
> +             }
> +             lenWithoutBinders := len(helloBytes)
>               b := cryptobyte.NewFixedBuilder(m.raw[:lenWithoutBinders])
>               b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
>                       for _, binder := range m.pskBinders {
> @@ -338,9 +345,11 @@
>                       }
>               })
>               if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
> -                     panic("tls: internal error: failed to update binders")
> +                     return errors.New("tls: internal error: failed to 
> update binders")
>               }
>       }
> +
> +     return nil
>  }
>  
>  func (m *clientHelloMsg) unmarshal(data []byte) bool {
> @@ -618,9 +627,98 @@
>       selectedGroup CurveID
>  }
>  
> -func (m *serverHelloMsg) marshal() []byte {
> +func (m *serverHelloMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
> +     }
> +
> +     var exts cryptobyte.Builder
> +     if m.ocspStapling {
> +             exts.AddUint16(extensionStatusRequest)
> +             exts.AddUint16(0) // empty extension_data
> +     }
> +     if m.ticketSupported {
> +             exts.AddUint16(extensionSessionTicket)
> +             exts.AddUint16(0) // empty extension_data
> +     }
> +     if m.secureRenegotiationSupported {
> +             exts.AddUint16(extensionRenegotiationInfo)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.secureRenegotiation)
> +                     })
> +             })
> +     }
> +     if len(m.alpnProtocol) > 0 {
> +             exts.AddUint16(extensionALPN)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                                     exts.AddBytes([]byte(m.alpnProtocol))
> +                             })
> +                     })
> +             })
> +     }
> +     if len(m.scts) > 0 {
> +             exts.AddUint16(extensionSCT)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             for _, sct := range m.scts {
> +                                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                                             exts.AddBytes(sct)
> +                                     })
> +                             }
> +                     })
> +             })
> +     }
> +     if m.supportedVersion != 0 {
> +             exts.AddUint16(extensionSupportedVersions)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16(m.supportedVersion)
> +             })
> +     }
> +     if m.serverShare.group != 0 {
> +             exts.AddUint16(extensionKeyShare)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16(uint16(m.serverShare.group))
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.serverShare.data)
> +                     })
> +             })
> +     }
> +     if m.selectedIdentityPresent {
> +             exts.AddUint16(extensionPreSharedKey)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16(m.selectedIdentity)
> +             })
> +     }
> +
> +     if len(m.cookie) > 0 {
> +             exts.AddUint16(extensionCookie)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.cookie)
> +                     })
> +             })
> +     }
> +     if m.selectedGroup != 0 {
> +             exts.AddUint16(extensionKeyShare)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint16(uint16(m.selectedGroup))
> +             })
> +     }
> +     if len(m.supportedPoints) > 0 {
> +             exts.AddUint16(extensionSupportedPoints)
> +             exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
> +                     exts.AddUint8LengthPrefixed(func(exts 
> *cryptobyte.Builder) {
> +                             exts.AddBytes(m.supportedPoints)
> +                     })
> +             })
> +     }
> +
> +     extBytes, err := exts.Bytes()
> +     if err != nil {
> +             return nil, err
>       }
>  
>       var b cryptobyte.Builder
> @@ -634,104 +732,15 @@
>               b.AddUint16(m.cipherSuite)
>               b.AddUint8(m.compressionMethod)
>  
> -             // If extensions aren't present, omit them.
> -             var extensionsPresent bool
> -             bWithoutExtensions := *b
> -
> -             b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> -                     if m.ocspStapling {
> -                             b.AddUint16(extensionStatusRequest)
> -                             b.AddUint16(0) // empty extension_data
> -                     }
> -                     if m.ticketSupported {
> -                             b.AddUint16(extensionSessionTicket)
> -                             b.AddUint16(0) // empty extension_data
> -                     }
> -                     if m.secureRenegotiationSupported {
> -                             b.AddUint16(extensionRenegotiationInfo)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint8LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             
> b.AddBytes(m.secureRenegotiation)
> -                                     })
> -                             })
> -                     }
> -                     if len(m.alpnProtocol) > 0 {
> -                             b.AddUint16(extensionALPN)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddUint8LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                                     
> b.AddBytes([]byte(m.alpnProtocol))
> -                                             })
> -                                     })
> -                             })
> -                     }
> -                     if len(m.scts) > 0 {
> -                             b.AddUint16(extensionSCT)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             for _, sct := range m.scts {
> -                                                     
> b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> -                                                             b.AddBytes(sct)
> -                                                     })
> -                                             }
> -                                     })
> -                             })
> -                     }
> -                     if m.supportedVersion != 0 {
> -                             b.AddUint16(extensionSupportedVersions)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16(m.supportedVersion)
> -                             })
> -                     }
> -                     if m.serverShare.group != 0 {
> -                             b.AddUint16(extensionKeyShare)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16(uint16(m.serverShare.group))
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddBytes(m.serverShare.data)
> -                                     })
> -                             })
> -                     }
> -                     if m.selectedIdentityPresent {
> -                             b.AddUint16(extensionPreSharedKey)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16(m.selectedIdentity)
> -                             })
> -                     }
> -
> -                     if len(m.cookie) > 0 {
> -                             b.AddUint16(extensionCookie)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddBytes(m.cookie)
> -                                     })
> -                             })
> -                     }
> -                     if m.selectedGroup != 0 {
> -                             b.AddUint16(extensionKeyShare)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint16(uint16(m.selectedGroup))
> -                             })
> -                     }
> -                     if len(m.supportedPoints) > 0 {
> -                             b.AddUint16(extensionSupportedPoints)
> -                             b.AddUint16LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                     b.AddUint8LengthPrefixed(func(b 
> *cryptobyte.Builder) {
> -                                             b.AddBytes(m.supportedPoints)
> -                                     })
> -                             })
> -                     }
> -
> -                     extensionsPresent = len(b.BytesOrPanic()) > 2
> -             })
> -
> -             if !extensionsPresent {
> -                     *b = bWithoutExtensions
> +             if len(extBytes) > 0 {
> +                     b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
> +                             b.AddBytes(extBytes)
> +                     })
>               }
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *serverHelloMsg) unmarshal(data []byte) bool {
> @@ -855,9 +864,9 @@
>       alpnProtocol string
>  }
>  
> -func (m *encryptedExtensionsMsg) marshal() []byte {
> +func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -877,8 +886,9 @@
>               })
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
> @@ -926,10 +936,10 @@
>  
>  type endOfEarlyDataMsg struct{}
>  
> -func (m *endOfEarlyDataMsg) marshal() []byte {
> +func (m *endOfEarlyDataMsg) marshal() ([]byte, error) {
>       x := make([]byte, 4)
>       x[0] = typeEndOfEarlyData
> -     return x
> +     return x, nil
>  }
>  
>  func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
> @@ -941,9 +951,9 @@
>       updateRequested bool
>  }
>  
> -func (m *keyUpdateMsg) marshal() []byte {
> +func (m *keyUpdateMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -956,8 +966,9 @@
>               }
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *keyUpdateMsg) unmarshal(data []byte) bool {
> @@ -989,9 +1000,9 @@
>       maxEarlyData uint32
>  }
>  
> -func (m *newSessionTicketMsgTLS13) marshal() []byte {
> +func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -1016,8 +1027,9 @@
>               })
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
> @@ -1070,9 +1082,9 @@
>       certificateAuthorities           [][]byte
>  }
>  
> -func (m *certificateRequestMsgTLS13) marshal() []byte {
> +func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -1131,8 +1143,9 @@
>               })
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
> @@ -1216,9 +1229,9 @@
>       certificates [][]byte
>  }
>  
> -func (m *certificateMsg) marshal() (x []byte) {
> +func (m *certificateMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var i int
> @@ -1227,7 +1240,7 @@
>       }
>  
>       length := 3 + 3*len(m.certificates) + i
> -     x = make([]byte, 4+length)
> +     x := make([]byte, 4+length)
>       x[0] = typeCertificate
>       x[1] = uint8(length >> 16)
>       x[2] = uint8(length >> 8)
> @@ -1248,7 +1261,7 @@
>       }
>  
>       m.raw = x
> -     return
> +     return m.raw, nil
>  }
>  
>  func (m *certificateMsg) unmarshal(data []byte) bool {
> @@ -1295,9 +1308,9 @@
>       scts         bool
>  }
>  
> -func (m *certificateMsgTLS13) marshal() []byte {
> +func (m *certificateMsgTLS13) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -1315,8 +1328,9 @@
>               marshalCertificate(b, certificate)
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
> @@ -1439,9 +1453,9 @@
>       key []byte
>  }
>  
> -func (m *serverKeyExchangeMsg) marshal() []byte {
> +func (m *serverKeyExchangeMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>       length := len(m.key)
>       x := make([]byte, length+4)
> @@ -1452,7 +1466,7 @@
>       copy(x[4:], m.key)
>  
>       m.raw = x
> -     return x
> +     return x, nil
>  }
>  
>  func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
> @@ -1469,9 +1483,9 @@
>       response []byte
>  }
>  
> -func (m *certificateStatusMsg) marshal() []byte {
> +func (m *certificateStatusMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -1483,8 +1497,9 @@
>               })
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *certificateStatusMsg) unmarshal(data []byte) bool {
> @@ -1503,10 +1518,10 @@
>  
>  type serverHelloDoneMsg struct{}
>  
> -func (m *serverHelloDoneMsg) marshal() []byte {
> +func (m *serverHelloDoneMsg) marshal() ([]byte, error) {
>       x := make([]byte, 4)
>       x[0] = typeServerHelloDone
> -     return x
> +     return x, nil
>  }
>  
>  func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
> @@ -1518,9 +1533,9 @@
>       ciphertext []byte
>  }
>  
> -func (m *clientKeyExchangeMsg) marshal() []byte {
> +func (m *clientKeyExchangeMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>       length := len(m.ciphertext)
>       x := make([]byte, length+4)
> @@ -1531,7 +1546,7 @@
>       copy(x[4:], m.ciphertext)
>  
>       m.raw = x
> -     return x
> +     return x, nil
>  }
>  
>  func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
> @@ -1552,9 +1567,9 @@
>       verifyData []byte
>  }
>  
> -func (m *finishedMsg) marshal() []byte {
> +func (m *finishedMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -1563,8 +1578,9 @@
>               b.AddBytes(m.verifyData)
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *finishedMsg) unmarshal(data []byte) bool {
> @@ -1586,9 +1602,9 @@
>       certificateAuthorities       [][]byte
>  }
>  
> -func (m *certificateRequestMsg) marshal() (x []byte) {
> +func (m *certificateRequestMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       // See RFC 4346, Section 7.4.4.
> @@ -1603,7 +1619,7 @@
>               length += 2 + 2*len(m.supportedSignatureAlgorithms)
>       }
>  
> -     x = make([]byte, 4+length)
> +     x := make([]byte, 4+length)
>       x[0] = typeCertificateRequest
>       x[1] = uint8(length >> 16)
>       x[2] = uint8(length >> 8)
> @@ -1638,7 +1654,7 @@
>       }
>  
>       m.raw = x
> -     return
> +     return m.raw, nil
>  }
>  
>  func (m *certificateRequestMsg) unmarshal(data []byte) bool {
> @@ -1724,9 +1740,9 @@
>       signature             []byte
>  }
>  
> -func (m *certificateVerifyMsg) marshal() (x []byte) {
> +func (m *certificateVerifyMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       var b cryptobyte.Builder
> @@ -1740,8 +1756,9 @@
>               })
>       })
>  
> -     m.raw = b.BytesOrPanic()
> -     return m.raw
> +     var err error
> +     m.raw, err = b.Bytes()
> +     return m.raw, err
>  }
>  
>  func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
> @@ -1764,15 +1781,15 @@
>       ticket []byte
>  }
>  
> -func (m *newSessionTicketMsg) marshal() (x []byte) {
> +func (m *newSessionTicketMsg) marshal() ([]byte, error) {
>       if m.raw != nil {
> -             return m.raw
> +             return m.raw, nil
>       }
>  
>       // See RFC 5077, Section 3.3.
>       ticketLen := len(m.ticket)
>       length := 2 + 4 + ticketLen
> -     x = make([]byte, 4+length)
> +     x := make([]byte, 4+length)
>       x[0] = typeNewSessionTicket
>       x[1] = uint8(length >> 16)
>       x[2] = uint8(length >> 8)
> @@ -1783,7 +1800,7 @@
>  
>       m.raw = x
>  
> -     return
> +     return m.raw, nil
>  }
>  
>  func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
> @@ -1811,10 +1828,25 @@
>  type helloRequestMsg struct {
>  }
>  
> -func (*helloRequestMsg) marshal() []byte {
> -     return []byte{typeHelloRequest, 0, 0, 0}
> +func (*helloRequestMsg) marshal() ([]byte, error) {
> +     return []byte{typeHelloRequest, 0, 0, 0}, nil
>  }
>  
>  func (*helloRequestMsg) unmarshal(data []byte) bool {
>       return len(data) == 4
>  }
> +
> +type transcriptHash interface {
> +     Write([]byte) (int, error)
> +}
> +
> +// transcriptMsg is a helper used to marshal and hash messages which 
> typically
> +// are not written to the wire, and as such aren't hashed during 
> Conn.writeRecord.
> +func transcriptMsg(msg handshakeMessage, h transcriptHash) error {
> +     data, err := msg.marshal()
> +     if err != nil {
> +             return err
> +     }
> +     h.Write(data)
> +     return nil
> +}
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_messages_test.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_messages_test.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_messages_test.go      
> 2023-01-10 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_messages_test.go      
> 2023-02-14 01:38:45.000000000 +0800
> @@ -38,6 +38,15 @@
>       &certificateMsgTLS13{},
>  }
>  
> +func mustMarshal(t *testing.T, msg handshakeMessage) []byte {
> +     t.Helper()
> +     b, err := msg.marshal()
> +     if err != nil {
> +             t.Fatal(err)
> +     }
> +     return b
> +}
> +
>  func TestMarshalUnmarshal(t *testing.T) {
>       rand := rand.New(rand.NewSource(time.Now().UnixNano()))
>  
> @@ -56,7 +65,7 @@
>                       }
>  
>                       m1 := v.Interface().(handshakeMessage)
> -                     marshaled := m1.marshal()
> +                     marshaled := mustMarshal(t, m1)
>                       m2 := iface.(handshakeMessage)
>                       if !m2.unmarshal(marshaled) {
>                               t.Errorf("#%d failed to unmarshal %#v %x", i, 
> m1, marshaled)
> @@ -409,12 +418,12 @@
>  
>       var random [32]byte
>       sct := []byte{0x42, 0x42, 0x42, 0x42}
> -     serverHello := serverHelloMsg{
> +     serverHello := &serverHelloMsg{
>               vers:   VersionTLS12,
>               random: random[:],
>               scts:   [][]byte{sct},
>       }
> -     serverHelloBytes := serverHello.marshal()
> +     serverHelloBytes := mustMarshal(t, serverHello)
>  
>       var serverHelloCopy serverHelloMsg
>       if !serverHelloCopy.unmarshal(serverHelloBytes) {
> @@ -452,12 +461,12 @@
>       // not be zero length.
>  
>       var random [32]byte
> -     serverHello := serverHelloMsg{
> +     serverHello := &serverHelloMsg{
>               vers:   VersionTLS12,
>               random: random[:],
>               scts:   [][]byte{nil},
>       }
> -     serverHelloBytes := serverHello.marshal()
> +     serverHelloBytes := mustMarshal(t, serverHello)
>  
>       var serverHelloCopy serverHelloMsg
>       if serverHelloCopy.unmarshal(serverHelloBytes) {
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_server.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_server.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_server.go     2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_server.go     2023-02-14 
> 01:38:45.000000000 +0800
> @@ -129,7 +129,9 @@
>  
>  // readClientHello reads a ClientHello message and selects the protocol 
> version.
>  func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) 
> {
> -     msg, err := c.readHandshake()
> +     // clientHelloMsg is included in the transcript, but we haven't 
> initialized
> +     // it yet. The respective handshake functions will record it themselves.
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return nil, err
>       }
> @@ -463,9 +465,10 @@
>       hs.hello.ticketSupported = hs.sessionState.usedOldKey
>       hs.finishedHash = newFinishedHash(c.vers, hs.suite)
>       hs.finishedHash.discardHandshakeBuffer()
> -     hs.finishedHash.Write(hs.clientHello.marshal())
> -     hs.finishedHash.Write(hs.hello.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); 
> err != nil {
> +     if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
> +             return err
> +     }
> +     if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err 
> != nil {
>               return err
>       }
>  
> @@ -503,24 +506,23 @@
>               // certificates won't be used.
>               hs.finishedHash.discardHandshakeBuffer()
>       }
> -     hs.finishedHash.Write(hs.clientHello.marshal())
> -     hs.finishedHash.Write(hs.hello.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); 
> err != nil {
> +     if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
> +             return err
> +     }
> +     if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err 
> != nil {
>               return err
>       }
>  
>       certMsg := new(certificateMsg)
>       certMsg.certificates = hs.cert.Certificate
> -     hs.finishedHash.Write(certMsg.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err 
> != nil {
> +     if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err 
> != nil {
>               return err
>       }
>  
>       if hs.hello.ocspStapling {
>               certStatus := new(certificateStatusMsg)
>               certStatus.response = hs.cert.OCSPStaple
> -             hs.finishedHash.Write(certStatus.marshal())
> -             if _, err := c.writeRecord(recordTypeHandshake, 
> certStatus.marshal()); err != nil {
> +             if _, err := hs.c.writeHandshakeRecord(certStatus, 
> &hs.finishedHash); err != nil {
>                       return err
>               }
>       }
> @@ -532,8 +534,7 @@
>               return err
>       }
>       if skx != nil {
> -             hs.finishedHash.Write(skx.marshal())
> -             if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); 
> err != nil {
> +             if _, err := hs.c.writeHandshakeRecord(skx, &hs.finishedHash); 
> err != nil {
>                       return err
>               }
>       }
> @@ -559,15 +560,13 @@
>               if c.config.ClientCAs != nil {
>                       certReq.certificateAuthorities = 
> c.config.ClientCAs.Subjects()
>               }
> -             hs.finishedHash.Write(certReq.marshal())
> -             if _, err := c.writeRecord(recordTypeHandshake, 
> certReq.marshal()); err != nil {
> +             if _, err := hs.c.writeHandshakeRecord(certReq, 
> &hs.finishedHash); err != nil {
>                       return err
>               }
>       }
>  
>       helloDone := new(serverHelloDoneMsg)
> -     hs.finishedHash.Write(helloDone.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); 
> err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(helloDone, &hs.finishedHash); 
> err != nil {
>               return err
>       }
>  
> @@ -577,7 +576,7 @@
>  
>       var pub crypto.PublicKey // public key for client auth, if any
>  
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(&hs.finishedHash)
>       if err != nil {
>               return err
>       }
> @@ -590,7 +589,6 @@
>                       c.sendAlert(alertUnexpectedMessage)
>                       return unexpectedMessageError(certMsg, msg)
>               }
> -             hs.finishedHash.Write(certMsg.marshal())
>  
>               if err := c.processCertsFromClient(Certificate{
>                       Certificate: certMsg.certificates,
> @@ -601,7 +599,7 @@
>                       pub = c.peerCertificates[0].PublicKey
>               }
>  
> -             msg, err = c.readHandshake()
> +             msg, err = c.readHandshake(&hs.finishedHash)
>               if err != nil {
>                       return err
>               }
> @@ -619,7 +617,6 @@
>               c.sendAlert(alertUnexpectedMessage)
>               return unexpectedMessageError(ckx, msg)
>       }
> -     hs.finishedHash.Write(ckx.marshal())
>  
>       preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, 
> hs.cert, ckx, c.vers)
>       if err != nil {
> @@ -639,7 +636,10 @@
>       // to the client's certificate. This allows us to verify that the 
> client is in
>       // possession of the private key of the certificate.
>       if len(c.peerCertificates) > 0 {
> -             msg, err = c.readHandshake()
> +             // certificateVerifyMsg is included in the transcript, but not 
> until
> +             // after we verify the handshake signature, since the state 
> before
> +             // this message was sent is used.
> +             msg, err = c.readHandshake(nil)
>               if err != nil {
>                       return err
>               }
> @@ -674,7 +674,9 @@
>                       return errors.New("tls: invalid signature by the client 
> certificate: " + err.Error())
>               }
>  
> -             hs.finishedHash.Write(certVerify.marshal())
> +             if err := transcriptMsg(certVerify, &hs.finishedHash); err != 
> nil {
> +                     return err
> +             }
>       }
>  
>       hs.finishedHash.discardHandshakeBuffer()
> @@ -714,7 +716,10 @@
>               return err
>       }
>  
> -     msg, err := c.readHandshake()
> +     // finishedMsg is included in the transcript, but not until after we
> +     // check the client version, since the state before this message was
> +     // sent is used during verification.
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -731,7 +736,10 @@
>               return errors.New("tls: client's Finished message is incorrect")
>       }
>  
> -     hs.finishedHash.Write(clientFinished.marshal())
> +     if err := transcriptMsg(clientFinished, &hs.finishedHash); err != nil {
> +             return err
> +     }
> +
>       copy(out, verify)
>       return nil
>  }
> @@ -765,14 +773,16 @@
>               masterSecret: hs.masterSecret,
>               certificates: certsFromClient,
>       }
> -     var err error
> -     m.ticket, err = c.encryptTicket(state.marshal())
> +     stateBytes, err := state.marshal()
> +     if err != nil {
> +             return err
> +     }
> +     m.ticket, err = c.encryptTicket(stateBytes)
>       if err != nil {
>               return err
>       }
>  
> -     hs.finishedHash.Write(m.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != 
> nil {
> +     if _, err := hs.c.writeHandshakeRecord(m, &hs.finishedHash); err != nil 
> {
>               return err
>       }
>  
> @@ -782,14 +792,13 @@
>  func (hs *serverHandshakeState) sendFinished(out []byte) error {
>       c := hs.c
>  
> -     if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err 
> != nil {
> +     if err := c.writeChangeCipherRecord(); err != nil {
>               return err
>       }
>  
>       finished := new(finishedMsg)
>       finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
> -     hs.finishedHash.Write(finished.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); 
> err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err 
> != nil {
>               return err
>       }
>  
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_server_test.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_server_test.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_server_test.go        
> 2023-01-10 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_server_test.go        
> 2023-02-14 01:38:45.000000000 +0800
> @@ -30,6 +30,13 @@
>       testClientHelloFailure(t, serverConfig, m, "")
>  }
>  
> +// testFatal is a hack to prevent the compiler from complaining that there 
> is a
> +// call to t.Fatal from a non-test goroutine
> +func testFatal(t *testing.T, err error) {
> +     t.Helper()
> +     t.Fatal(err)
> +}
> +
>  func testClientHelloFailure(t *testing.T, serverConfig *Config, m 
> handshakeMessage, expectedSubStr string) {
>       c, s := localPipe(t)
>       go func() {
> @@ -37,7 +44,9 @@
>               if ch, ok := m.(*clientHelloMsg); ok {
>                       cli.vers = ch.vers
>               }
> -             cli.writeRecord(recordTypeHandshake, m.marshal())
> +             if _, err := cli.writeHandshakeRecord(m, nil); err != nil {
> +                     testFatal(t, err)
> +             }
>               c.Close()
>       }()
>       ctx := context.Background()
> @@ -194,7 +203,9 @@
>       go func() {
>               cli := Client(c, testConfig)
>               cli.vers = clientHello.vers
> -             cli.writeRecord(recordTypeHandshake, clientHello.marshal())
> +             if _, err := cli.writeHandshakeRecord(clientHello, nil); err != 
> nil {
> +                     testFatal(t, err)
> +             }
>  
>               buf := make([]byte, 1024)
>               n, err := c.Read(buf)
> @@ -253,8 +264,10 @@
>       go func() {
>               cli := Client(c, testConfig)
>               cli.vers = clientHello.vers
> -             cli.writeRecord(recordTypeHandshake, clientHello.marshal())
> -             reply, err := cli.readHandshake()
> +             if _, err := cli.writeHandshakeRecord(clientHello, nil); err != 
> nil {
> +                     testFatal(t, err)
> +             }
> +             reply, err := cli.readHandshake(nil)
>               c.Close()
>               if err != nil {
>                       replyChan <- err
> @@ -311,8 +324,10 @@
>                       go func() {
>                               cli := Client(c, testConfig)
>                               cli.vers = clientHello.vers
> -                             cli.writeRecord(recordTypeHandshake, 
> clientHello.marshal())
> -                             reply, err := cli.readHandshake()
> +                             if _, err := 
> cli.writeHandshakeRecord(clientHello, nil); err != nil {
> +                                     testFatal(t, err)
> +                             }
> +                             reply, err := cli.readHandshake(nil)
>                               c.Close()
>                               if err != nil {
>                                       replyChan <- err
> @@ -1426,7 +1441,9 @@
>       go func() {
>               cli := Client(c, testConfig)
>               cli.vers = clientHello.vers
> -             cli.writeRecord(recordTypeHandshake, clientHello.marshal())
> +             if _, err := cli.writeHandshakeRecord(clientHello, nil); err != 
> nil {
> +                     testFatal(t, err)
> +             }
>               c.Close()
>       }()
>       conn := Server(s, serverConfig)
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/handshake_server_tls13.go 
> golang-1.19-1.19.6/src/crypto/tls/handshake_server_tls13.go
> --- golang-1.19-1.19.5/src/crypto/tls/handshake_server_tls13.go       
> 2023-01-10 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/handshake_server_tls13.go       
> 2023-02-14 01:38:45.000000000 +0800
> @@ -302,7 +302,12 @@
>                       c.sendAlert(alertInternalError)
>                       return errors.New("tls: internal error: failed to clone 
> hash")
>               }
> -             transcript.Write(hs.clientHello.marshalWithoutBinders())
> +             clientHelloBytes, err := hs.clientHello.marshalWithoutBinders()
> +             if err != nil {
> +                     c.sendAlert(alertInternalError)
> +                     return err
> +             }
> +             transcript.Write(clientHelloBytes)
>               pskBinder := hs.suite.finishedHash(binderKey, transcript)
>               if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) {
>                       c.sendAlert(alertDecryptError)
> @@ -393,8 +398,7 @@
>       }
>       hs.sentDummyCCS = true
>  
> -     _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
> -     return err
> +     return hs.c.writeChangeCipherRecord()
>  }
>  
>  func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup 
> CurveID) error {
> @@ -402,7 +406,9 @@
>  
>       // The first ClientHello gets double-hashed into the transcript upon a
>       // HelloRetryRequest. See RFC 8446, Section 4.4.1.
> -     hs.transcript.Write(hs.clientHello.marshal())
> +     if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
> +             return err
> +     }
>       chHash := hs.transcript.Sum(nil)
>       hs.transcript.Reset()
>       hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
> @@ -418,8 +424,7 @@
>               selectedGroup:     selectedGroup,
>       }
>  
> -     hs.transcript.Write(helloRetryRequest.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, 
> helloRetryRequest.marshal()); err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(helloRetryRequest, 
> hs.transcript); err != nil {
>               return err
>       }
>  
> @@ -427,7 +432,8 @@
>               return err
>       }
>  
> -     msg, err := c.readHandshake()
> +     // clientHelloMsg is not included in the transcript.
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> @@ -518,9 +524,10 @@
>  func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
>       c := hs.c
>  
> -     hs.transcript.Write(hs.clientHello.marshal())
> -     hs.transcript.Write(hs.hello.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); 
> err != nil {
> +     if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
> +             return err
> +     }
> +     if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != 
> nil {
>               return err
>       }
>  
> @@ -563,8 +570,7 @@
>       encryptedExtensions.alpnProtocol = selectedProto
>       c.clientProtocol = selectedProto
>  
> -     hs.transcript.Write(encryptedExtensions.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, 
> encryptedExtensions.marshal()); err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, 
> hs.transcript); err != nil {
>               return err
>       }
>  
> @@ -593,8 +599,7 @@
>                       certReq.certificateAuthorities = 
> c.config.ClientCAs.Subjects()
>               }
>  
> -             hs.transcript.Write(certReq.marshal())
> -             if _, err := c.writeRecord(recordTypeHandshake, 
> certReq.marshal()); err != nil {
> +             if _, err := hs.c.writeHandshakeRecord(certReq, hs.transcript); 
> err != nil {
>                       return err
>               }
>       }
> @@ -605,8 +610,7 @@
>       certMsg.scts = hs.clientHello.scts && 
> len(hs.cert.SignedCertificateTimestamps) > 0
>       certMsg.ocspStapling = hs.clientHello.ocspStapling && 
> len(hs.cert.OCSPStaple) > 0
>  
> -     hs.transcript.Write(certMsg.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err 
> != nil {
> +     if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != 
> nil {
>               return err
>       }
>  
> @@ -637,8 +641,7 @@
>       }
>       certVerifyMsg.signature = sig
>  
> -     hs.transcript.Write(certVerifyMsg.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, 
> certVerifyMsg.marshal()); err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); 
> err != nil {
>               return err
>       }
>  
> @@ -652,8 +655,7 @@
>               verifyData: hs.suite.finishedHash(c.out.trafficSecret, 
> hs.transcript),
>       }
>  
> -     hs.transcript.Write(finished.marshal())
> -     if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); 
> err != nil {
> +     if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != 
> nil {
>               return err
>       }
>  
> @@ -714,7 +716,9 @@
>       finishedMsg := &finishedMsg{
>               verifyData: hs.clientFinished,
>       }
> -     hs.transcript.Write(finishedMsg.marshal())
> +     if err := transcriptMsg(finishedMsg, hs.transcript); err != nil {
> +             return err
> +     }
>  
>       if !hs.shouldSendSessionTickets() {
>               return nil
> @@ -739,8 +743,12 @@
>                       SignedCertificateTimestamps: c.scts,
>               },
>       }
> -     var err error
> -     m.label, err = c.encryptTicket(state.marshal())
> +     stateBytes, err := state.marshal()
> +     if err != nil {
> +             c.sendAlert(alertInternalError)
> +             return err
> +     }
> +     m.label, err = c.encryptTicket(stateBytes)
>       if err != nil {
>               return err
>       }
> @@ -759,7 +767,7 @@
>       // ticket_nonce, which must be unique per connection, is always left at
>       // zero because we only ever send one ticket per connection.
>  
> -     if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != 
> nil {
> +     if _, err := c.writeHandshakeRecord(m, nil); err != nil {
>               return err
>       }
>  
> @@ -784,7 +792,7 @@
>       // If we requested a client certificate, then the client must send a
>       // certificate message. If it's empty, no CertificateVerify is sent.
>  
> -     msg, err := c.readHandshake()
> +     msg, err := c.readHandshake(hs.transcript)
>       if err != nil {
>               return err
>       }
> @@ -794,7 +802,6 @@
>               c.sendAlert(alertUnexpectedMessage)
>               return unexpectedMessageError(certMsg, msg)
>       }
> -     hs.transcript.Write(certMsg.marshal())
>  
>       if err := c.processCertsFromClient(certMsg.certificate); err != nil {
>               return err
> @@ -808,7 +815,10 @@
>       }
>  
>       if len(certMsg.certificate.Certificate) != 0 {
> -             msg, err = c.readHandshake()
> +             // certificateVerifyMsg is included in the transcript, but not 
> until
> +             // after we verify the handshake signature, since the state 
> before
> +             // this message was sent is used.
> +             msg, err = c.readHandshake(nil)
>               if err != nil {
>                       return err
>               }
> @@ -839,7 +849,9 @@
>                       return errors.New("tls: invalid signature by the client 
> certificate: " + err.Error())
>               }
>  
> -             hs.transcript.Write(certVerify.marshal())
> +             if err := transcriptMsg(certVerify, hs.transcript); err != nil {
> +                     return err
> +             }
>       }
>  
>       // If we waited until the client certificates to send session tickets, 
> we
> @@ -854,7 +866,8 @@
>  func (hs *serverHandshakeStateTLS13) readClientFinished() error {
>       c := hs.c
>  
> -     msg, err := c.readHandshake()
> +     // finishedMsg is not included in the transcript.
> +     msg, err := c.readHandshake(nil)
>       if err != nil {
>               return err
>       }
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/key_schedule.go 
> golang-1.19-1.19.6/src/crypto/tls/key_schedule.go
> --- golang-1.19-1.19.5/src/crypto/tls/key_schedule.go 2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/key_schedule.go 2023-02-14 
> 01:38:45.000000000 +0800
> @@ -8,6 +8,7 @@
>       "crypto/elliptic"
>       "crypto/hmac"
>       "errors"
> +     "fmt"
>       "hash"
>       "io"
>       "math/big"
> @@ -42,8 +43,24 @@
>       hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
>               b.AddBytes(context)
>       })
> +     hkdfLabelBytes, err := hkdfLabel.Bytes()
> +     if err != nil {
> +             // Rather than calling BytesOrPanic, we explicitly handle this 
> error, in
> +             // order to provide a reasonable error message. It should be 
> basically
> +             // impossible for this to panic, and routing errors back 
> through the
> +             // tree rooted in this function is quite painful. The labels 
> are fixed
> +             // size, and the context is either a fixed-length computed 
> hash, or
> +             // parsed from a field which has the same length limitation. As 
> such, an
> +             // error here is likely to only be caused during development.
> +             //
> +             // NOTE: another reasonable approach here might be to return a
> +             // randomized slice if we encounter an error, which would break 
> the
> +             // connection, but avoid panicking. This would perhaps be safer 
> but
> +             // significantly more confusing to users.
> +             panic(fmt.Errorf("failed to construct HKDF label: %s", err))
> +     }
>       out := make([]byte, length)
> -     n, err := hkdf.Expand(c.hash.New, secret, 
> hkdfLabel.BytesOrPanic()).Read(out)
> +     n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out)
>       if err != nil || n != length {
>               panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
>       }
> diff -Nru golang-1.19-1.19.5/src/crypto/tls/ticket.go 
> golang-1.19-1.19.6/src/crypto/tls/ticket.go
> --- golang-1.19-1.19.5/src/crypto/tls/ticket.go       2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/tls/ticket.go       2023-02-14 
> 01:38:45.000000000 +0800
> @@ -32,7 +32,7 @@
>       usedOldKey bool
>  }
>  
> -func (m *sessionState) marshal() []byte {
> +func (m *sessionState) marshal() ([]byte, error) {
>       var b cryptobyte.Builder
>       b.AddUint16(m.vers)
>       b.AddUint16(m.cipherSuite)
> @@ -47,7 +47,7 @@
>                       })
>               }
>       })
> -     return b.BytesOrPanic()
> +     return b.Bytes()
>  }
>  
>  func (m *sessionState) unmarshal(data []byte) bool {
> @@ -86,7 +86,7 @@
>       certificate      Certificate // CertificateEntry 
> certificate_list<0..2^24-1>;
>  }
>  
> -func (m *sessionStateTLS13) marshal() []byte {
> +func (m *sessionStateTLS13) marshal() ([]byte, error) {
>       var b cryptobyte.Builder
>       b.AddUint16(VersionTLS13)
>       b.AddUint8(0) // revision
> @@ -96,7 +96,7 @@
>               b.AddBytes(m.resumptionSecret)
>       })
>       marshalCertificate(&b, m.certificate)
> -     return b.BytesOrPanic()
> +     return b.Bytes()
>  }
>  
>  func (m *sessionStateTLS13) unmarshal(data []byte) bool {
> diff -Nru golang-1.19-1.19.5/src/crypto/x509/boring_test.go 
> golang-1.19-1.19.6/src/crypto/x509/boring_test.go
> --- golang-1.19-1.19.5/src/crypto/x509/boring_test.go 2023-01-10 
> 06:38:14.000000000 +0800
> +++ golang-1.19-1.19.6/src/crypto/x509/boring_test.go 2023-02-14 
> 01:38:45.000000000 +0800
> @@ -54,7 +54,7 @@
>  
>  func TestBoringAllowCert(t *testing.T) {
>       R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, 
> boringCertCA|boringCertFIPSOK)
> -     R2 := testBoringCert(t, "R2", boringRSAKey(t, 8192), nil, boringCertCA)
> +     R2 := testBoringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA)
>       R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, 
> boringCertCA|boringCertFIPSOK)
>  
>       M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), 
> R1, boringCertCA|boringCertFIPSOK)
> diff -Nru golang-1.19-1.19.5/src/mime/multipart/formdata.go 
> golang-1.19-1.19.6/src/mime/multipart/formdata.go
> --- golang-1.19-1.19.5/src/mime/multipart/formdata.go 2023-01-10 
> 06:38:18.000000000 +0800
> +++ golang-1.19-1.19.6/src/mime/multipart/formdata.go 2023-02-14 
> 01:38:47.000000000 +0800
> @@ -7,6 +7,7 @@
>  import (
>       "bytes"
>       "errors"
> +     "internal/godebug"
>       "io"
>       "math"
>       "net/textproto"
> @@ -33,23 +34,58 @@
>  
>  func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
>       form := &Form{make(map[string][]string), make(map[string][]*FileHeader)}
> +     var (
> +             file    *os.File
> +             fileOff int64
> +     )
> +     numDiskFiles := 0
> +     multipartFiles := godebug.Get("multipartfiles")
> +     combineFiles := multipartFiles != "distinct"
>       defer func() {
> +             if file != nil {
> +                     if cerr := file.Close(); err == nil {
> +                             err = cerr
> +                     }
> +             }
> +             if combineFiles && numDiskFiles > 1 {
> +                     for _, fhs := range form.File {
> +                             for _, fh := range fhs {
> +                                     fh.tmpshared = true
> +                             }
> +                     }
> +             }
>               if err != nil {
>                       form.RemoveAll()
> +                     if file != nil {
> +                             os.Remove(file.Name())
> +                     }
>               }
>       }()
>  
> -     // Reserve an additional 10 MB for non-file parts.
> -     maxValueBytes := maxMemory + int64(10<<20)
> -     if maxValueBytes <= 0 {
> +     // maxFileMemoryBytes is the maximum bytes of file data we will store 
> in memory.
> +     // Data past this limit is written to disk.
> +     // This limit strictly applies to content, not metadata (filenames, 
> MIME headers, etc.),
> +     // since metadata is always stored in memory, not disk.
> +     //
> +     // maxMemoryBytes is the maximum bytes we will store in memory, 
> including file content,
> +     // non-file part values, metdata, and map entry overhead.
> +     //
> +     // We reserve an additional 10 MB in maxMemoryBytes for non-file data.
> +     //
> +     // The relationship between these parameters, as well as the 
> overly-large and
> +     // unconfigurable 10 MB added on to maxMemory, is unfortunate but 
> difficult to change
> +     // within the constraints of the API as documented.
> +     maxFileMemoryBytes := maxMemory
> +     maxMemoryBytes := maxMemory + int64(10<<20)
> +     if maxMemoryBytes <= 0 {
>               if maxMemory < 0 {
> -                     maxValueBytes = 0
> +                     maxMemoryBytes = 0
>               } else {
> -                     maxValueBytes = math.MaxInt64
> +                     maxMemoryBytes = math.MaxInt64
>               }
>       }
>       for {
> -             p, err := r.NextPart()
> +             p, err := r.nextPart(false, maxMemoryBytes)
>               if err == io.EOF {
>                       break
>               }
> @@ -63,16 +99,27 @@
>               }
>               filename := p.FileName()
>  
> +             // Multiple values for the same key (one map entry, longer 
> slice) are cheaper
> +             // than the same number of values for different keys (many map 
> entries), but
> +             // using a consistent per-value cost for overhead is simpler.
> +             maxMemoryBytes -= int64(len(name))
> +             maxMemoryBytes -= 100 // map overhead
> +             if maxMemoryBytes < 0 {
> +                     // We can't actually take this path, since nextPart 
> would already have
> +                     // rejected the MIME headers for being too large. Check 
> anyway.
> +                     return nil, ErrMessageTooLarge
> +             }
> +
>               var b bytes.Buffer
>  
>               if filename == "" {
>                       // value, store as string in memory
> -                     n, err := io.CopyN(&b, p, maxValueBytes+1)
> +                     n, err := io.CopyN(&b, p, maxMemoryBytes+1)
>                       if err != nil && err != io.EOF {
>                               return nil, err
>                       }
> -                     maxValueBytes -= n
> -                     if maxValueBytes < 0 {
> +                     maxMemoryBytes -= n
> +                     if maxMemoryBytes < 0 {
>                               return nil, ErrMessageTooLarge
>                       }
>                       form.Value[name] = append(form.Value[name], b.String())
> @@ -80,35 +127,45 @@
>               }
>  
>               // file, store in memory or on disk
> +             maxMemoryBytes -= mimeHeaderSize(p.Header)
> +             if maxMemoryBytes < 0 {
> +                     return nil, ErrMessageTooLarge
> +             }
>               fh := &FileHeader{
>                       Filename: filename,
>                       Header:   p.Header,
>               }
> -             n, err := io.CopyN(&b, p, maxMemory+1)
> +             n, err := io.CopyN(&b, p, maxFileMemoryBytes+1)
>               if err != nil && err != io.EOF {
>                       return nil, err
>               }
> -             if n > maxMemory {
> -                     // too big, write to disk and flush buffer
> -                     file, err := os.CreateTemp("", "multipart-")
> -                     if err != nil {
> -                             return nil, err
> +             if n > maxFileMemoryBytes {
> +                     if file == nil {
> +                             file, err = os.CreateTemp(r.tempDir, 
> "multipart-")
> +                             if err != nil {
> +                                     return nil, err
> +                             }
>                       }
> +                     numDiskFiles++
>                       size, err := io.Copy(file, io.MultiReader(&b, p))
> -                     if cerr := file.Close(); err == nil {
> -                             err = cerr
> -                     }
>                       if err != nil {
> -                             os.Remove(file.Name())
>                               return nil, err
>                       }
>                       fh.tmpfile = file.Name()
>                       fh.Size = size
> +                     fh.tmpoff = fileOff
> +                     fileOff += size
> +                     if !combineFiles {
> +                             if err := file.Close(); err != nil {
> +                                     return nil, err
> +                             }
> +                             file = nil
> +                     }
>               } else {
>                       fh.content = b.Bytes()
>                       fh.Size = int64(len(fh.content))
> -                     maxMemory -= n
> -                     maxValueBytes -= n
> +                     maxFileMemoryBytes -= n
> +                     maxMemoryBytes -= n
>               }
>               form.File[name] = append(form.File[name], fh)
>       }
> @@ -116,6 +173,17 @@
>       return form, nil
>  }
>  
> +func mimeHeaderSize(h textproto.MIMEHeader) (size int64) {
> +     for k, vs := range h {
> +             size += int64(len(k))
> +             size += 100 // map entry overhead
> +             for _, v := range vs {
> +                     size += int64(len(v))
> +             }
> +     }
> +     return size
> +}
> +
>  // Form is a parsed multipart form.
>  // Its File parts are stored either in memory or on disk,
>  // and are accessible via the *FileHeader's Open method.
> @@ -133,7 +201,7 @@
>               for _, fh := range fhs {
>                       if fh.tmpfile != "" {
>                               e := os.Remove(fh.tmpfile)
> -                             if e != nil && err == nil {
> +                             if e != nil && !errors.Is(e, os.ErrNotExist) && 
> err == nil {
>                                       err = e
>                               }
>                       }
> @@ -148,15 +216,25 @@
>       Header   textproto.MIMEHeader
>       Size     int64
>  
> -     content []byte
> -     tmpfile string
> +     content   []byte
> +     tmpfile   string
> +     tmpoff    int64
> +     tmpshared bool
>  }
>  
>  // Open opens and returns the FileHeader's associated File.
>  func (fh *FileHeader) Open() (File, error) {
>       if b := fh.content; b != nil {
>               r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))
> -             return sectionReadCloser{r}, nil
> +             return sectionReadCloser{r, nil}, nil
> +     }
> +     if fh.tmpshared {
> +             f, err := os.Open(fh.tmpfile)
> +             if err != nil {
> +                     return nil, err
> +             }
> +             r := io.NewSectionReader(f, fh.tmpoff, fh.Size)
> +             return sectionReadCloser{r, f}, nil
>       }
>       return os.Open(fh.tmpfile)
>  }
> @@ -175,8 +253,12 @@
>  
>  type sectionReadCloser struct {
>       *io.SectionReader
> +     io.Closer
>  }
>  
>  func (rc sectionReadCloser) Close() error {
> +     if rc.Closer != nil {
> +             return rc.Closer.Close()
> +     }
>       return nil
>  }
> diff -Nru golang-1.19-1.19.5/src/mime/multipart/formdata_test.go 
> golang-1.19-1.19.6/src/mime/multipart/formdata_test.go
> --- golang-1.19-1.19.5/src/mime/multipart/formdata_test.go    2023-01-10 
> 06:38:18.000000000 +0800
> +++ golang-1.19-1.19.6/src/mime/multipart/formdata_test.go    2023-02-14 
> 01:38:47.000000000 +0800
> @@ -6,8 +6,10 @@
>  
>  import (
>       "bytes"
> +     "fmt"
>       "io"
>       "math"
> +     "net/textproto"
>       "os"
>       "strings"
>       "testing"
> @@ -208,8 +210,8 @@
>               maxMemory int64
>               err       error
>       }{
> -             {"smaller", 50, nil},
> -             {"exact-fit", 25, nil},
> +             {"smaller", 50 + int64(len("largetext")) + 100, nil},
> +             {"exact-fit", 25 + int64(len("largetext")) + 100, nil},
>               {"too-large", 0, ErrMessageTooLarge},
>       }
>       for _, tc := range testCases {
> @@ -224,7 +226,7 @@
>                               defer f.RemoveAll()
>                       }
>                       if tc.err != err {
> -                             t.Fatalf("ReadForm error - got: %v; expected: 
> %v", tc.err, err)
> +                             t.Fatalf("ReadForm error - got: %v; expected: 
> %v", err, tc.err)
>                       }
>                       if err == nil {
>                               if g := f.Value["largetext"][0]; g != 
> largeTextValue {
> @@ -234,3 +236,135 @@
>               })
>       }
>  }
> +
> +// TestReadForm_MetadataTooLarge verifies that we account for the size of 
> field names,
> +// MIME headers, and map entry overhead while limiting the memory 
> consumption of parsed forms.
> +func TestReadForm_MetadataTooLarge(t *testing.T) {
> +     for _, test := range []struct {
> +             name string
> +             f    func(*Writer)
> +     }{{
> +             name: "large name",
> +             f: func(fw *Writer) {
> +                     name := strings.Repeat("a", 10<<20)
> +                     w, _ := fw.CreateFormField(name)
> +                     w.Write([]byte("value"))
> +             },
> +     }, {
> +             name: "large MIME header",
> +             f: func(fw *Writer) {
> +                     h := make(textproto.MIMEHeader)
> +                     h.Set("Content-Disposition", `form-data; name="a"`)
> +                     h.Set("X-Foo", strings.Repeat("a", 10<<20))
> +                     w, _ := fw.CreatePart(h)
> +                     w.Write([]byte("value"))
> +             },
> +     }, {
> +             name: "many parts",
> +             f: func(fw *Writer) {
> +                     for i := 0; i < 110000; i++ {
> +                             w, _ := fw.CreateFormField("f")
> +                             w.Write([]byte("v"))
> +                     }
> +             },
> +     }} {
> +             t.Run(test.name, func(t *testing.T) {
> +                     var buf bytes.Buffer
> +                     fw := NewWriter(&buf)
> +                     test.f(fw)
> +                     if err := fw.Close(); err != nil {
> +                             t.Fatal(err)
> +                     }
> +                     fr := NewReader(&buf, fw.Boundary())
> +                     _, err := fr.ReadForm(0)
> +                     if err != ErrMessageTooLarge {
> +                             t.Errorf("fr.ReadForm() = %v, want 
> ErrMessageTooLarge", err)
> +                     }
> +             })
> +     }
> +}
> +
> +// TestReadForm_ManyFiles_Combined tests that a multipart form containing 
> many files only
> +// results in a single on-disk file.
> +func TestReadForm_ManyFiles_Combined(t *testing.T) {
> +     const distinct = false
> +     testReadFormManyFiles(t, distinct)
> +}
> +
> +// TestReadForm_ManyFiles_Distinct tests that setting 
> GODEBUG=multipartfiles=distinct
> +// results in every file in a multipart form being placed in a distinct 
> on-disk file.
> +func TestReadForm_ManyFiles_Distinct(t *testing.T) {
> +     t.Setenv("GODEBUG", "multipartfiles=distinct")
> +     const distinct = true
> +     testReadFormManyFiles(t, distinct)
> +}
> +
> +func testReadFormManyFiles(t *testing.T, distinct bool) {
> +     var buf bytes.Buffer
> +     fw := NewWriter(&buf)
> +     const numFiles = 10
> +     for i := 0; i < numFiles; i++ {
> +             name := fmt.Sprint(i)
> +             w, err := fw.CreateFormFile(name, name)
> +             if err != nil {
> +                     t.Fatal(err)
> +             }
> +             w.Write([]byte(name))
> +     }
> +     if err := fw.Close(); err != nil {
> +             t.Fatal(err)
> +     }
> +     fr := NewReader(&buf, fw.Boundary())
> +     fr.tempDir = t.TempDir()
> +     form, err := fr.ReadForm(0)
> +     if err != nil {
> +             t.Fatal(err)
> +     }
> +     for i := 0; i < numFiles; i++ {
> +             name := fmt.Sprint(i)
> +             if got := len(form.File[name]); got != 1 {
> +                     t.Fatalf("form.File[%q] has %v entries, want 1", name, 
> got)
> +             }
> +             fh := form.File[name][0]
> +             file, err := fh.Open()
> +             if err != nil {
> +                     t.Fatalf("form.File[%q].Open() = %v", name, err)
> +             }
> +             if distinct {
> +                     if _, ok := file.(*os.File); !ok {
> +                             t.Fatalf("form.File[%q].Open: %T, want 
> *os.File", name, file)
> +                     }
> +             }
> +             got, err := io.ReadAll(file)
> +             file.Close()
> +             if string(got) != name || err != nil {
> +                     t.Fatalf("read form.File[%q]: %q, %v; want %q, nil", 
> name, string(got), err, name)
> +             }
> +     }
> +     dir, err := os.Open(fr.tempDir)
> +     if err != nil {
> +             t.Fatal(err)
> +     }
> +     defer dir.Close()
> +     names, err := dir.Readdirnames(0)
> +     if err != nil {
> +             t.Fatal(err)
> +     }
> +     wantNames := 1
> +     if distinct {
> +             wantNames = numFiles
> +     }
> +     if len(names) != wantNames {
> +             t.Fatalf("temp dir contains %v files; want 1", len(names))
> +     }
> +     if err := form.RemoveAll(); err != nil {
> +             t.Fatalf("form.RemoveAll() = %v", err)
> +     }
> +     names, err = dir.Readdirnames(0)
> +     if err != nil {
> +             t.Fatal(err)
> +     }
> +     if len(names) != 0 {
> +             t.Fatalf("temp dir contains %v files; want 0", len(names))
> +     }
> +}
> diff -Nru golang-1.19-1.19.5/src/mime/multipart/multipart.go 
> golang-1.19-1.19.6/src/mime/multipart/multipart.go
> --- golang-1.19-1.19.5/src/mime/multipart/multipart.go        2023-01-10 
> 06:38:18.000000000 +0800
> +++ golang-1.19-1.19.6/src/mime/multipart/multipart.go        2023-02-14 
> 01:38:47.000000000 +0800
> @@ -128,12 +128,12 @@
>       return n, r.err
>  }
>  
> -func newPart(mr *Reader, rawPart bool) (*Part, error) {
> +func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize int64) (*Part, 
> error) {
>       bp := &Part{
>               Header: make(map[string][]string),
>               mr:     mr,
>       }
> -     if err := bp.populateHeaders(); err != nil {
> +     if err := bp.populateHeaders(maxMIMEHeaderSize); err != nil {
>               return nil, err
>       }
>       bp.r = partReader{bp}
> @@ -149,12 +149,16 @@
>       return bp, nil
>  }
>  
> -func (p *Part) populateHeaders() error {
> +func (p *Part) populateHeaders(maxMIMEHeaderSize int64) error {
>       r := textproto.NewReader(p.mr.bufReader)
> -     header, err := r.ReadMIMEHeader()
> +     header, err := readMIMEHeader(r, maxMIMEHeaderSize)
>       if err == nil {
>               p.Header = header
>       }
> +     // TODO: Add a distinguishable error to net/textproto.
> +     if err != nil && err.Error() == "message too large" {
> +             err = ErrMessageTooLarge
> +     }
>       return err
>  }
>  
> @@ -311,6 +315,7 @@
>  // isn't supported.
>  type Reader struct {
>       bufReader *bufio.Reader
> +     tempDir   string // used in tests
>  
>       currentPart *Part
>       partsRead   int
> @@ -321,6 +326,10 @@
>       dashBoundary     []byte // "--boundary"
>  }
>  
> +// maxMIMEHeaderSize is the maximum size of a MIME header we will parse,
> +// including header keys, values, and map overhead.
> +const maxMIMEHeaderSize = 10 << 20
> +
>  // NextPart returns the next part in the multipart or an error.
>  // When there are no more parts, the error io.EOF is returned.
>  //
> @@ -328,7 +337,7 @@
>  // has a value of "quoted-printable", that header is instead
>  // hidden and the body is transparently decoded during Read calls.
>  func (r *Reader) NextPart() (*Part, error) {
> -     return r.nextPart(false)
> +     return r.nextPart(false, maxMIMEHeaderSize)
>  }
>  
>  // NextRawPart returns the next part in the multipart or an error.
> @@ -337,10 +346,10 @@
>  // Unlike NextPart, it does not have special handling for
>  // "Content-Transfer-Encoding: quoted-printable".
>  func (r *Reader) NextRawPart() (*Part, error) {
> -     return r.nextPart(true)
> +     return r.nextPart(true, maxMIMEHeaderSize)
>  }
>  
> -func (r *Reader) nextPart(rawPart bool) (*Part, error) {
> +func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize int64) (*Part, 
> error) {
>       if r.currentPart != nil {
>               r.currentPart.Close()
>       }
> @@ -365,7 +374,7 @@
>  
>               if r.isBoundaryDelimiterLine(line) {
>                       r.partsRead++
> -                     bp, err := newPart(r, rawPart)
> +                     bp, err := newPart(r, rawPart, maxMIMEHeaderSize)
>                       if err != nil {
>                               return nil, err
>                       }
> diff -Nru golang-1.19-1.19.5/src/mime/multipart/readmimeheader.go 
> golang-1.19-1.19.6/src/mime/multipart/readmimeheader.go
> --- golang-1.19-1.19.5/src/mime/multipart/readmimeheader.go   1970-01-01 
> 08:00:00.000000000 +0800
> +++ golang-1.19-1.19.6/src/mime/multipart/readmimeheader.go   2023-02-14 
> 01:38:47.000000000 +0800
> @@ -0,0 +1,14 @@
> +// Copyright 2023 The Go Authors. All rights reserved.
> +// Use of this source code is governed by a BSD-style
> +// license that can be found in the LICENSE file.
> +package multipart
> +
> +import (
> +     "net/textproto"
> +     _ "unsafe" // for go:linkname
> +)
> +
> +// readMIMEHeader is defined in package net/textproto.
> +//
> +//go:linkname readMIMEHeader net/textproto.readMIMEHeader
> +func readMIMEHeader(r *textproto.Reader, lim int64) (textproto.MIMEHeader, 
> error)
> diff -Nru golang-1.19-1.19.5/src/net/http/readrequest_test.go 
> golang-1.19-1.19.6/src/net/http/readrequest_test.go
> --- golang-1.19-1.19.5/src/net/http/readrequest_test.go       2023-01-10 
> 06:38:18.000000000 +0800
> +++ golang-1.19-1.19.6/src/net/http/readrequest_test.go       2023-02-14 
> 01:38:47.000000000 +0800
> @@ -450,16 +450,19 @@
>  Content-Length: 4
>  
>  abc`)},
> -     {"smuggle_content_len_head", reqBytes(`HEAD / HTTP/1.1
> +     {"smuggle_two_content_len_head", reqBytes(`HEAD / HTTP/1.1
>  Host: foo
> -Content-Length: 5`)},
> +Content-Length: 4
> +Content-Length: 5
> +
> +1234`)},
>  
>       // golang.org/issue/22464
>       {"leading_space_in_header", reqBytes(`HEAD / HTTP/1.1
>   Host: foo
>  Content-Length: 5`)},
>       {"leading_tab_in_header", reqBytes(`HEAD / HTTP/1.1
> -\tHost: foo
> +` + "\t" + `Host: foo
>  Content-Length: 5`)},
>  }
>  
> diff -Nru golang-1.19-1.19.5/src/net/http/request_test.go 
> golang-1.19-1.19.6/src/net/http/request_test.go
> --- golang-1.19-1.19.5/src/net/http/request_test.go   2023-01-10 
> 06:38:18.000000000 +0800
> +++ golang-1.19-1.19.6/src/net/http/request_test.go   2023-02-14 
> 01:38:47.000000000 +0800
> @@ -485,10 +485,6 @@
>       1: {"GET / HTTP/1.1\r\nheader:foo\r\n", io.ErrUnexpectedEOF.Error(), 
> nil},
>       2: {"", io.EOF.Error(), nil},
>       3: {
> -             in:  "HEAD / HTTP/1.1\r\nContent-Length:4\r\n\r\n",
> -             err: "http: method cannot contain a Content-Length",
> -     },
> -     4: {
>               in:     "HEAD / HTTP/1.1\r\n\r\n",
>               header: Header{},
>       },
> @@ -496,32 +492,32 @@
>       // Multiple Content-Length values should either be
>       // deduplicated if same or reject otherwise
>       // See Issue 16490.
> -     5: {
> +     4: {
>               in:  "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 
> 0\r\n\r\nGopher hey\r\n",
>               err: "cannot contain multiple Content-Length headers",
>       },
> -     6: {
> +     5: {
>               in:  "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 
> 6\r\n\r\nGopher\r\n",
>               err: "cannot contain multiple Content-Length headers",
>       },
> -     7: {
> +     6: {
>               in:     "PUT / HTTP/1.1\r\nContent-Length: 6 
> \r\nContent-Length: 6\r\nContent-Length:6\r\n\r\nGopher\r\n",
>               err:    "",
>               header: Header{"Content-Length": {"6"}},
>       },
> -     8: {
> +     7: {
>               in:  "PUT / HTTP/1.1\r\nContent-Length: 1\r\nContent-Length: 6 
> \r\n\r\n",
>               err: "cannot contain multiple Content-Length headers",
>       },
> -     9: {
> +     8: {
>               in:  "POST / HTTP/1.1\r\nContent-Length:\r\nContent-Length: 
> 3\r\n\r\n",
>               err: "cannot contain multiple Content-Length headers",
>       },
> -     10: {
> +     9: {
>               in:     "HEAD / HTTP/1.1\r\nContent-Length:0\r\nContent-Length: 
> 0\r\n\r\n",
>               header: Header{"Content-Length": {"0"}},
>       },
> -     11: {
> +     10: {
>               in:  "HEAD / HTTP/1.1\r\nHost: foo\r\nHost: 
> bar\r\n\r\n\r\n\r\n",
>               err: "too many Host headers",
>       },
> @@ -1108,7 +1104,7 @@
>               t.Errorf("FormFile file = %v, want nil", f)
>       }
>       if fh != nil {
> -             t.Errorf("FormFile file header = %q, want nil", fh)
> +             t.Errorf("FormFile file header = %v, want nil", fh)
>       }
>       if err != ErrMissingFile {
>               t.Errorf("FormFile err = %q, want ErrMissingFile", err)
> diff -Nru golang-1.19-1.19.5/src/net/http/serve_test.go 
> golang-1.19-1.19.6/src/net/http/serve_test.go
> --- golang-1.19-1.19.5/src/net/http/serve_test.go     2023-01-10 
> 06:38:18.000000000 +0800
> +++ golang-1.19-1.19.6/src/net/http/serve_test.go     2023-02-14 
> 01:38:47.000000000 +0800
> @@ -6758,3 +6758,73 @@
>               t.Errorf("unexpected response; got %q; should start by %q", 
> got, expected)
>       }
>  }
> +
> +func TestHeadBody(t *testing.T) {
> +     const identityMode = false
> +     const chunkedMode = true
> +     t.Run("h1", func(t *testing.T) {
> +             t.Run("identity", func(t *testing.T) { testHeadBody(t, h1Mode, 
> identityMode, "HEAD") })
> +             t.Run("chunked", func(t *testing.T) { testHeadBody(t, h1Mode, 
> chunkedMode, "HEAD") })
> +     })
> +     t.Run("h2", func(t *testing.T) {
> +             t.Run("identity", func(t *testing.T) { testHeadBody(t, h2Mode, 
> identityMode, "HEAD") })
> +             t.Run("chunked", func(t *testing.T) { testHeadBody(t, h2Mode, 
> chunkedMode, "HEAD") })
> +     })
> +}
> +
> +func TestGetBody(t *testing.T) {
> +     const identityMode = false
> +     const chunkedMode = true
> +     t.Run("h1", func(t *testing.T) {
> +             t.Run("identity", func(t *testing.T) { testHeadBody(t, h1Mode, 
> identityMode, "GET") })
> +             t.Run("chunked", func(t *testing.T) { testHeadBody(t, h1Mode, 
> chunkedMode, "GET") })
> +     })
> +     t.Run("h2", func(t *testing.T) {
> +             t.Run("identity", func(t *testing.T) { testHeadBody(t, h2Mode, 
> identityMode, "GET") })
> +             t.Run("chunked", func(t *testing.T) { testHeadBody(t, h2Mode, 
> chunkedMode, "GET") })
> +     })
> +}
> +
> +func testHeadBody(t *testing.T, h2, chunked bool, method string) {
> +     setParallel(t)
> +     defer afterTest(t)
> +     cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r 
> *Request) {
> +             b, err := io.ReadAll(r.Body)
> +             if err != nil {
> +                     t.Errorf("server reading body: %v", err)
> +                     return
> +             }
> +             w.Header().Set("X-Request-Body", string(b))
> +             w.Header().Set("Content-Length", "0")
> +     }))
> +     defer cst.close()
> +     for _, reqBody := range []string{
> +             "",
> +             "",
> +             "request_body",
> +             "",
> +     } {
> +             var bodyReader io.Reader
> +             if reqBody != "" {
> +                     bodyReader = strings.NewReader(reqBody)
> +                     if chunked {
> +                             bodyReader = bufio.NewReader(bodyReader)
> +                     }
> +             }
> +             req, err := NewRequest(method, cst.ts.URL, bodyReader)
> +             if err != nil {
> +                     t.Fatal(err)
> +             }
> +             res, err := cst.c.Do(req)
> +             if err != nil {
> +                     t.Fatal(err)
> +             }
> +             res.Body.Close()
> +             if got, want := res.StatusCode, 200; got != want {
> +                     t.Errorf("%v request with %d-byte body: StatusCode = 
> %v, want %v", method, len(reqBody), got, want)
> +             }
> +             if got, want := res.Header.Get("X-Request-Body"), reqBody; got 
> != want {
> +                     t.Errorf("%v request with %d-byte body: handler read 
> body %q, want %q", method, len(reqBody), got, want)
> +             }
> +     }
> +}
> diff -Nru golang-1.19-1.19.5/src/net/http/transfer.go 
> golang-1.19-1.19.6/src/net/http/transfer.go
> --- golang-1.19-1.19.5/src/net/http/transfer.go       2023-01-10 
> 06:38:19.000000000 +0800
> +++ golang-1.19-1.19.6/src/net/http/transfer.go       2023-02-14 
> 01:38:47.000000000 +0800
> @@ -557,7 +557,7 @@
>       // or close connection when finished, since multipart is not supported 
> yet
>       switch {
>       case t.Chunked:
> -             if noResponseBodyExpected(t.RequestMethod) || 
> !bodyAllowedForStatus(t.StatusCode) {
> +             if isResponse && (noResponseBodyExpected(t.RequestMethod) || 
> !bodyAllowedForStatus(t.StatusCode)) {
>                       t.Body = NoBody
>               } else {
>                       t.Body = &body{src: internal.NewChunkedReader(r), hdr: 
> msg, r: r, closing: t.Close}
> @@ -691,14 +691,7 @@
>       }
>  
>       // Logic based on response type or status
> -     if noResponseBodyExpected(requestMethod) {
> -             // For HTTP requests, as part of hardening against request
> -             // smuggling (RFC 7230), don't allow a Content-Length header for
> -             // methods which don't permit bodies. As an exception, allow
> -             // exactly one Content-Length header if its value is "0".
> -             if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 
> && contentLens[0] == "0") {
> -                     return 0, fmt.Errorf("http: method cannot contain a 
> Content-Length; got %q", contentLens)
> -             }
> +     if isResponse && noResponseBodyExpected(requestMethod) {
>               return 0, nil
>       }
>       if status/100 == 1 {
> diff -Nru golang-1.19-1.19.5/src/net/textproto/reader.go 
> golang-1.19-1.19.6/src/net/textproto/reader.go
> --- golang-1.19-1.19.5/src/net/textproto/reader.go    2023-01-10 
> 06:38:19.000000000 +0800
> +++ golang-1.19-1.19.6/src/net/textproto/reader.go    2023-02-14 
> 01:38:47.000000000 +0800
> @@ -7,8 +7,10 @@
>  import (
>       "bufio"
>       "bytes"
> +     "errors"
>       "fmt"
>       "io"
> +     "math"
>       "strconv"
>       "strings"
>       "sync"
> @@ -481,6 +483,12 @@
>  //           "Long-Key": {"Even Longer Value"},
>  //   }
>  func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
> +     return readMIMEHeader(r, math.MaxInt64)
> +}
> +
> +// readMIMEHeader is a version of ReadMIMEHeader which takes a limit on the 
> header size.
> +// It is called by the mime/multipart package.
> +func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) {
>       // Avoid lots of small slice allocations later by allocating one
>       // large one ahead of time which we'll cut up into smaller
>       // slices. If this isn't big enough later, we allocate small ones.
> @@ -522,9 +530,19 @@
>               }
>  
>               // Skip initial spaces in value.
> -             value := strings.TrimLeft(string(v), " \t")
> +             value := string(bytes.TrimLeft(v, " \t"))
>  
>               vv := m[key]
> +             if vv == nil {
> +                     lim -= int64(len(key))
> +                     lim -= 100 // map entry overhead
> +             }
> +             lim -= int64(len(value))
> +             if lim < 0 {
> +                     // TODO: This should be a distinguishable error 
> (ErrMessageTooLarge)
> +                     // to allow mime/multipart to detect it.
> +                     return m, errors.New("message too large")
> +             }
>               if vv == nil && len(strs) > 0 {
>                       // More than likely this will be a single-element key.
>                       // Most headers aren't multi-valued.
> diff -Nru golang-1.19-1.19.5/src/path/filepath/path.go 
> golang-1.19-1.19.6/src/path/filepath/path.go
> --- golang-1.19-1.19.5/src/path/filepath/path.go      2023-01-10 
> 06:38:19.000000000 +0800
> +++ golang-1.19-1.19.6/src/path/filepath/path.go      2023-02-14 
> 01:38:47.000000000 +0800
> @@ -15,6 +15,7 @@
>       "errors"
>       "io/fs"
>       "os"
> +     "runtime"
>       "sort"
>       "strings"
>  )
> @@ -117,21 +118,9 @@
>               case os.IsPathSeparator(path[r]):
>                       // empty path element
>                       r++
> -             case path[r] == '.' && r+1 == n:
> +             case path[r] == '.' && (r+1 == n || 
> os.IsPathSeparator(path[r+1])):
>                       // . element
>                       r++
> -             case path[r] == '.' && os.IsPathSeparator(path[r+1]):
> -                     // ./ element
> -                     r++
> -
> -                     for r < len(path) && os.IsPathSeparator(path[r]) {
> -                             r++
> -                     }
> -                     if out.w == 0 && volumeNameLen(path[r:]) > 0 {
> -                             // When joining prefix "." and an absolute path 
> on Windows,
> -                             // the prefix should not be removed.
> -                             out.append('.')
> -                     }
>               case path[r] == '.' && path[r+1] == '.' && (r+2 == n || 
> os.IsPathSeparator(path[r+2])):
>                       // .. element: remove to last separator
>                       r += 2
> @@ -157,6 +146,18 @@
>                       if rooted && out.w != 1 || !rooted && out.w != 0 {
>                               out.append(Separator)
>                       }
> +                     // If a ':' appears in the path element at the start of 
> a Windows path,
> +                     // insert a .\ at the beginning to avoid converting 
> relative paths
> +                     // like a/../c: into c:.
> +                     if runtime.GOOS == "windows" && out.w == 0 && 
> out.volLen == 0 && r != 0 {
> +                             for i := r; i < n && 
> !os.IsPathSeparator(path[i]); i++ {
> +                                     if path[i] == ':' {
> +                                             out.append('.')
> +                                             out.append(Separator)
> +                                             break
> +                                     }
> +                             }
> +                     }
>                       // copy element
>                       for ; r < n && !os.IsPathSeparator(path[r]); r++ {
>                               out.append(path[r])
> diff -Nru golang-1.19-1.19.5/src/path/filepath/path_test.go 
> golang-1.19-1.19.6/src/path/filepath/path_test.go
> --- golang-1.19-1.19.5/src/path/filepath/path_test.go 2023-01-10 
> 06:38:19.000000000 +0800
> +++ golang-1.19-1.19.6/src/path/filepath/path_test.go 2023-02-14 
> 01:38:47.000000000 +0800
> @@ -96,6 +96,13 @@
>       {`.\c:`, `.\c:`},
>       {`.\c:\foo`, `.\c:\foo`},
>       {`.\c:foo`, `.\c:foo`},
> +
> +     // Don't allow cleaning to move an element with a colon to the start of 
> the path.
> +     {`a/../c:`, `.\c:`},
> +     {`a\..\c:`, `.\c:`},
> +     {`a/../c:/a`, `.\c:\a`},
> +     {`a/../../c:`, `..\c:`},
> +     {`foo:bar`, `foo:bar`},
>  }
>  
>  func TestClean(t *testing.T) {
> diff -Nru golang-1.19-1.19.5/src/path/filepath/path_windows_test.go 
> golang-1.19-1.19.6/src/path/filepath/path_windows_test.go
> --- golang-1.19-1.19.5/src/path/filepath/path_windows_test.go 2023-01-10 
> 06:38:19.000000000 +0800
> +++ golang-1.19-1.19.6/src/path/filepath/path_windows_test.go 2023-02-14 
> 01:38:47.000000000 +0800
> @@ -542,7 +542,7 @@
>       }{
>               {`..\.`, `C:`, `..\C:`},
>               {`..`, `C:`, `..\C:`},
> -             {`.`, `:`, `:`},
> +             {`.`, `:`, `.\:`},
>               {`.`, `C:`, `.\C:`},
>               {`.`, `C:/a/b/../c`, `.\C:\a\c`},
>               {`.`, `\C:`, `.\C:`},
> diff -Nru golang-1.19-1.19.5/src/runtime/asm_ppc64x.s 
> golang-1.19-1.19.6/src/runtime/asm_ppc64x.s
> --- golang-1.19-1.19.5/src/runtime/asm_ppc64x.s       2023-01-10 
> 06:38:19.000000000 +0800
> +++ golang-1.19-1.19.6/src/runtime/asm_ppc64x.s       2023-02-14 
> 01:38:47.000000000 +0800
> @@ -339,8 +339,11 @@
>       // the caller doesn't save LR on stack but passes it as a
>       // register (R5), and the unwinder currently doesn't understand.
>       // Make it SPWRITE to stop unwinding. (See issue 54332)
> -     MOVD    R1, R1
> +     // Use OR R0, R1 instead of MOVD R1, R1 as the MOVD instruction
> +     // has a special affect on Power8,9,10 by lowering the thread 
> +     // priority and causing a slowdown in execution time
>  
> +     OR      R0, R1
>       MOVD    R0, R11
>       BR      runtime·morestack(SB)
>  
> diff -Nru golang-1.19-1.19.5/src/time/zoneinfo_abbrs_windows.go 
> golang-1.19-1.19.6/src/time/zoneinfo_abbrs_windows.go
> --- golang-1.19-1.19.5/src/time/zoneinfo_abbrs_windows.go     2023-01-10 
> 06:38:24.000000000 +0800
> +++ golang-1.19-1.19.6/src/time/zoneinfo_abbrs_windows.go     2023-02-14 
> 01:38:48.000000000 +0800
> @@ -16,10 +16,11 @@
>       "Egypt Standard Time":             {"EET", "EET"},     // Africa/Cairo
>       "Morocco Standard Time":           {"+00", "+01"},     // 
> Africa/Casablanca
>       "South Africa Standard Time":      {"SAST", "SAST"},   // 
> Africa/Johannesburg
> +     "South Sudan Standard Time":       {"CAT", "CAT"},     // Africa/Juba
>       "Sudan Standard Time":             {"CAT", "CAT"},     // 
> Africa/Khartoum
>       "W. Central Africa Standard Time": {"WAT", "WAT"},     // Africa/Lagos
>       "E. Africa Standard Time":         {"EAT", "EAT"},     // Africa/Nairobi
> -     "Sao Tome Standard Time":          {"GMT", "WAT"},     // 
> Africa/Sao_Tome
> +     "Sao Tome Standard Time":          {"GMT", "GMT"},     // 
> Africa/Sao_Tome
>       "Libya Standard Time":             {"EET", "EET"},     // Africa/Tripoli
>       "Namibia Standard Time":           {"CAT", "CAT"},     // 
> Africa/Windhoek
>       "Aleutian Standard Time":          {"HST", "HDT"},     // America/Adak
> @@ -33,8 +34,8 @@
>       "Venezuela Standard Time":         {"-04", "-04"},     // 
> America/Caracas
>       "SA Eastern Standard Time":        {"-03", "-03"},     // 
> America/Cayenne
>       "Central Standard Time":           {"CST", "CDT"},     // 
> America/Chicago
> -     "Mountain Standard Time (Mexico)": {"MST", "MDT"},     // 
> America/Chihuahua
> -     "Central Brazilian Standard Time": {"-04", "-03"},     // America/Cuiaba
> +     "Mountain Standard Time (Mexico)": {"CST", "CST"},     // 
> America/Chihuahua
> +     "Central Brazilian Standard Time": {"-04", "-04"},     // America/Cuiaba
>       "Mountain Standard Time":          {"MST", "MDT"},     // America/Denver
>       "Greenland Standard Time":         {"-03", "-02"},     // 
> America/Godthab
>       "Turks And Caicos Standard Time":  {"EST", "EDT"},     // 
> America/Grand_Turk
> @@ -44,7 +45,7 @@
>       "US Eastern Standard Time":        {"EST", "EDT"},     // 
> America/Indianapolis
>       "SA Western Standard Time":        {"-04", "-04"},     // America/La_Paz
>       "Pacific Standard Time":           {"PST", "PDT"},     // 
> America/Los_Angeles
> -     "Central Standard Time (Mexico)":  {"CST", "CDT"},     // 
> America/Mexico_City
> +     "Central Standard Time (Mexico)":  {"CST", "CST"},     // 
> America/Mexico_City
>       "Saint Pierre Standard Time":      {"-03", "-02"},     // 
> America/Miquelon
>       "Montevideo Standard Time":        {"-03", "-03"},     // 
> America/Montevideo
>       "Eastern Standard Time":           {"EST", "EDT"},     // 
> America/New_York
> @@ -53,11 +54,12 @@
>       "Magallanes Standard Time":        {"-03", "-03"},     // 
> America/Punta_Arenas
>       "Canada Central Standard Time":    {"CST", "CST"},     // America/Regina
>       "Pacific SA Standard Time":        {"-04", "-03"},     // 
> America/Santiago
> -     "E. South America Standard Time":  {"-03", "-02"},     // 
> America/Sao_Paulo
> +     "E. South America Standard Time":  {"-03", "-03"},     // 
> America/Sao_Paulo
>       "Newfoundland Standard Time":      {"NST", "NDT"},     // 
> America/St_Johns
>       "Pacific Standard Time (Mexico)":  {"PST", "PDT"},     // 
> America/Tijuana
> +     "Yukon Standard Time":             {"MST", "MST"},     // 
> America/Whitehorse
>       "Central Asia Standard Time":      {"+06", "+06"},     // Asia/Almaty
> -     "Jordan Standard Time":            {"EET", "EEST"},    // Asia/Amman
> +     "Jordan Standard Time":            {"+03", "+03"},     // Asia/Amman
>       "Arabic Standard Time":            {"+03", "+03"},     // Asia/Baghdad
>       "Azerbaijan Standard Time":        {"+04", "+04"},     // Asia/Baku
>       "SE Asia Standard Time":           {"+07", "+07"},     // Asia/Bangkok
> @@ -66,7 +68,7 @@
>       "India Standard Time":             {"IST", "IST"},     // Asia/Calcutta
>       "Transbaikal Standard Time":       {"+09", "+09"},     // Asia/Chita
>       "Sri Lanka Standard Time":         {"+0530", "+0530"}, // Asia/Colombo
> -     "Syria Standard Time":             {"EET", "EEST"},    // Asia/Damascus
> +     "Syria Standard Time":             {"+03", "+03"},     // Asia/Damascus
>       "Bangladesh Standard Time":        {"+06", "+06"},     // Asia/Dhaka
>       "Arabian Standard Time":           {"+04", "+04"},     // Asia/Dubai
>       "West Bank Standard Time":         {"EET", "EEST"},    // Asia/Hebron
> @@ -82,7 +84,7 @@
>       "N. Central Asia Standard Time":   {"+07", "+07"},     // 
> Asia/Novosibirsk
>       "Omsk Standard Time":              {"+06", "+06"},     // Asia/Omsk
>       "North Korea Standard Time":       {"KST", "KST"},     // Asia/Pyongyang
> -     "Qyzylorda Standard Time":         {"+05", "+06"},     // Asia/Qyzylorda
> +     "Qyzylorda Standard Time":         {"+05", "+05"},     // Asia/Qyzylorda
>       "Myanmar Standard Time":           {"+0630", "+0630"}, // Asia/Rangoon
>       "Arab Standard Time":              {"+03", "+03"},     // Asia/Riyadh
>       "Sakhalin Standard Time":          {"+11", "+11"},     // Asia/Sakhalin
> @@ -93,7 +95,7 @@
>       "Taipei Standard Time":            {"CST", "CST"},     // Asia/Taipei
>       "West Asia Standard Time":         {"+05", "+05"},     // Asia/Tashkent
>       "Georgian Standard Time":          {"+04", "+04"},     // Asia/Tbilisi
> -     "Iran Standard Time":              {"+0330", "+0430"}, // Asia/Tehran
> +     "Iran Standard Time":              {"+0330", "+0330"}, // Asia/Tehran
>       "Tokyo Standard Time":             {"JST", "JST"},     // Asia/Tokyo
>       "Tomsk Standard Time":             {"+07", "+07"},     // Asia/Tomsk
>       "Ulaanbaatar Standard Time":       {"+08", "+08"},     // 
> Asia/Ulaanbaatar
> @@ -112,7 +114,6 @@
>       "Lord Howe Standard Time":         {"+1030", "+11"},   // 
> Australia/Lord_Howe
>       "W. Australia Standard Time":      {"AWST", "AWST"},   // 
> Australia/Perth
>       "AUS Eastern Standard Time":       {"AEST", "AEDT"},   // 
> Australia/Sydney
> -     "UTC":                             {"GMT", "GMT"},     // Etc/GMT
>       "UTC-11":                          {"-11", "-11"},     // Etc/GMT+11
>       "Dateline Standard Time":          {"-12", "-12"},     // Etc/GMT+12
>       "UTC-02":                          {"-02", "-02"},     // Etc/GMT+2
> @@ -120,6 +121,7 @@
>       "UTC-09":                          {"-09", "-09"},     // Etc/GMT+9
>       "UTC+12":                          {"+12", "+12"},     // Etc/GMT-12
>       "UTC+13":                          {"+13", "+13"},     // Etc/GMT-13
> +     "UTC":                             {"UTC", "UTC"},     // Etc/UTC
>       "Astrakhan Standard Time":         {"+04", "+04"},     // 
> Europe/Astrakhan
>       "W. Europe Standard Time":         {"CET", "CEST"},    // Europe/Berlin
>       "GTB Standard Time":               {"EET", "EEST"},    // 
> Europe/Bucharest
> @@ -134,20 +136,20 @@
>       "Romance Standard Time":           {"CET", "CEST"},    // Europe/Paris
>       "Russia Time Zone 3":              {"+04", "+04"},     // Europe/Samara
>       "Saratov Standard Time":           {"+04", "+04"},     // Europe/Saratov
> -     "Volgograd Standard Time":         {"+04", "+04"},     // 
> Europe/Volgograd
> +     "Volgograd Standard Time":         {"+03", "+03"},     // 
> Europe/Volgograd
>       "Central European Standard Time":  {"CET", "CEST"},    // Europe/Warsaw
>       "Mauritius Standard Time":         {"+04", "+04"},     // 
> Indian/Mauritius
> -     "Samoa Standard Time":             {"+13", "+14"},     // Pacific/Apia
> +     "Samoa Standard Time":             {"+13", "+13"},     // Pacific/Apia
>       "New Zealand Standard Time":       {"NZST", "NZDT"},   // 
> Pacific/Auckland
>       "Bougainville Standard Time":      {"+11", "+11"},     // 
> Pacific/Bougainville
>       "Chatham Islands Standard Time":   {"+1245", "+1345"}, // 
> Pacific/Chatham
>       "Easter Island Standard Time":     {"-06", "-05"},     // Pacific/Easter
> -     "Fiji Standard Time":              {"+12", "+13"},     // Pacific/Fiji
> +     "Fiji Standard Time":              {"+12", "+12"},     // Pacific/Fiji
>       "Central Pacific Standard Time":   {"+11", "+11"},     // 
> Pacific/Guadalcanal
>       "Hawaiian Standard Time":          {"HST", "HST"},     // 
> Pacific/Honolulu
>       "Line Islands Standard Time":      {"+14", "+14"},     // 
> Pacific/Kiritimati
>       "Marquesas Standard Time":         {"-0930", "-0930"}, // 
> Pacific/Marquesas
> -     "Norfolk Standard Time":           {"+11", "+11"},     // 
> Pacific/Norfolk
> +     "Norfolk Standard Time":           {"+11", "+12"},     // 
> Pacific/Norfolk
>       "West Pacific Standard Time":      {"+10", "+10"},     // 
> Pacific/Port_Moresby
>       "Tonga Standard Time":             {"+13", "+13"},     // 
> Pacific/Tongatapu
>  }
> diff -Nru golang-1.19-1.19.5/src/vendor/golang.org/x/net/http2/hpack/hpack.go 
> golang-1.19-1.19.6/src/vendor/golang.org/x/net/http2/hpack/hpack.go
> --- golang-1.19-1.19.5/src/vendor/golang.org/x/net/http2/hpack/hpack.go       
> 2023-01-10 06:38:24.000000000 +0800
> +++ golang-1.19-1.19.6/src/vendor/golang.org/x/net/http2/hpack/hpack.go       
> 2023-02-14 01:38:48.000000000 +0800
> @@ -359,6 +359,7 @@
>  
>       var hf HeaderField
>       wantStr := d.emitEnabled || it.indexed()
> +     var undecodedName undecodedString
>       if nameIdx > 0 {
>               ihf, ok := d.at(nameIdx)
>               if !ok {
> @@ -366,15 +367,27 @@
>               }
>               hf.Name = ihf.Name
>       } else {
> -             hf.Name, buf, err = d.readString(buf, wantStr)
> +             undecodedName, buf, err = d.readString(buf)
>               if err != nil {
>                       return err
>               }
>       }
> -     hf.Value, buf, err = d.readString(buf, wantStr)
> +     undecodedValue, buf, err := d.readString(buf)
>       if err != nil {
>               return err
>       }
> +     if wantStr {
> +             if nameIdx <= 0 {
> +                     hf.Name, err = d.decodeString(undecodedName)
> +                     if err != nil {
> +                             return err
> +                     }
> +             }
> +             hf.Value, err = d.decodeString(undecodedValue)
> +             if err != nil {
> +                     return err
> +             }
> +     }
>       d.buf = buf
>       if it.indexed() {
>               d.dynTab.add(hf)
> @@ -459,46 +472,52 @@
>       return 0, origP, errNeedMore
>  }
>  
> -// readString decodes an hpack string from p.
> +// readString reads an hpack string from p.
>  //
> -// wantStr is whether s will be used. If false, decompression and
> -// []byte->string garbage are skipped if s will be ignored
> -// anyway. This does mean that huffman decoding errors for non-indexed
> -// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
> -// is returning an error anyway, and because they're not indexed, the error
> -// won't affect the decoding state.
> -func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain 
> []byte, err error) {
> +// It returns a reference to the encoded string data to permit deferring 
> decode costs
> +// until after the caller verifies all data is present.
> +func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, 
> err error) {
>       if len(p) == 0 {
> -             return "", p, errNeedMore
> +             return u, p, errNeedMore
>       }
>       isHuff := p[0]&128 != 0
>       strLen, p, err := readVarInt(7, p)
>       if err != nil {
> -             return "", p, err
> +             return u, p, err
>       }
>       if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
> -             return "", nil, ErrStringLength
> +             // Returning an error here means Huffman decoding errors
> +             // for non-indexed strings past the maximum string length
> +             // are ignored, but the server is returning an error anyway
> +             // and because the string is not indexed the error will not
> +             // affect the decoding state.
> +             return u, nil, ErrStringLength
>       }
>       if uint64(len(p)) < strLen {
> -             return "", p, errNeedMore
> -     }
> -     if !isHuff {
> -             if wantStr {
> -                     s = string(p[:strLen])
> -             }
> -             return s, p[strLen:], nil
> +             return u, p, errNeedMore
>       }
> +     u.isHuff = isHuff
> +     u.b = p[:strLen]
> +     return u, p[strLen:], nil
> +}
>  
> -     if wantStr {
> -             buf := bufPool.Get().(*bytes.Buffer)
> -             buf.Reset() // don't trust others
> -             defer bufPool.Put(buf)
> -             if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != 
> nil {
> -                     buf.Reset()
> -                     return "", nil, err
> -             }
> +type undecodedString struct {
> +     isHuff bool
> +     b      []byte
> +}
> +
> +func (d *Decoder) decodeString(u undecodedString) (string, error) {
> +     if !u.isHuff {
> +             return string(u.b), nil
> +     }
> +     buf := bufPool.Get().(*bytes.Buffer)
> +     buf.Reset() // don't trust others
> +     var s string
> +     err := huffmanDecode(buf, d.maxStrLen, u.b)
> +     if err == nil {
>               s = buf.String()
> -             buf.Reset() // be nice to GC
>       }
> -     return s, p[strLen:], nil
> +     buf.Reset() // be nice to GC
> +     bufPool.Put(buf)
> +     return s, err
>  }
> diff -Nru golang-1.19-1.19.5/VERSION golang-1.19-1.19.6/VERSION
> --- golang-1.19-1.19.5/VERSION        2023-01-10 06:38:00.000000000 +0800
> +++ golang-1.19-1.19.6/VERSION        2023-02-14 01:38:41.000000000 +0800
> @@ -1 +1 @@
> -go1.19.5
> \ No newline at end of file
> +go1.19.6
> \ No newline at end of file


-- 
Sebastian Ramacher


Reply via email to