diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 750102f..145c15e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,7 +19,8 @@ dev **Bugfixes** -- +- Reject oversized frame bodies in ``Frame.serialize()`` instead of silently + truncating their 24-bit serialized length. 6.1.0 (2025-01-22) ------------------ diff --git a/src/hyperframe/frame.py b/src/hyperframe/frame.py index 5bab673..8e6c950 100644 --- a/src/hyperframe/frame.py +++ b/src/hyperframe/frame.py @@ -159,6 +159,10 @@ def serialize(self) -> bytes: body = self.serialize_body() self.body_len = len(body) + if self.body_len > FRAME_MAX_ALLOWED_LEN: + msg = f"Frame body exceeds maximum allowed length: {self.body_len} > {FRAME_MAX_ALLOWED_LEN}" + raise InvalidFrameError(msg) + # Build the common frame header. # First, get the flags. flags = 0 diff --git a/tests/test_frames.py b/tests/test_frames.py index b683354..c4fd7ad 100644 --- a/tests/test_frames.py +++ b/tests/test_frames.py @@ -112,6 +112,29 @@ def test_cannot_parse_invalid_frame_header(self): with pytest.raises(InvalidFrameError): Frame.parse_frame_header(b'\x00\x00\x08\x00\x01\x00\x00\x00') + @pytest.mark.parametrize('frame_type', [DataFrame, ContinuationFrame]) + def test_serialize_maximum_frame_length(self, frame_type): + f = frame_type(1, data=b'x' * 0xFFFFFF) + wire = f.serialize() + + assert wire[:3] == b'\xFF\xFF\xFF' + assert f.body_len == len(wire) - 9 == 0xFFFFFF + assert decode_frame(wire).data == f.data + + @pytest.mark.parametrize('frame_type', [DataFrame, ContinuationFrame]) + @pytest.mark.parametrize('body_length', [0x1000000, 0x1000001]) + def test_serialize_rejects_unrepresentable_frame_length(self, frame_type, body_length): + f = frame_type(1, data=b'x' * body_length) + + with pytest.raises(InvalidFrameError): + f.serialize() + + def test_serialize_length_limit_includes_padding_length_field(self): + f = DataFrame(1, data=b'x' * 0xFFFFFF, flags=['PADDED']) + + with pytest.raises(InvalidFrameError): + f.serialize() + class TestDataFrame: payload = b'\x00\x00\x08\x00\x01\x00\x00\x00\x01testdata'