mirror of
https://github.com/google/bumble.git
synced 2026-05-09 04:08:02 +00:00
fix: address review feedback - use InvalidPacketError and abort on buffer overflow
- att.py: raise core.InvalidPacketError instead of generic ValueError - smp.py: raise core.InvalidPacketError instead of generic ValueError - hfp.py: add MAX_BUFFER_SIZE class constant (64KB) - hfp.py: drop incoming data when it would overflow buffer instead of truncating, preserving existing partial-packet state Per review comments on PR #912 by @zxzxwu.
This commit is contained in:
@@ -42,7 +42,7 @@ from typing_extensions import TypeIs
|
|||||||
|
|
||||||
from bumble import hci, l2cap, utils
|
from bumble import hci, l2cap, utils
|
||||||
from bumble.colors import color
|
from bumble.colors import color
|
||||||
from bumble.core import UUID, InvalidOperationError, ProtocolError
|
from bumble.core import UUID, InvalidOperationError, InvalidPacketError, ProtocolError
|
||||||
from bumble.hci import HCI_Object
|
from bumble.hci import HCI_Object
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@@ -250,7 +250,7 @@ class ATT_PDU:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, pdu: bytes) -> ATT_PDU:
|
def from_bytes(cls, pdu: bytes) -> ATT_PDU:
|
||||||
if not pdu:
|
if not pdu:
|
||||||
raise ValueError("Empty ATT PDU")
|
raise InvalidPacketError("Empty ATT PDU")
|
||||||
op_code = pdu[0]
|
op_code = pdu[0]
|
||||||
|
|
||||||
subclass = ATT_PDU.pdu_classes.get(op_code)
|
subclass = ATT_PDU.pdu_classes.get(op_code)
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ class HfpProtocolError(ProtocolError):
|
|||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
class HfpProtocol:
|
class HfpProtocol:
|
||||||
|
MAX_BUFFER_SIZE: ClassVar[int] = 65536
|
||||||
|
|
||||||
dlc: rfcomm.DLC
|
dlc: rfcomm.DLC
|
||||||
buffer: str
|
buffer: str
|
||||||
lines: collections.deque
|
lines: collections.deque
|
||||||
@@ -88,11 +90,17 @@ class HfpProtocol:
|
|||||||
|
|
||||||
logger.debug(f'<<< Data received: {data}')
|
logger.debug(f'<<< Data received: {data}')
|
||||||
|
|
||||||
|
# Drop incoming data if it would overflow the buffer; keep existing
|
||||||
|
# partial packet state intact so a future clean packet can still parse.
|
||||||
|
if len(self.buffer) + len(data) > self.MAX_BUFFER_SIZE:
|
||||||
|
logger.warning(
|
||||||
|
'HFP buffer overflow (>%d bytes), dropping incoming data',
|
||||||
|
self.MAX_BUFFER_SIZE,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
# Add to the buffer and look for lines
|
# Add to the buffer and look for lines
|
||||||
self.buffer += data
|
self.buffer += data
|
||||||
if len(self.buffer) > 65536:
|
|
||||||
logger.warning("HFP buffer overflow, truncating")
|
|
||||||
self.buffer = self.buffer[-65536:]
|
|
||||||
while (separator := self.buffer.find('\r')) >= 0:
|
while (separator := self.buffer.find('\r')) >= 0:
|
||||||
line = self.buffer[:separator].strip()
|
line = self.buffer[:separator].strip()
|
||||||
self.buffer = self.buffer[separator + 1 :]
|
self.buffer = self.buffer[separator + 1 :]
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ from bumble.colors import color
|
|||||||
from bumble.core import (
|
from bumble.core import (
|
||||||
AdvertisingData,
|
AdvertisingData,
|
||||||
InvalidArgumentError,
|
InvalidArgumentError,
|
||||||
|
InvalidPacketError,
|
||||||
PhysicalTransport,
|
PhysicalTransport,
|
||||||
ProtocolError,
|
ProtocolError,
|
||||||
)
|
)
|
||||||
@@ -216,7 +217,7 @@ class SMP_Command:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, pdu: bytes) -> SMP_Command:
|
def from_bytes(cls, pdu: bytes) -> SMP_Command:
|
||||||
if not pdu:
|
if not pdu:
|
||||||
raise ValueError("Empty SMP PDU")
|
raise InvalidPacketError("Empty SMP PDU")
|
||||||
code = CommandCode(pdu[0])
|
code = CommandCode(pdu[0])
|
||||||
|
|
||||||
subclass = SMP_Command.smp_classes.get(code)
|
subclass = SMP_Command.smp_classes.get(code)
|
||||||
|
|||||||
Reference in New Issue
Block a user