diff --git a/changelog.d/20261013_invalid_gml_polygon.rst b/changelog.d/20261013_invalid_gml_polygon.rst new file mode 100644 index 00000000..02d89357 --- /dev/null +++ b/changelog.d/20261013_invalid_gml_polygon.rst @@ -0,0 +1,5 @@ +Fixed +----- + +* Ignore invalid numeric coordinates in GML polygon position lists instead + of raising ``TypeError``. (#599) diff --git a/feedparser/namespaces/georss.py b/feedparser/namespaces/georss.py index c2d9eb09..0b8a604e 100644 --- a/feedparser/namespaces/georss.py +++ b/feedparser/namespaces/georss.py @@ -172,6 +172,8 @@ def _parse_poslist(value, geom_type, swap=True, dims=2): return _parse_georss_line(value, swap, dims) if geom_type == "polygon": ring = _parse_georss_line(value, swap, dims) + if ring is None: + return None return {"type": "Polygon", "coordinates": (ring["coordinates"],)} return None diff --git a/tests/test_georss.py b/tests/test_georss.py new file mode 100644 index 00000000..93b7b840 --- /dev/null +++ b/tests/test_georss.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +import pytest + +import feedparser +from feedparser.namespaces.georss import _parse_poslist + + +@pytest.mark.parametrize("value", [".", "1 invalid", "1 2 3 invalid"]) +def test_invalid_polygon_poslist(value): + assert _parse_poslist(value, "polygon") is None + + +@pytest.mark.parametrize("loose", [False, True]) +@pytest.mark.parametrize("value", [".", "1 invalid", "1 2 3 invalid"]) +def test_invalid_gml_polygon_does_not_raise(value, loose, monkeypatch): + if loose: + monkeypatch.setattr(feedparser.api, "_XML_AVAILABLE", False) + data = f""" + Preserved + {value} + + """ + result = feedparser.parse(data) + assert result.entries[0].title == "Preserved" + assert "coordinates" not in result.entries[0].get("where", {}) + + +def test_invalid_gml_polygon_minimized_input(): + result = feedparser.parse( + b"." + ) + assert result.bozo + + +def test_valid_polygon_poslist(): + assert _parse_poslist("1 2 3 4 5 6 1 2", "polygon") == { + "type": "Polygon", + "coordinates": ([(2.0, 1.0), (4.0, 3.0), (6.0, 5.0), (2.0, 1.0)],), + }