diff --git a/CHANGELOG.md b/CHANGELOG.md index c6022d3..710349b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 0.1.3 + +### Fixed +- Restored documented `YYYY-MM-DD` string support in `search()` (broken in + 0.1.2 when naive datetimes started being rejected); date-only strings are + formatted as UTC midnight. Naive timestamp strings (e.g. + `2024-01-15T10:00:00`) remain rejected as ambiguous. +- `examples/_example_utils.safe_markdown_url` now validates with `urlsplit` + (scheme + hostname required) and percent-encodes angle brackets, + parentheses, and spaces, closing a Markdown/HTML injection path where a + `https://...>") is None + + def test_scheme_relative_rejected(self): + assert safe_markdown_url("//attacker.example/x") is None + + def test_missing_netloc_rejected(self): + assert safe_markdown_url("https://") is None + + def test_angle_brackets_percent_encoded(self): + out = safe_markdown_url("https://example.com>") + assert "<" not in out and ">" not in out + assert out == "https://example.com%3E%3Cscript%3Ex%3C/script%3E" + + def test_parens_percent_encoded(self): + assert safe_markdown_url("https://example.com/x(1)") == "https://example.com/x%281%29" + + def test_normal_url_unchanged(self): + assert safe_markdown_url("https://example.com/a?b=1&c=2") == "https://example.com/a?b=1&c=2" + + def test_non_string_rejected(self): + assert safe_markdown_url(None) is None + assert safe_markdown_url(123) is None + + +class TestBriefingOutputSanitization: + def test_hostile_title_cannot_form_link(self): + art = { + "title": "[click here](javascript:alert(1))", + "description": "", + "url": "", + "published": "2026-01-01", + } + md, _ = briefing.build_output( + {"status": "ok", "news": [art]}, generated_at="2026-01-01T00:00:00Z" + ) + assert "](javascript:" not in md + + def test_hostile_url_cannot_break_out(self): + art = { + "title": "t", + "description": "", + "url": "https://example.com>", + "published": "2026-01-01", + } + md, _ = briefing.build_output( + {"status": "ok", "news": [art]}, generated_at="2026-01-01T00:00:00Z" + ) + assert "