From 5c3e11bd0b5c0a86e5beffcd4339b86a902b21c3 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Mon, 6 Feb 2023 10:03:44 -0800 Subject: [PATCH] [release-branch.go1.19] net/http: update bundled golang.org/x/net/http2 Disable cmd/internal/moddeps test, since this update includes PRIVATE track fixes. Fixes CVE-2022-41723 Fixes #58355 Updates #57855 Change-Id: Ie870562a6f6e44e4e8f57db6a0dde1a41a2b090c Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728939 Reviewed-by: Damien Neil Reviewed-by: Julie Qiu Reviewed-by: Tatiana Bradley Run-TryBot: Roland Shoemaker Reviewed-on: https://go-review.googlesource.com/c/go/+/468118 TryBot-Result: Gopher Robot Run-TryBot: Michael Pratt Auto-Submit: Michael Pratt Reviewed-by: Than McIntosh --- src/cmd/internal/moddeps/moddeps_test.go | 2 +- .../golang.org/x/net/http2/hpack/hpack.go | 79 ++++++++++++------- 2 files changed, 50 insertions(+), 31 deletions(-) Index: go/src/cmd/internal/moddeps/moddeps_test.go =================================================================== --- go.orig/src/cmd/internal/moddeps/moddeps_test.go +++ go/src/cmd/internal/moddeps/moddeps_test.go @@ -34,7 +34,7 @@ import ( // See issues 36852, 41409, and 43687. // (Also see golang.org/issue/27348.) func TestAllDependencies(t *testing.T) { - t.Skip("TODO(#57008): 1.18.9 contains unreleased changes from vendored modules") + t.Skip("TODO(#58355): 1.18.9 contains unreleased changes from vendored modules") goBin := testenv.GoToolPath(t) Index: go/src/vendor/golang.org/x/net/http2/hpack/hpack.go =================================================================== --- go.orig/src/vendor/golang.org/x/net/http2/hpack/hpack.go +++ go/src/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -359,6 +359,7 @@ func (d *Decoder) parseFieldLiteral(n ui 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 @@ func (d *Decoder) parseFieldLiteral(n ui } 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 @@ func readVarInt(n byte, p []byte) (i uin 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 }