Skip to content

Commit

Permalink
server/conn.go: recover from packet decoding panics
Browse files Browse the repository at this point in the history
  • Loading branch information
cooldogedev committed Jan 20, 2025
1 parent b650d6b commit 321f8fa
Showing 1 changed file with 31 additions and 25 deletions.
56 changes: 31 additions & 25 deletions server/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,38 +263,44 @@ func (c *Conn) read() (pk any, err error) {
case <-c.closed:
return nil, net.ErrClosed
default:
payload, err := c.reader.ReadPacket()
if err != nil {
return nil, err
}
}

if payload[0] != packetDecodeNeeded && payload[0] != packetDecodeNotNeeded {
return nil, fmt.Errorf("unknown decode byte marker %v", payload[0])
}
payload, err := c.reader.ReadPacket()
if err != nil {
return nil, err
}

decompressed, err := snappy.Decode(nil, payload[1:])
if err != nil {
return nil, err
}
if payload[0] != packetDecodeNeeded && payload[0] != packetDecodeNotNeeded {
return nil, fmt.Errorf("unknown decode byte marker %v", payload[0])
}

if payload[0] == packetDecodeNotNeeded {
return decompressed, nil
}
decompressed, err := snappy.Decode(nil, payload[1:])
if err != nil {
return nil, err
}

buf := bytes.NewBuffer(decompressed)
header := &packet.Header{}
if err := header.Read(buf); err != nil {
return nil, err
}
if payload[0] == packetDecodeNotNeeded {
return decompressed, nil
}

buf := bytes.NewBuffer(decompressed)
header := &packet.Header{}
if err := header.Read(buf); err != nil {
return nil, err
}

factory, ok := c.pool[header.PacketID]
if !ok {
return nil, fmt.Errorf("unknown packet ID %v", header.PacketID)
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic while decoding packet %v: %v", header.PacketID, r)
}
pk = factory()
pk.(packet.Packet).Marshal(c.protocol.NewReader(buf, c.shieldID, false))
return pk, nil
}()
factory, ok := c.pool[header.PacketID]
if !ok {
return nil, fmt.Errorf("unknown packet ID %v", header.PacketID)
}
pk = factory()
pk.(packet.Packet).Marshal(c.protocol.NewReader(buf, c.shieldID, false))
return pk, nil
}

// deferPacket defers a packet to be returned later in ReadPacket().
Expand Down

0 comments on commit 321f8fa

Please sign in to comment.