diff --git a/src/ifcparse/utils.cpp b/src/ifcparse/utils.cpp index 41366817b0..4ca451c45a 100644 --- a/src/ifcparse/utils.cpp +++ b/src/ifcparse/utils.cpp @@ -107,6 +107,15 @@ void ifcopenshell::sanitate_material_name(std::string& str) { } void ifcopenshell::escape_xml(std::string& str) { + // Strip characters that are illegal in XML 1.0. Control characters other + // than tab (0x09), newline (0x0A) and carriage return (0x0D) are not valid + // XML 1.0 characters and cannot even be represented as numeric character + // references, so they would otherwise make the serialized XML/SVG output + // non-well-formed. Bytes belonging to a valid UTF-8 multibyte sequence are + // always >= 0x80, so filtering on the low control range leaves them intact. + str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char c) { + return c < 0x20 && c != '\t' && c != '\n' && c != '\r'; + }), str.end()); boost::replace_all(str, "&", "&"); boost::replace_all(str, "\"", """); boost::replace_all(str, "'", "'");