From c72b205d873971f87b70932742850ad0a331f157 Mon Sep 17 00:00:00 2001 From: Alex X Date: Tue, 18 Nov 2025 20:38:04 +0300 Subject: [PATCH] Fix panic for HomeKit server proxy mode #1940 --- pkg/hap/hds/hds.go | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/pkg/hap/hds/hds.go b/pkg/hap/hds/hds.go index 60ee05d2..0e299919 100644 --- a/pkg/hap/hds/hds.go +++ b/pkg/hap/hds/hds.go @@ -5,6 +5,7 @@ import ( "bufio" "encoding/binary" "encoding/json" + "errors" "io" "net" "time" @@ -68,13 +69,13 @@ func (c *Conn) MarshalJSON() ([]byte, error) { return json.Marshal(conn) } -func (c *Conn) Read(p []byte) (n int, err error) { +func (c *Conn) read() (b []byte, err error) { verify := make([]byte, 4) if _, err = io.ReadFull(c.rd, verify); err != nil { return } - n = int(binary.BigEndian.Uint32(verify) & 0xFFFFFF) + n := int(binary.BigEndian.Uint32(verify) & 0xFFFFFF) ciphertext := make([]byte, n+hap.Overhead) if _, err = io.ReadFull(c.rd, ciphertext); err != nil { @@ -85,15 +86,46 @@ func (c *Conn) Read(p []byte) (n int, err error) { binary.LittleEndian.PutUint64(nonce, c.decryptCnt) c.decryptCnt++ - _, err = chacha20poly1305.DecryptAndVerify(c.decryptKey, p[:0], nonce, ciphertext, verify) - c.recv += n + + return chacha20poly1305.DecryptAndVerify(c.decryptKey, ciphertext[:0], nonce, ciphertext, verify) +} + +func (c *Conn) Read(p []byte) (n int, err error) { + b, err := c.read() + if err != nil { + return 0, err + } + n = copy(p, b) + if len(b) > n { + err = errors.New("hds: read buffer too small") + } return } +func (c *Conn) WriteTo(w io.Writer) (int64, error) { + var total int64 + for { + b, err := c.read() + if err != nil { + return total, err + } + + n, err := w.Write(b) + total += int64(n) + if err != nil { + return total, err + } + } +} + func (c *Conn) Write(b []byte) (n int, err error) { n = len(b) + if n > 0xFFFFFF { + return 0, errors.New("hds: write buffer too big") + } + verify := make([]byte, 4) binary.BigEndian.PutUint32(verify, 0x01000000|uint32(n)) if _, err = c.wr.Write(verify); err != nil {