diff --git a/include/internal/catch_xmlwriter.hpp b/include/internal/catch_xmlwriter.hpp index c59725b0..97890d2f 100644 --- a/include/internal/catch_xmlwriter.hpp +++ b/include/internal/catch_xmlwriter.hpp @@ -55,9 +55,10 @@ namespace Catch { break; default: - // Escape control chars - based on contribution by @espenalb in PR #465 + // Escape control chars - based on contribution by @espenalb in PR #465 and + // by @mrpi PR #588 if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) - os << "&#x" << std::uppercase << std::hex << static_cast( c ); + os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast( c ) << ';'; else os << c; } @@ -112,13 +113,20 @@ namespace Catch { : m_tagIsOpen( false ), m_needsNewline( false ), m_os( &Catch::cout() ) - {} + { + // We encode control characters, which requires + // XML 1.1 + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + *m_os << "\n"; + } XmlWriter( std::ostream& os ) : m_tagIsOpen( false ), m_needsNewline( false ), m_os( &os ) - {} + { + *m_os << "\n"; + } ~XmlWriter() { while( !m_tags.empty() ) diff --git a/projects/SelfTest/MiscTests.cpp b/projects/SelfTest/MiscTests.cpp index 9a2a2ab6..bb9cbf0a 100644 --- a/projects/SelfTest/MiscTests.cpp +++ b/projects/SelfTest/MiscTests.cpp @@ -406,27 +406,27 @@ TEST_CASE( "Tabs and newlines show in output", "[.][whitespace][failing]" ) { TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) { - const wchar_t * const s = L"wide load"; - std::string result = Catch::toString( s ); - CHECK( result == "\"wide load\"" ); + const wchar_t * const s = L"wide load"; + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); } TEST_CASE( "toString on const wchar_t pointer returns the string contents", "[toString]" ) { - const wchar_t * s = L"wide load"; - std::string result = Catch::toString( s ); - CHECK( result == "\"wide load\"" ); + const wchar_t * s = L"wide load"; + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); } TEST_CASE( "toString on wchar_t const pointer returns the string contents", "[toString]" ) { - wchar_t * const s = const_cast( L"wide load" ); - std::string result = Catch::toString( s ); - CHECK( result == "\"wide load\"" ); + wchar_t * const s = const_cast( L"wide load" ); + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); } TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) { - wchar_t * s = const_cast( L"wide load" ); - std::string result = Catch::toString( s ); - CHECK( result == "\"wide load\"" ); + wchar_t * s = const_cast( L"wide load" ); + std::string result = Catch::toString( s ); + CHECK( result == "\"wide load\"" ); } inline std::string encode( std::string const& str, Catch::XmlEncode::ForWhat forWhat = Catch::XmlEncode::ForTextNodes ) { @@ -458,10 +458,10 @@ TEST_CASE( "XmlEncode" ) { REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't "quote" me on that" ); } SECTION( "string with control char (1)" ) { - REQUIRE( encode( "[\x01]" ) == "[]" ); + REQUIRE( encode( "[\x01]" ) == "[]" ); } SECTION( "string with control char (x7F)" ) { - REQUIRE( encode( "[\x7F]" ) == "[]" ); + REQUIRE( encode( "[\x7F]" ) == "[]" ); } }