diff --git a/src/picosvg/svg.py b/src/picosvg/svg.py index 1b7ce56..6abb6f9 100644 --- a/src/picosvg/svg.py +++ b/src/picosvg/svg.py @@ -1303,7 +1303,9 @@ def checkpicosvg(self, allow_text=False): r"^/svg\[0\](/(path|g)\[\d+\])+$", } if allow_text: - path_allowlist.add(r"^/svg\[0\](/text\[\d+\])+$") + path_allowlist.add( + r"^/svg\[0\](/(text|textPath)\[\d+\])+(/(text|tspan|textPath)\[\d+\])*$" + ) paths_required = { "/svg[0]", "/svg[0]/defs[0]", diff --git a/tests/svg_test.py b/tests/svg_test.py index 898cc52..a175843 100644 --- a/tests/svg_test.py +++ b/tests/svg_test.py @@ -675,14 +675,66 @@ def test_remove_processing_instructions(): assert "xpacket" not in pico_svg.tostring() -def test_allow_text(): - text_svg = load_test_svg("text-before.svg") +@pytest.mark.parametrize( + "svg_string, match_re, expected_passthrough", + [ + # text element + ( + """ + + Hello + + """, + r"Unable to convert to picosvg: BadElement: /svg\[0\]/text\[0\]", + "text", + ), + # text with tspan + ( + """ + + + Hello + + + """, + r"Unable to convert to picosvg: BadElement: /svg\[0\]/text\[0\]", + "tspan", + ), + # text with textPath, sample copied from https://developer.mozilla.org/en-US/docs/Web/SVG/Element/textPath + ( + """ + + + + + + + + A very long text on path. + + + """, + r"Unable to convert to picosvg: BadElement: /svg\[0\]/text\[0\]", + "textPath", + ), + ], +) +def test_allow_text(svg_string, match_re, expected_passthrough): + text_svg = SVG.fromstring(svg_string) with pytest.raises( ValueError, - match=r"Unable to convert to picosvg: BadElement: /svg\[0\]/text\[0\]", + match=match_re, ): text_svg.topicosvg() - assert "text" in text_svg.topicosvg(allow_text=True).tostring() + assert expected_passthrough in text_svg.topicosvg(allow_text=True).tostring() def test_bounding_box(): diff --git a/tests/text-before.svg b/tests/text-before.svg deleted file mode 100644 index 390a696..0000000 --- a/tests/text-before.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Hello -