Skip to content

Commit

Permalink
Unescape the XmlEscape method from XUnit (#7323)
Browse files Browse the repository at this point in the history
XUnit applies some custom escaping to this particular field.
This code is the closest we can come to correctly reversing it so
that it can render normally.

It will produce incorrect results if a control character is followed
by valid hex digits, but there is no way to avoid that, and it should
be relatively rare for raw control characters to appear in error messages.
  • Loading branch information
ChadNedzlek authored Apr 30, 2021
1 parent 8d5c0ee commit 46ad27d
Showing 1 changed file with 25 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
import re
import xml.etree.ElementTree

from .result_format import ResultFormat
from defs import TestResult, TestResultAttachment

_unescape_char_map = {
'r': '\r',
'n': '\n',
't': '\t',
'0': '\0',
'a': '\a',
'b': '\b',
'v': '\v',
'f': '\f',
}

def _unescape_xunit_message(value):
# xunit does some escaping on the error message we need to do our
# best to turn back into something resembling the original message
# It only uses \x**, \x**** (indistinguishably), and then the items from __unescape_char_map
def bs(match):
grp = match.group(0)
sym = grp[1]
if sym == 'x':
return chr(int(grp[2:], 16))
return _unescape_char_map.get(match[0][1]) or sym
return re.sub(r'\\x[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]?[0-9a-fA-F]?|\\[^x]', bs, value)

class XUnitFormat(ResultFormat):

Expand Down Expand Up @@ -38,7 +62,7 @@ def read_results(self, path):
exception_type = failure_element.get("exception-type")
message_element = failure_element.find("message")
if message_element is not None:
failure_message = message_element.text
failure_message = _unescape_xunit_message(message_element.text)
stack_trace_element = failure_element.find("stack-trace")
if stack_trace_element is not None:
stack_trace = stack_trace_element.text
Expand Down

0 comments on commit 46ad27d

Please sign in to comment.