Reject invalid control frames when building - #305
Conversation
|
lets see if the CI turn green |
auvipy
left a comment
There was a problem hiding this comment.
test/test_websocket.py .................. [100%]
=================================== FAILURES ===================================
_________ WSFrameParserTest.test_fragmented_control_frame_is_too_large _________
self = <test.test_frame.WSFrameParserTest testMethod=test_fragmented_control_frame_is_too_large>
def test_fragmented_control_frame_is_too_large(self):
bytes = Frame(opcode=OPCODE_PING, body=b'*'*65536, fin=1).build()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test/test_frame.py:202:
self = <ws4py.framing.Frame object at 0x7fc1acf349e0>
def build(self):
"""
Builds a frame from the instance's attributes and returns
its bytes representation.
"""
header = b''
if self.fin > 0x1:
raise ValueError('FIN bit parameter must be 0 or 1')
if 0x3 <= self.opcode <= 0x7 or 0xB <= self.opcode:
raise ValueError('Opcode cannot be a reserved opcode')
if self.opcode in (OPCODE_CLOSE, OPCODE_PING, OPCODE_PONG):
if self.fin != 1:
raise ValueError('Control frames cannot be fragmented')
if self.payload_length > 125:
raise FrameTooLargeException()
E ws4py.exc.FrameTooLargeException
ws4py/framing.py:82: FrameTooLargeException
__________________ WSStreamTest.test_too_large_close_message ___________________
self = <test.test_stream.WSStreamTest testMethod=test_too_large_close_message>
def test_too_large_close_message(self):
payload = struct.pack("!H", 1000) + b'*' * 330
f = Frame(opcode=OPCODE_CLOSE, body=payload,
fin=1, masking_key=os.urandom(4)).build()
^^^^^^^
test/test_stream.py:132:
self = <ws4py.framing.Frame object at 0x7fc1a3daa0c0>
def build(self):
"""
Builds a frame from the instance's attributes and returns
its bytes representation.
"""
header = b''
if self.fin > 0x1:
raise ValueError('FIN bit parameter must be 0 or 1')
if 0x3 <= self.opcode <= 0x7 or 0xB <= self.opcode:
raise ValueError('Opcode cannot be a reserved opcode')
if self.opcode in (OPCODE_CLOSE, OPCODE_PING, OPCODE_PONG):
if self.fin != 1:
raise ValueError('Control frames cannot be fragmented')
if self.payload_length > 125:
raise FrameTooLargeException()
E ws4py.exc.FrameTooLargeException
ws4py/framing.py:82: FrameTooLargeException
=========================== short test summary info ============================
FAILED test/test_frame.py::WSFrameParserTest::test_fragmented_control_frame_is_too_large
FAILED test/test_stream.py::WSStreamTest::test_too_large_close_message - ws4p...
======================== 2 failed, 124 passed in 4.41s =========================
py312: exit 1 (4.63 seconds) /home/runner/work/WebSocket-for-Python/WebSocket-for-Python> pytest pid=2132
py312: FAIL code 1 (12.57=setup[7.94]+cmd[4.63] seconds)
evaluation failed :( (12.58 seconds)
|
The two failing fixtures now build malformed peer bytes directly, preserving their parser/stream checks without asking the validating sender to emit invalid controls. Added sender regressions for fragmentation, the 125/126-byte boundary, and masked/unmasked controls. The rejection cases fail against unchanged upstream framing; all 62 frame/stream tests pass with the fix. Full Windows validation has one separate |
Fixes #304.
Reject fragmented or oversized outgoing Close, Ping and Pong frames. Incoming-invalid-frame tests now construct malformed peer bytes directly, so they continue testing the parser without relying on the sender to generate protocol violations. Add output-boundary regressions for fragmentation, 126-byte rejection and valid empty/125-byte masked and unmasked controls.
Validation: the two rejection regressions fail against unchanged upstream framing and pass with this fix; all 62 frame/stream tests pass on Windows Python 3.13. The full local suite has 128 passes and one unrelated Unix-socket test failure because this Windows interpreter has no
AF_UNIX. The supported Ubuntu/Python CI matrix must be checked on the updated head.Additional validation: the complete suite passes on Linux/Python 3.12 (129 passed). The current-head upstream Actions run requires maintainer approval: https://github.com/Lawouach/WebSocket-for-Python/actions/runs/37199966249.