Skip to content

Commit 5cdc707

Browse files
Kriechipgjones
authored andcommitted
SETTINGS: fix mutual exclusion of ACK and settings body
1 parent abe6757 commit 5cdc707

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

HISTORY.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Release History
1515
- Fixed promised stream id parsing for ``PushPromiseFrame``.
1616
- Fixed unchecked frame length for ``WindowUpdateFrame``. It now correctly raises ``InvalidFrameError``.
1717
- Fixed window increment value range validation. It must be 1 <= increment <= 2^31-1.
18+
- Fixed parsing of ``SettingsFrame`` with mutual exclusion of ACK flag and payload.
1819

1920
**Other Changes**
2021

hyperframe/frame.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,12 @@ def serialize_body(self):
425425
for setting, value in self.settings.items()])
426426

427427
def parse_body(self, data):
428+
if 'ACK' in self.flags and len(data) > 0:
429+
raise InvalidFrameError(
430+
"SETTINGS ack frame must not have payload: got %s bytes" %
431+
len(data)
432+
)
433+
428434
body_len = 0
429435
for i in range(0, len(data), 6):
430436
try:

test/test_frames.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,14 +361,26 @@ def test_settings_frame_ack_and_settings(self):
361361
with pytest.raises(ValueError):
362362
SettingsFrame(settings=self.settings, flags=('ACK',))
363363

364+
with pytest.raises(ValueError):
365+
decode_frame(self.serialized)
366+
364367
def test_settings_frame_parses_properly(self):
365-
f = decode_frame(self.serialized)
368+
# unset the ACK flag to allow correct parsing
369+
data = self.serialized[:4] + b"\x00" + self.serialized[5:]
370+
371+
f = decode_frame(data)
366372

367373
assert isinstance(f, SettingsFrame)
368-
assert f.flags == set(['ACK'])
374+
assert f.flags == set()
369375
assert f.settings == self.settings
370376
assert f.body_len == 42
371377

378+
def test_settings_frame_invalid_body_length(self):
379+
with pytest.raises(ValueError):
380+
decode_frame(
381+
b'\x00\x00\x2A\x04\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF'
382+
)
383+
372384
def test_settings_frames_never_have_streams(self):
373385
with pytest.raises(ValueError):
374386
SettingsFrame(stream_id=1)

0 commit comments

Comments
 (0)