Skip to content

Commit 758d056

Browse files
committed
Be more tolerant of badly formed blocks in LLUDP
This helps us deal with badly formed ImprovedInstantMessage messages sent by newer viewers.
1 parent 67e07a1 commit 758d056

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

hippolyzer/lib/base/message/udpdeserializer.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ def parse_message_body(self, msg: Message):
168168
current_template = self.template_dict.get_template_by_name(msg.name)
169169
reader.seek(current_template.get_msg_freq_num_len() + msg.offset)
170170

171+
ran_off_end = False
171172
for tmpl_block in current_template.blocks:
172173
# EOF?
173174
if not len(reader):
@@ -200,9 +201,21 @@ def parse_message_body(self, msg: Message):
200201
reader=reader,
201202
tmpl_variable=tmpl_variable,
202203
)
203-
except:
204+
except se.ReadPastEndError:
205+
# Ran off end of packet. Remove the partially-created
206+
# block and bail out so reserialization doesn't include
207+
# blocks that weren't in the original message.
208+
LOG.debug(f"Ran off end of {msg.name} while parsing {context_str}")
209+
msg.blocks[tmpl_block.name].pop()
210+
ran_off_end = True
211+
break
212+
except Exception:
204213
LOG.exception(f"Raised while parsing var in {context_str}")
205214
raise
215+
if ran_off_end:
216+
break
217+
if ran_off_end:
218+
break
206219

207220
if not msg.blocks and current_template.blocks:
208221
raise exc.MessageDeserializationError("message", "message is empty")

hippolyzer/lib/base/serialization.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
from hippolyzer.lib.base.multidict import OrderedMultiDict
1919

2020

21+
class ReadPastEndError(ValueError):
22+
"""Raised when a read would go past the end of the buffer"""
23+
24+
2125
SERIALIZABLE_TYPE = Union["SerializableBase", Type["SerializableBase"]]
2226
SUBFIELD_SERIALIZERS: Dict[Tuple[str, str, str], "BaseSubfieldSerializer"] = {}
2327
HTTP_SERIALIZERS: Dict[str, "BaseHTTPSerializer"] = {}
@@ -224,7 +228,7 @@ def seek(self, pos: int, whence: int = SEEK_SET):
224228
def read_bytes(self, num_bytes, peek=False, to_bytes=False, check_len=True):
225229
end_pos = self._pos + num_bytes
226230
if end_pos > self._len and check_len:
227-
raise ValueError(f"{len(self)} bytes left, needed {num_bytes}")
231+
raise ReadPastEndError(f"{len(self)} bytes left, needed {num_bytes}")
228232

229233
read_bytes = self._buffer[self._pos:end_pos]
230234
if to_bytes:

0 commit comments

Comments
 (0)