Skip to content

Commit 4aba5ca

Browse files
authored
Fix xml writing bug introduced in #16388 (#16713)
#16388 introduced a bug where invalid xml could be produced by `write_junit_xml`, as special characters were no longer being escaped. The fix is to revert the removal of `from xml.sax.saxutils import escape` and `escape("\n".join(messages))` in the `write_junit_xml` function. I've added a small test case which checks that the `<`, `>`, `&` are escaped correctly in the xml.
1 parent b08c8b5 commit 4aba5ca

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

mypy/test/testutil.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,28 @@ def test_junit_pass(self) -> None:
3131
<testcase classname="mypy" file="mypy" line="1" name="mypy-py3.14-test-plat" time="1.230">
3232
</testcase>
3333
</testsuite>
34+
"""
35+
result = _generate_junit_contents(
36+
dt=1.23,
37+
serious=serious,
38+
messages_by_file=messages_by_file,
39+
version="3.14",
40+
platform="test-plat",
41+
)
42+
assert result == expected
43+
44+
def test_junit_fail_escape_xml_chars(self) -> None:
45+
serious = False
46+
messages_by_file: dict[str | None, list[str]] = {
47+
"file1.py": ["Test failed", "another line < > &"]
48+
}
49+
expected = """<?xml version="1.0" encoding="utf-8"?>
50+
<testsuite errors="0" failures="1" name="mypy" skips="0" tests="1" time="1.230">
51+
<testcase classname="mypy" file="file1.py" line="1" name="mypy-py3.14-test-plat file1.py" time="1.230">
52+
<failure message="mypy produced messages">Test failed
53+
another line &lt; &gt; &amp;</failure>
54+
</testcase>
55+
</testsuite>
3456
"""
3557
result = _generate_junit_contents(
3658
dt=1.23,

mypy/util.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ def _generate_junit_contents(
263263
version: str,
264264
platform: str,
265265
) -> str:
266+
from xml.sax.saxutils import escape
267+
266268
if serious:
267269
failures = 0
268270
errors = len(messages_by_file)
@@ -284,7 +286,7 @@ def _generate_junit_contents(
284286
for filename, messages in messages_by_file.items():
285287
if filename is not None:
286288
xml += JUNIT_TESTCASE_FAIL_TEMPLATE.format(
287-
text="\n".join(messages),
289+
text=escape("\n".join(messages)),
288290
filename=filename,
289291
time=dt,
290292
name="mypy-py{ver}-{platform} {filename}".format(
@@ -293,7 +295,7 @@ def _generate_junit_contents(
293295
)
294296
else:
295297
xml += JUNIT_TESTCASE_FAIL_TEMPLATE.format(
296-
text="\n".join(messages),
298+
text=escape("\n".join(messages)),
297299
filename="mypy",
298300
time=dt,
299301
name="mypy-py{ver}-{platform}".format(ver=version, platform=platform),

0 commit comments

Comments
 (0)