From c21d968cc23e5f0c0bdd9a4cda7b5d15ee522fd1 Mon Sep 17 00:00:00 2001 From: timmy Date: Thu, 6 Aug 2026 13:17:35 +0000 Subject: [PATCH] fix: reject malformed activity feed payloads (#107) --- src/gitea_proxy.py | 4 ++++ tests/test_event_stream.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/gitea_proxy.py b/src/gitea_proxy.py index 70f62ef..cb90595 100644 --- a/src/gitea_proxy.py +++ b/src/gitea_proxy.py @@ -40,6 +40,10 @@ async def pull_requests() -> list[dict]: async def activity_events() -> list[dict]: user = await current_user() events = await fetch(f"users/{user['login']}/activities/feeds?limit=20") + if events is None: + events = [] + elif not isinstance(events, list): + raise ValueError("Gitea activity feed response was not a list") return [ { "type": ( diff --git a/tests/test_event_stream.py b/tests/test_event_stream.py index 3bd5a3e..0594291 100644 --- a/tests/test_event_stream.py +++ b/tests/test_event_stream.py @@ -164,6 +164,25 @@ async def test_activity_events_normalizes_null_feed_payload(monkeypatch): assert await gitea_proxy.activity_events() == [] +@pytest.mark.anyio +async def test_event_stream_rejects_malformed_activity_feed_payload(monkeypatch): + async def fake_current_user(): + return {"login": "timmy"} + + async def fake_fetch(path): + return {"message": "unexpected upstream shape"} + + monkeypatch.setattr(gitea_proxy, "current_user", fake_current_user) + monkeypatch.setattr(gitea_proxy, "fetch", fake_fetch) + + response = await main.event_stream() + + assert getattr(response, "status_code", None) == 503 + assert json.loads(response.body) == { + "error": "Gitea event stream is temporarily unavailable" + } + + @pytest.mark.anyio async def test_activity_events_normalizes_malformed_nested_metadata(monkeypatch): async def fake_current_user(): -- 2.43.0