diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index 9f0291138..8e7d40259 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -617,6 +617,7 @@ ExPolygons Emboss::text2shapes(FontFileWithCache &font_with_cache, cursor.x() += count_spaces * space_opt->advance_width; continue; } + if (wc == '\r') continue; int unicode = static_cast(wc); std::optional glyph_opt = Private::get_glyph(unicode, font, font_prop, cache, font_info_opt); diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index bea038a35..977492220 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -3307,10 +3307,10 @@ void TextConfigurationSerialization::to_xml(std::stringstream &stream, const Tex { stream << " <" << TEXT_TAG << " "; - stream << TEXT_DATA_ATTR << "=\"" << xml_escape(tc.text) << "\" "; + stream << TEXT_DATA_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(tc.text) << "\" "; // font item const FontItem &fi = tc.font_item; - stream << FONT_DESCRIPTOR_ATTR << "=\"" << fi.path << "\" "; + stream << FONT_DESCRIPTOR_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(fi.path) << "\" "; stream << FONT_DESCRIPTOR_TYPE_ATTR << "=\"" << TextConfigurationSerialization::to_string.at(fi.type) << "\" "; // font property diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 10790ef49..01dcd05ad 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -250,6 +250,7 @@ inline typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER } extern std::string xml_escape(std::string text, bool is_marked = false); +extern std::string xml_escape_double_quotes_attribute_value(std::string text); #if defined __GNUC__ && __GNUC__ < 5 && !defined __clang__ diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 1d48f8452..75bb30eb5 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -992,7 +992,7 @@ std::string xml_escape(std::string text, bool is_marked/* = false*/) std::string::size_type pos = 0; for (;;) { - pos = text.find_first_of("\"\'&<>\n\t", pos); + pos = text.find_first_of("\"\'&<>", pos); if (pos == std::string::npos) break; @@ -1004,8 +1004,33 @@ std::string xml_escape(std::string text, bool is_marked/* = false*/) case '&': replacement = "&"; break; case '<': replacement = is_marked ? "<" :"<"; break; case '>': replacement = is_marked ? ">" : ">"; break; - case '\n': replacement = " "; break; - case '\t': replacement = " "; break; + default: break; + } + + text.replace(pos, 1, replacement); + pos += replacement.size(); + } + + return text; +} + +// Definition of escape symbols https://www.w3.org/TR/REC-xml/#AVNormalize + +std::string xml_escape_double_quotes_attribute_value(std::string text) +{ + std::string::size_type pos = 0; + for (;;) { + pos = text.find_first_of("\"&<\r\n\t", pos); + if (pos == std::string::npos) break; + + std::string replacement; + switch (text[pos]) { + case '\"': replacement = """; break; + case '&': replacement = "&"; break; + case '<': replacement = "<"; break; + case '\r': replacement = " "; break; + case '\n': replacement = " "; break; + case '\t': replacement = " "; break; default: break; }