Skip to content

Commit

Permalink
fix: Escaping HTML in log (#757)
Browse files Browse the repository at this point in the history
  • Loading branch information
BeyondEvil committed Nov 4, 2023
1 parent 84a1f68 commit 82762a2
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/pytest_html/basereport.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import re
import warnings
from collections import defaultdict
from html import escape
from pathlib import Path

import pytest
Expand Down Expand Up @@ -312,11 +313,11 @@ def _is_error(report):
def _process_logs(report):
log = []
if report.longreprtext:
log.append(report.longreprtext.replace("<", "&lt;").replace(">", "&gt;") + "\n")
log.append(escape(report.longreprtext) + "\n")
# Don't add captured output to reruns
if report.outcome != "rerun":
for section in report.sections:
header, content = section
header, content = map(escape, section)
log.append(f"{' ' + header + ' ':-^80}\n{content}")

# weird formatting related to logs
Expand Down
3 changes: 2 additions & 1 deletion src/pytest_html/report_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import warnings
from collections import defaultdict
from html import escape

from pytest_html.util import _handle_ansi

Expand Down Expand Up @@ -146,7 +147,7 @@ def append_teardown_log(self, report):
# Last index is "call"
test = self._data["tests"][report.nodeid][-1]
for section in report.sections:
header, content = section
header, content = map(escape, section)
if "teardown" in header:
log.append(f"{' ' + header + ' ':-^80}\n{content}")
test["log"] += _handle_ansi("\n".join(log))
36 changes: 36 additions & 0 deletions testing/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,42 @@ def test_pass(utf8):
log = get_log(page)
assert_that(log).does_not_match(r"测试用例名称")

@pytest.mark.parametrize("outcome, occurrence", [(True, 1), (False, 2)])
def test_log_escaping(self, pytester, outcome, occurrence):
"""
Not the best test, but it does a simple verification
that the string is escaped properly and not rendered as HTML
"""
texts = [
"0 Checking object <Chopstick Container> and more",
"1 Checking object < > and more",
"2 Checking object <> and more",
"3 Checking object < C > and more",
"4 Checking object <C > and more",
"5 Checking object < and more",
"6 Checking object < and more",
"7 Checking object < C and more",
"8 Checking object <C and more",
'9 Checking object "<Chopstick Container>" and more',
'10 Checking object "< >" and more',
'11 Checking object "<>" and more',
'12 Checking object "< C >" and more',
'13 Checking object "<C >" and more',
]
test_file = "def test_escape():\n"
for t in texts:
test_file += f"\tprint('{t}')\n"
test_file += f"\tassert {outcome}"
pytester.makepyfile(test_file)

page = run(pytester)
assert_results(page, passed=1 if outcome else 0, failed=1 if not outcome else 0)

log = get_log(page)
for each in texts:
count = log.count(each)
assert_that(count).is_equal_to(occurrence)


class TestLogCapturing:
LOG_LINE_REGEX = r"\s+this is {}"
Expand Down

0 comments on commit 82762a2

Please sign in to comment.