Skip to content

Commit e7254fb

Browse files
committed
Cover frame header field boundaries and invalid sizes
1 parent 632e309 commit e7254fb

1 file changed

Lines changed: 55 additions & 0 deletions

File tree

‎tests/test_frame_header.py‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import pytest
2+
3+
from hyperframe.exceptions import InvalidFrameError, UnknownFrameError
4+
from hyperframe.frame import DataFrame, ExtensionFrame, Frame
5+
6+
7+
@pytest.mark.parametrize('length', [0, 0xFF, 0x100, 0xFFFF, 0x10000, 0xFFFFFF])
8+
def test_frame_header_length_boundaries(length):
9+
header = length.to_bytes(3, 'big') + b'\x00\x00\x00\x00\x00\x01'
10+
frame, parsed_length = Frame.parse_frame_header(memoryview(header))
11+
12+
assert isinstance(frame, DataFrame)
13+
assert parsed_length == length
14+
assert frame.stream_id == 1
15+
16+
17+
@pytest.mark.parametrize('stream_id', [1, 0xFF, 0x100, 0xFFFF, 0x10000, 0x7FFFFFFF])
18+
@pytest.mark.parametrize('reserved', [0, 0x80000000])
19+
def test_frame_header_preserves_stream_id_bits(stream_id, reserved):
20+
header = b'\x00' * 5 + (stream_id | reserved).to_bytes(4, 'big')
21+
frame, length = Frame.parse_frame_header(memoryview(header))
22+
23+
assert frame.stream_id == stream_id
24+
assert length == 0
25+
26+
27+
@pytest.mark.parametrize('strict', [False, True])
28+
@pytest.mark.parametrize('frame_type,length,flags', [
29+
(0x0B, 0, 0x80),
30+
(0x80, 0x10000, 0xFF),
31+
(0xFF, 0xFFFFFF, 0x7F),
32+
])
33+
def test_unknown_frame_header_boundaries(frame_type, length, flags, strict):
34+
header = length.to_bytes(3, 'big') + bytes([frame_type, flags]) + b'\x00\x00\x00\x01'
35+
36+
if strict:
37+
with pytest.raises(UnknownFrameError) as excinfo:
38+
Frame.parse_frame_header(memoryview(header), strict=True)
39+
assert excinfo.value.frame_type == frame_type
40+
assert excinfo.value.length == length
41+
return
42+
43+
frame, parsed_length = Frame.parse_frame_header(memoryview(header))
44+
assert isinstance(frame, ExtensionFrame)
45+
assert frame.type == frame_type
46+
assert frame.flag_byte == flags
47+
assert parsed_length == length
48+
assert frame.stream_id == 1
49+
50+
51+
@pytest.mark.parametrize('header_length', [*range(9), 10, 18])
52+
def test_frame_header_requires_exactly_nine_bytes(header_length):
53+
header = b'\x00' * 8 + b'\x01' + b'\x00' * 9
54+
with pytest.raises(InvalidFrameError):
55+
Frame.parse_frame_header(memoryview(header)[:header_length])

0 commit comments

Comments
 (0)