Browse Source

fix: add null-byte protection to SSE 'event' field for symmetry with 'id'

`_check_event_no_newline` lacked a `\0` check that `_check_id_no_null_or_newline`
has had since the original implementation. Similarly, `format_sse_event()` stripped
`\0` from `id` but not from `event`.

Changes:
- Extend `_check_event_no_newline` to also reject `\0` characters
- Strip `\0` in `format_sse_event()` for `event` (mirrors existing `id` behavior)
- Add `test_server_sent_event_null_event_rejected` regression test

`event` and `id` are now fully symmetric in both the model validator and the
low-level wire formatter.
pull/15187/head
Subhash Dasyam 4 months ago
parent
commit
06eccbf077
  1. 9
      fastapi/sse.py
  2. 5
      tests/test_sse.py

9
fastapi/sse.py

@ -43,8 +43,11 @@ def _check_id_no_null_or_newline(v: str | None) -> str | None:
def _check_event_no_newline(v: str | None) -> str | None:
if v is not None and ("\n" in v or "\r" in v):
raise ValueError("SSE 'event' must not contain newline characters")
if v is not None:
if "\0" in v:
raise ValueError("SSE 'event' must not contain null characters")
if "\n" in v or "\r" in v:
raise ValueError("SSE 'event' must not contain newline characters")
return v
@ -209,7 +212,7 @@ def format_sse_event(
lines.append(f": {line}")
if event is not None:
event = event.replace("\r", "").replace("\n", "")
event = event.replace("\r", "").replace("\n", "").replace("\0", "")
lines.append(f"event: {event}")
if data_str is not None:

5
tests/test_sse.py

@ -221,6 +221,11 @@ def test_server_sent_event_null_id_rejected():
ServerSentEvent(data="test", id="has\0null")
def test_server_sent_event_null_event_rejected():
with pytest.raises(ValueError, match="null"):
ServerSentEvent(data="test", event="has\0null")
def test_server_sent_event_newline_event_rejected():
with pytest.raises(ValueError, match="newline"):
ServerSentEvent(data="test", event="chat\npwned")

Loading…
Cancel
Save