From f2f93ec16c5bc41375b19519321155cb935be605 Mon Sep 17 00:00:00 2001 From: leo <80651389+civilwarinfrance@users.noreply.github.com> Date: Fri, 6 Nov 2026 12:48:09 -0800 Subject: [PATCH] Validate OSC bundle element lengths before parsing --- pythonosc/osc_bundle.py | 6 ++++++ pythonosc/test/test_osc_bundle.py | 23 +++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/pythonosc/osc_bundle.py b/pythonosc/osc_bundle.py index 8868e4d..ee0d3e2 100644 --- a/pythonosc/osc_bundle.py +++ b/pythonosc/osc_bundle.py @@ -50,6 +50,12 @@ def _parse_contents( while self._dgram[index:]: # Get the sub content size. content_size, index = osc_types.get_int(self._dgram, index) + if content_size <= 0 or content_size % 4: + raise ParseError( + "Invalid bundle element size: {}".format(content_size) + ) + if content_size > len(self._dgram) - index: + raise ParseError("Bundle element exceeds the datagram length") # Get the datagram for the sub content. content_dgram = self._dgram[index : index + content_size] # Increment our position index up to the next possible content. diff --git a/pythonosc/test/test_osc_bundle.py b/pythonosc/test/test_osc_bundle.py index d881971..12f5f50 100644 --- a/pythonosc/test/test_osc_bundle.py +++ b/pythonosc/test/test_osc_bundle.py @@ -51,7 +51,7 @@ _DGRAM_BUNDLE_IN_BUNDLE = ( b"#bundle\x00" b"\x00\x00\x00\x00\x00\x00\x00\x01" - b"\x00\x00\x00(" # length of sub bundle: 40 bytes. + b"\x00\x00\x00$" # length of sub bundle: 36 bytes. b"#bundle\x00" b"\x00\x00\x00\x00\x00\x00\x00\x01" b"\x00\x00\x00\x10" @@ -67,7 +67,7 @@ ) _DGRAM_UNKNOWN_TYPE = ( - b"#bundle\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x10iamnotaslash" + b"#bundle\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0ciamnotaslash" ) @@ -118,6 +118,25 @@ def test_raises_on_invalid_datagram(self): osc_bundle.ParseError, osc_bundle.OscBundle, _DGRAM_INVALID_INDEX ) + def test_rejects_oversized_element(self): + message = _DGRAM_SWITCH_GOES_ON[20:] + packet = _DGRAM_EMPTY_BUNDLE + osc_types.write_int(len(message) + 4) + message + with self.assertRaises(osc_bundle.ParseError): + osc_bundle.OscBundle(packet) + + def test_rejects_invalid_element_lengths(self): + for size in (-2147483648, -8, -4, -1, 0, 1, 3, 5): + with self.subTest(size=size): + packet = _DGRAM_EMPTY_BUNDLE + osc_types.write_int(size) + b"abcd" + with self.assertRaises(osc_bundle.ParseError): + osc_bundle.OscBundle(packet) + + def test_rejects_malformed_nested_element(self): + inner = _DGRAM_EMPTY_BUNDLE + osc_types.write_int(0) + packet = _DGRAM_EMPTY_BUNDLE + osc_types.write_int(len(inner)) + inner + with self.assertRaises(osc_bundle.ParseError): + osc_bundle.OscBundle(packet) + def test_unknown_type(self): osc_bundle.OscBundle(_DGRAM_UNKNOWN_TYPE)