From 604861e520d2d6579674a1c2bd5e59cb10f7ecd2 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 10 Mar 2015 09:03:22 -0700 Subject: [PATCH] Escape ?> sequence in PI value during printing This prevents malformed PI value from breaking the document structure. --- src/pugixml.cpp | 23 ++++++++++++++++++++++- tests/test_write.cpp | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 6c88d55..ce8a79f 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3462,6 +3462,27 @@ PUGI__NS_BEGIN writer.write('-', '-', '>'); } + PUGI__FN void node_output_pi_value(xml_buffered_writer& writer, const char_t* s) + { + while (*s) + { + const char_t* prev = s; + + // look for ?> sequence - we can't output it since ?> terminates PI + while (*s && !(s[0] == '?' && s[1] == '>')) ++s; + + writer.write_buffer(prev, static_cast(s - prev)); + + if (*s) + { + assert(s[0] == '?' && s[1] == '>'); + + writer.write('?', ' ', '>'); + s += 2; + } + } + } + PUGI__FN void node_output_attributes(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); @@ -3575,7 +3596,7 @@ PUGI__NS_BEGIN if (node->value) { writer.write(' '); - writer.write_string(node->value); + node_output_pi_value(writer, node->value); } writer.write('?', '>'); diff --git a/tests/test_write.cpp b/tests/test_write.cpp index da83745..59cdb3e 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -115,6 +115,25 @@ TEST(write_pi_null) CHECK_NODE(doc, STR("")); } +TEST(write_pi_invalid) +{ + xml_document doc; + xml_node node = doc.append_child(node_pi); + + node.set_name(STR("test")); + node.set_value(STR("?")); + + CHECK_NODE(doc, STR("")); + + node.set_value(STR("?>")); + + CHECK_NODE(doc, STR("?>")); + + node.set_value(STR("")); + + CHECK_NODE(doc, STR("?>")); +} + TEST_XML_FLAGS(write_declaration, "", parse_declaration | parse_fragment) { CHECK_NODE(doc, STR(""));