fix(deps): update module golang.org/x/crypto to v0.45.0 [security]

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
renovate[bot]
2025-11-20 05:13:00 +00:00
committed by GitHub
parent 6541fc4fb2
commit f8b968246d
12 changed files with 191 additions and 77 deletions

4
go.mod
View File

@@ -67,8 +67,8 @@ require (
go.podman.io/common v0.66.1-0.20251112195944-4afce3558e66 go.podman.io/common v0.66.1-0.20251112195944-4afce3558e66
go.podman.io/image/v5 v5.38.1-0.20251112195944-4afce3558e66 go.podman.io/image/v5 v5.38.1-0.20251112195944-4afce3558e66
go.podman.io/storage v1.61.1-0.20251112195944-4afce3558e66 go.podman.io/storage v1.61.1-0.20251112195944-4afce3558e66
golang.org/x/crypto v0.44.0 golang.org/x/crypto v0.45.0
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 golang.org/x/net v0.47.0
golang.org/x/sync v0.18.0 golang.org/x/sync v0.18.0
golang.org/x/sys v0.38.0 golang.org/x/sys v0.38.0
golang.org/x/term v0.37.0 golang.org/x/term v0.37.0

8
go.sum
View File

@@ -489,8 +489,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -515,8 +515,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View File

@@ -203,6 +203,9 @@ func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse
for len(constraints) != 0 { for len(constraints) != 0 {
switch constraints[0] { switch constraints[0] {
case agentConstrainLifetime: case agentConstrainLifetime:
if len(constraints) < 5 {
return 0, false, nil, io.ErrUnexpectedEOF
}
lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5]) lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5])
constraints = constraints[5:] constraints = constraints[5:]
case agentConstrainConfirm: case agentConstrainConfirm:

View File

@@ -1490,6 +1490,7 @@ type openSSHEncryptedPrivateKey struct {
NumKeys uint32 NumKeys uint32
PubKey []byte PubKey []byte
PrivKeyBlock []byte PrivKeyBlock []byte
Rest []byte `ssh:"rest"`
} }
type openSSHPrivateKey struct { type openSSHPrivateKey struct {

View File

@@ -106,6 +106,13 @@ func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) {
if !ok { if !ok {
return nil, errors.New("parse uint32 failed") return nil, errors.New("parse uint32 failed")
} }
// Each ASN.1 encoded OID must have a minimum
// of 2 bytes; 64 maximum mechanisms is an
// arbitrary, but reasonable ceiling.
const maxMechs = 64
if n > maxMechs || int(n)*2 > len(rest) {
return nil, errors.New("invalid mechanism count")
}
s := &userAuthRequestGSSAPI{ s := &userAuthRequestGSSAPI{
N: n, N: n,
OIDS: make([]asn1.ObjectIdentifier, n), OIDS: make([]asn1.ObjectIdentifier, n),
@@ -122,7 +129,6 @@ func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) {
if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil { if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil {
return nil, err return nil, err
} }
} }
return s, nil return s, nil
} }

View File

@@ -44,7 +44,7 @@ func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
if !ok { if !ok {
return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer") return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer")
} }
ch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: "unix"}) ch := c.forwards.add("unix", socketPath)
return &unixListener{socketPath, c, ch}, nil return &unixListener{socketPath, c, ch}, nil
} }
@@ -96,7 +96,7 @@ func (l *unixListener) Accept() (net.Conn, error) {
// Close closes the listener. // Close closes the listener.
func (l *unixListener) Close() error { func (l *unixListener) Close() error {
// this also closes the listener. // this also closes the listener.
l.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: "unix"}) l.conn.forwards.remove("unix", l.socketPath)
m := streamLocalChannelForwardMsg{ m := streamLocalChannelForwardMsg{
l.socketPath, l.socketPath,
} }

View File

@@ -11,6 +11,7 @@ import (
"io" "io"
"math/rand" "math/rand"
"net" "net"
"net/netip"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@@ -22,14 +23,21 @@ import (
// the returned net.Listener. The listener must be serviced, or the // the returned net.Listener. The listener must be serviced, or the
// SSH connection may hang. // SSH connection may hang.
// N must be "tcp", "tcp4", "tcp6", or "unix". // N must be "tcp", "tcp4", "tcp6", or "unix".
//
// If the address is a hostname, it is sent to the remote peer as-is, without
// being resolved locally, and the Listener Addr method will return a zero IP.
func (c *Client) Listen(n, addr string) (net.Listener, error) { func (c *Client) Listen(n, addr string) (net.Listener, error) {
switch n { switch n {
case "tcp", "tcp4", "tcp6": case "tcp", "tcp4", "tcp6":
laddr, err := net.ResolveTCPAddr(n, addr) host, portStr, err := net.SplitHostPort(addr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return c.ListenTCP(laddr) port, err := strconv.ParseInt(portStr, 10, 32)
if err != nil {
return nil, err
}
return c.listenTCPInternal(host, int(port))
case "unix": case "unix":
return c.ListenUnix(addr) return c.ListenUnix(addr)
default: default:
@@ -102,15 +110,24 @@ func (c *Client) handleForwards() {
// ListenTCP requests the remote peer open a listening socket // ListenTCP requests the remote peer open a listening socket
// on laddr. Incoming connections will be available by calling // on laddr. Incoming connections will be available by calling
// Accept on the returned net.Listener. // Accept on the returned net.Listener.
//
// ListenTCP accepts an IP address, to provide a hostname use [Client.Listen]
// with "tcp", "tcp4", or "tcp6" network instead.
func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) { func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
c.handleForwardsOnce.Do(c.handleForwards) c.handleForwardsOnce.Do(c.handleForwards)
if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) { if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
return c.autoPortListenWorkaround(laddr) return c.autoPortListenWorkaround(laddr)
} }
return c.listenTCPInternal(laddr.IP.String(), laddr.Port)
}
func (c *Client) listenTCPInternal(host string, port int) (net.Listener, error) {
c.handleForwardsOnce.Do(c.handleForwards)
m := channelForwardMsg{ m := channelForwardMsg{
laddr.IP.String(), host,
uint32(laddr.Port), uint32(port),
} }
// send message // send message
ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m)) ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m))
@@ -123,20 +140,33 @@ func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
// If the original port was 0, then the remote side will // If the original port was 0, then the remote side will
// supply a real port number in the response. // supply a real port number in the response.
if laddr.Port == 0 { if port == 0 {
var p struct { var p struct {
Port uint32 Port uint32
} }
if err := Unmarshal(resp, &p); err != nil { if err := Unmarshal(resp, &p); err != nil {
return nil, err return nil, err
} }
laddr.Port = int(p.Port) port = int(p.Port)
} }
// Construct a local address placeholder for the remote listener. If the
// original host is an IP address, preserve it so that Listener.Addr()
// reports the same IP. If the host is a hostname or cannot be parsed as an
// IP, fall back to IPv4zero. The port field is always set, even if the
// original port was 0, because in that case the remote server will assign
// one, allowing callers to determine which port was selected.
ip := net.IPv4zero
if parsed, err := netip.ParseAddr(host); err == nil {
ip = net.IP(parsed.AsSlice())
}
laddr := &net.TCPAddr{
IP: ip,
Port: port,
}
addr := net.JoinHostPort(host, strconv.FormatInt(int64(port), 10))
ch := c.forwards.add("tcp", addr)
// Register this forward, using the port number we obtained. return &tcpListener{laddr, addr, c, ch}, nil
ch := c.forwards.add(laddr)
return &tcpListener{laddr, c, ch}, nil
} }
// forwardList stores a mapping between remote // forwardList stores a mapping between remote
@@ -149,7 +179,8 @@ type forwardList struct {
// forwardEntry represents an established mapping of a laddr on a // forwardEntry represents an established mapping of a laddr on a
// remote ssh server to a channel connected to a tcpListener. // remote ssh server to a channel connected to a tcpListener.
type forwardEntry struct { type forwardEntry struct {
laddr net.Addr addr string // host:port or socket path
network string // tcp or unix
c chan forward c chan forward
} }
@@ -161,11 +192,12 @@ type forward struct {
raddr net.Addr // the raddr of the incoming connection raddr net.Addr // the raddr of the incoming connection
} }
func (l *forwardList) add(addr net.Addr) chan forward { func (l *forwardList) add(n, addr string) chan forward {
l.Lock() l.Lock()
defer l.Unlock() defer l.Unlock()
f := forwardEntry{ f := forwardEntry{
laddr: addr, addr: addr,
network: n,
c: make(chan forward, 1), c: make(chan forward, 1),
} }
l.entries = append(l.entries, f) l.entries = append(l.entries, f)
@@ -185,17 +217,18 @@ func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) {
if port == 0 || port > 65535 { if port == 0 || port > 65535 {
return nil, fmt.Errorf("ssh: port number out of range: %d", port) return nil, fmt.Errorf("ssh: port number out of range: %d", port)
} }
ip := net.ParseIP(string(addr)) ip, err := netip.ParseAddr(addr)
if ip == nil { if err != nil {
return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr) return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr)
} }
return &net.TCPAddr{IP: ip, Port: int(port)}, nil return &net.TCPAddr{IP: net.IP(ip.AsSlice()), Port: int(port)}, nil
} }
func (l *forwardList) handleChannels(in <-chan NewChannel) { func (l *forwardList) handleChannels(in <-chan NewChannel) {
for ch := range in { for ch := range in {
var ( var (
laddr net.Addr addr string
network string
raddr net.Addr raddr net.Addr
err error err error
) )
@@ -207,40 +240,34 @@ func (l *forwardList) handleChannels(in <-chan NewChannel) {
continue continue
} }
// RFC 4254 section 7.2 specifies that incoming // RFC 4254 section 7.2 specifies that incoming addresses should
// addresses should list the address, in string // list the address that was connected, in string format. It is the
// format. It is implied that this should be an IP // same address used in the tcpip-forward request. The originator
// address, as it would be impossible to connect to it // address is an IP address instead.
// otherwise. addr = net.JoinHostPort(payload.Addr, strconv.FormatUint(uint64(payload.Port), 10))
laddr, err = parseTCPAddr(payload.Addr, payload.Port)
if err != nil {
ch.Reject(ConnectionFailed, err.Error())
continue
}
raddr, err = parseTCPAddr(payload.OriginAddr, payload.OriginPort) raddr, err = parseTCPAddr(payload.OriginAddr, payload.OriginPort)
if err != nil { if err != nil {
ch.Reject(ConnectionFailed, err.Error()) ch.Reject(ConnectionFailed, err.Error())
continue continue
} }
network = "tcp"
case "forwarded-streamlocal@openssh.com": case "forwarded-streamlocal@openssh.com":
var payload forwardedStreamLocalPayload var payload forwardedStreamLocalPayload
if err = Unmarshal(ch.ExtraData(), &payload); err != nil { if err = Unmarshal(ch.ExtraData(), &payload); err != nil {
ch.Reject(ConnectionFailed, "could not parse forwarded-streamlocal@openssh.com payload: "+err.Error()) ch.Reject(ConnectionFailed, "could not parse forwarded-streamlocal@openssh.com payload: "+err.Error())
continue continue
} }
laddr = &net.UnixAddr{ addr = payload.SocketPath
Name: payload.SocketPath,
Net: "unix",
}
raddr = &net.UnixAddr{ raddr = &net.UnixAddr{
Name: "@", Name: "@",
Net: "unix", Net: "unix",
} }
network = "unix"
default: default:
panic(fmt.Errorf("ssh: unknown channel type %s", channelType)) panic(fmt.Errorf("ssh: unknown channel type %s", channelType))
} }
if ok := l.forward(laddr, raddr, ch); !ok { if ok := l.forward(network, addr, raddr, ch); !ok {
// Section 7.2, implementations MUST reject spurious incoming // Section 7.2, implementations MUST reject spurious incoming
// connections. // connections.
ch.Reject(Prohibited, "no forward for address") ch.Reject(Prohibited, "no forward for address")
@@ -252,11 +279,11 @@ func (l *forwardList) handleChannels(in <-chan NewChannel) {
// remove removes the forward entry, and the channel feeding its // remove removes the forward entry, and the channel feeding its
// listener. // listener.
func (l *forwardList) remove(addr net.Addr) { func (l *forwardList) remove(n, addr string) {
l.Lock() l.Lock()
defer l.Unlock() defer l.Unlock()
for i, f := range l.entries { for i, f := range l.entries {
if addr.Network() == f.laddr.Network() && addr.String() == f.laddr.String() { if n == f.network && addr == f.addr {
l.entries = append(l.entries[:i], l.entries[i+1:]...) l.entries = append(l.entries[:i], l.entries[i+1:]...)
close(f.c) close(f.c)
return return
@@ -274,11 +301,11 @@ func (l *forwardList) closeAll() {
l.entries = nil l.entries = nil
} }
func (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool { func (l *forwardList) forward(n, addr string, raddr net.Addr, ch NewChannel) bool {
l.Lock() l.Lock()
defer l.Unlock() defer l.Unlock()
for _, f := range l.entries { for _, f := range l.entries {
if laddr.Network() == f.laddr.Network() && laddr.String() == f.laddr.String() { if n == f.network && addr == f.addr {
f.c <- forward{newCh: ch, raddr: raddr} f.c <- forward{newCh: ch, raddr: raddr}
return true return true
} }
@@ -288,6 +315,7 @@ func (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool {
type tcpListener struct { type tcpListener struct {
laddr *net.TCPAddr laddr *net.TCPAddr
addr string
conn *Client conn *Client
in <-chan forward in <-chan forward
@@ -314,13 +342,21 @@ func (l *tcpListener) Accept() (net.Conn, error) {
// Close closes the listener. // Close closes the listener.
func (l *tcpListener) Close() error { func (l *tcpListener) Close() error {
host, port, err := net.SplitHostPort(l.addr)
if err != nil {
return err
}
rport, err := strconv.ParseUint(port, 10, 32)
if err != nil {
return err
}
m := channelForwardMsg{ m := channelForwardMsg{
l.laddr.IP.String(), host,
uint32(l.laddr.Port), uint32(rport),
} }
// this also closes the listener. // this also closes the listener.
l.conn.forwards.remove(l.laddr) l.conn.forwards.remove("tcp", l.addr)
ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m)) ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m))
if err == nil && !ok { if err == nil && !ok {
err = errors.New("ssh: cancel-tcpip-forward failed") err = errors.New("ssh: cancel-tcpip-forward failed")

View File

@@ -1189,7 +1189,7 @@ var defaultRFC9218Priority = PriorityParam{
// PriorityParam struct below is a superset of both schemes. The exported // PriorityParam struct below is a superset of both schemes. The exported
// symbols are from RFC 7540 and the non-exported ones are from RFC 9218. // symbols are from RFC 7540 and the non-exported ones are from RFC 9218.
// PriorityParam are the stream prioritzation parameters. // PriorityParam are the stream prioritization parameters.
type PriorityParam struct { type PriorityParam struct {
// StreamDep is a 31-bit stream identifier for the // StreamDep is a 31-bit stream identifier for the
// stream that this stream depends on. Zero means no // stream that this stream depends on. Zero means no

View File

@@ -9,6 +9,7 @@ package http2
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"compress/flate"
"compress/gzip" "compress/gzip"
"context" "context"
"crypto/rand" "crypto/rand"
@@ -3076,35 +3077,102 @@ type erringRoundTripper struct{ err error }
func (rt erringRoundTripper) RoundTripErr() error { return rt.err } func (rt erringRoundTripper) RoundTripErr() error { return rt.err }
func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err } func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
var errConcurrentReadOnResBody = errors.New("http2: concurrent read on response body")
// gzipReader wraps a response body so it can lazily // gzipReader wraps a response body so it can lazily
// call gzip.NewReader on the first call to Read // get gzip.Reader from the pool on the first call to Read.
// After Close is called it puts gzip.Reader to the pool immediately
// if there is no Read in progress or later when Read completes.
type gzipReader struct { type gzipReader struct {
_ incomparable _ incomparable
body io.ReadCloser // underlying Response.Body body io.ReadCloser // underlying Response.Body
zr *gzip.Reader // lazily-initialized gzip reader mu sync.Mutex // guards zr and zerr
zerr error // sticky error zr *gzip.Reader // stores gzip reader from the pool between reads
zerr error // sticky gzip reader init error or sentinel value to detect concurrent read and read after close
}
type eofReader struct{}
func (eofReader) Read([]byte) (int, error) { return 0, io.EOF }
func (eofReader) ReadByte() (byte, error) { return 0, io.EOF }
var gzipPool = sync.Pool{New: func() any { return new(gzip.Reader) }}
// gzipPoolGet gets a gzip.Reader from the pool and resets it to read from r.
func gzipPoolGet(r io.Reader) (*gzip.Reader, error) {
zr := gzipPool.Get().(*gzip.Reader)
if err := zr.Reset(r); err != nil {
gzipPoolPut(zr)
return nil, err
}
return zr, nil
}
// gzipPoolPut puts a gzip.Reader back into the pool.
func gzipPoolPut(zr *gzip.Reader) {
// Reset will allocate bufio.Reader if we pass it anything
// other than a flate.Reader, so ensure that it's getting one.
var r flate.Reader = eofReader{}
zr.Reset(r)
gzipPool.Put(zr)
}
// acquire returns a gzip.Reader for reading response body.
// The reader must be released after use.
func (gz *gzipReader) acquire() (*gzip.Reader, error) {
gz.mu.Lock()
defer gz.mu.Unlock()
if gz.zerr != nil {
return nil, gz.zerr
}
if gz.zr == nil {
gz.zr, gz.zerr = gzipPoolGet(gz.body)
if gz.zerr != nil {
return nil, gz.zerr
}
}
ret := gz.zr
gz.zr, gz.zerr = nil, errConcurrentReadOnResBody
return ret, nil
}
// release returns the gzip.Reader to the pool if Close was called during Read.
func (gz *gzipReader) release(zr *gzip.Reader) {
gz.mu.Lock()
defer gz.mu.Unlock()
if gz.zerr == errConcurrentReadOnResBody {
gz.zr, gz.zerr = zr, nil
} else { // fs.ErrClosed
gzipPoolPut(zr)
}
}
// close returns the gzip.Reader to the pool immediately or
// signals release to do so after Read completes.
func (gz *gzipReader) close() {
gz.mu.Lock()
defer gz.mu.Unlock()
if gz.zerr == nil && gz.zr != nil {
gzipPoolPut(gz.zr)
gz.zr = nil
}
gz.zerr = fs.ErrClosed
} }
func (gz *gzipReader) Read(p []byte) (n int, err error) { func (gz *gzipReader) Read(p []byte) (n int, err error) {
if gz.zerr != nil { zr, err := gz.acquire()
return 0, gz.zerr
}
if gz.zr == nil {
gz.zr, err = gzip.NewReader(gz.body)
if err != nil { if err != nil {
gz.zerr = err
return 0, err return 0, err
} }
} defer gz.release(zr)
return gz.zr.Read(p)
return zr.Read(p)
} }
func (gz *gzipReader) Close() error { func (gz *gzipReader) Close() error {
if err := gz.body.Close(); err != nil { gz.close()
return err
} return gz.body.Close()
gz.zerr = fs.ErrClosed
return nil
} }
type errorReader struct{ err error } type errorReader struct{ err error }

View File

@@ -214,8 +214,8 @@ func (z sortPriorityNodeSiblingsRFC7540) Swap(i, k int) { z[i], z[k] = z[k], z[i
func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool { func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool {
// Prefer the subtree that has sent fewer bytes relative to its weight. // Prefer the subtree that has sent fewer bytes relative to its weight.
// See sections 5.3.2 and 5.3.4. // See sections 5.3.2 and 5.3.4.
wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes) wi, bi := float64(z[i].weight)+1, float64(z[i].subtreeBytes)
wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes) wk, bk := float64(z[k].weight)+1, float64(z[k].subtreeBytes)
if bi == 0 && bk == 0 { if bi == 0 && bk == 0 {
return wi >= wk return wi >= wk
} }

View File

@@ -39,7 +39,7 @@ type priorityWriteSchedulerRFC9218 struct {
prioritizeIncremental bool prioritizeIncremental bool
} }
func newPriorityWriteSchedulerRFC9128() WriteScheduler { func newPriorityWriteSchedulerRFC9218() WriteScheduler {
ws := &priorityWriteSchedulerRFC9218{ ws := &priorityWriteSchedulerRFC9218{
streams: make(map[uint32]streamMetadata), streams: make(map[uint32]streamMetadata),
} }

4
vendor/modules.txt vendored
View File

@@ -986,7 +986,7 @@ go.yaml.in/yaml/v2
# go.yaml.in/yaml/v3 v3.0.4 # go.yaml.in/yaml/v3 v3.0.4
## explicit; go 1.16 ## explicit; go 1.16
go.yaml.in/yaml/v3 go.yaml.in/yaml/v3
# golang.org/x/crypto v0.44.0 # golang.org/x/crypto v0.45.0
## explicit; go 1.24.0 ## explicit; go 1.24.0
golang.org/x/crypto/argon2 golang.org/x/crypto/argon2
golang.org/x/crypto/blake2b golang.org/x/crypto/blake2b
@@ -1020,7 +1020,7 @@ golang.org/x/crypto/xts
# golang.org/x/mod v0.29.0 # golang.org/x/mod v0.29.0
## explicit; go 1.24.0 ## explicit; go 1.24.0
golang.org/x/mod/semver golang.org/x/mod/semver
# golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 # golang.org/x/net v0.47.0
## explicit; go 1.24.0 ## explicit; go 1.24.0
golang.org/x/net/bpf golang.org/x/net/bpf
golang.org/x/net/html golang.org/x/net/html