Skip to content

Commit

Permalink
Escape control characters for “testcase[name]”
Browse files Browse the repository at this point in the history
  • Loading branch information
Sija committed Dec 24, 2019
1 parent b50e61a commit c42781c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
4 changes: 4 additions & 0 deletions spec/std/spec/junit_formatter_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,14 @@ describe "JUnit Formatter" do
it "escapes spec names" do
output = build_report do |f|
f.report Spec::Result.new(:success, %(complicated " <n>'&ame), __FILE__, __LINE__, nil, nil)
f.report Spec::Result.new(:success, %(ctrl characters follow - \r\n), __FILE__, __LINE__, nil, nil)
end

name = XML.parse(output).xpath_string("string(//testsuite/testcase[1]/@name)")
name.should eq(%(complicated \" <n>'&ame))

name = XML.parse(output).xpath_string("string(//testsuite/testcase[2]/@name)")
name.should eq(%(ctrl characters follow - \\r\\n))
end

it "report failure stacktrace if present" do
Expand Down
17 changes: 16 additions & 1 deletion src/spec/junit_formatter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,29 @@ module Spec
JUnitFormatter.new(file)
end

private def escape_xml_attr(value)
reader = Char::Reader.new(value)
String.build do |io|
while reader.has_next?
case current_char = reader.current_char
when .control?
current_char.to_s.inspect_unquoted(io)
else
current_char.to_s(io)
end
reader.next_char
end
end
end

# -------- private utility methods
private def write_report(result, io)
io << %( <testcase file=")
HTML.escape(result.file, io)
io << %(" classname=")
HTML.escape(classname(result), io)
io << %(" name=")
HTML.escape(result.description, io)
HTML.escape(escape_xml_attr(result.description), io)

if elapsed = result.elapsed
io << %(" time=")
Expand Down

0 comments on commit c42781c

Please sign in to comment.