From e7d2540c1a1be4c4f69d64771cfddfaf0fc6556a Mon Sep 17 00:00:00 2001
From: Arseny Kapoulkine <arseny.kapoulkine@gmail.com>
Date: Tue, 14 Oct 2014 04:11:17 +0000
Subject: Adjust comment output to avoid malformed documents.

Comment value can not contain the string "--" or end with "-". Since
comments do not support escaping, we're handling this by adding an extra
space after the first "-". A string of "-" thus turns into "- - - ...".

git-svn-id: https://pugixml.googlecode.com/svn/trunk@1058 99668b35-9821-0410-8761-19e4c4f06640
---
 src/pugixml.cpp | 44 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)

(limited to 'src')

diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 93b648b..7db62d0 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -3424,6 +3424,31 @@ PUGI__NS_BEGIN
 		}
 	}
 
+	PUGI__FN void node_output_comment(xml_buffered_writer& writer, const char_t* s)
+	{
+		writer.write('<', '!', '-', '-');
+
+		while (*s)
+		{
+			const char_t* prev = s;
+
+			// look for -\0 or -- sequence - we can't output it since -- is illegal in comment body
+			while (*s && !(s[0] == '-' && (s[1] == '-' || s[1] == 0))) ++s;
+
+			writer.write_buffer(prev, static_cast<size_t>(s - prev));
+
+			if (*s)
+			{
+				assert(*s == '-');
+
+				writer.write('-', ' ');
+				++s;
+			}
+		}
+
+		writer.write('-', '-', '>');
+	}
+
 	PUGI__FN void node_output_attributes(xml_buffered_writer& writer, const xml_node node, unsigned int flags)
 	{
 		const char_t* default_name = PUGIXML_TEXT(":anonymous");
@@ -3523,22 +3548,15 @@ PUGI__NS_BEGIN
 				break;
 
 			case node_comment:
-				writer.write('<', '!', '-', '-');
-				writer.write_string(node.value());
-				writer.write('-', '-', '>');
+				node_output_comment(writer, node.value());
 				if ((flags & format_raw) == 0) writer.write('\n');
 				break;
 
 			case node_pi:
-			case node_declaration:
 				writer.write('<', '?');
 				writer.write_string(node.name()[0] ? node.name() : default_name);
 
-				if (node.type() == node_declaration)
-				{
-					node_output_attributes(writer, node, flags);
-				}
-				else if (node.value()[0])
+				if (node.value()[0])
 				{
 					writer.write(' ');
 					writer.write_string(node.value());
@@ -3548,6 +3566,14 @@ PUGI__NS_BEGIN
 				if ((flags & format_raw) == 0) writer.write('\n');
 				break;
 
+			case node_declaration:
+				writer.write('<', '?');
+				writer.write_string(node.name()[0] ? node.name() : default_name);
+				node_output_attributes(writer, node, flags);
+				writer.write('?', '>');
+				if ((flags & format_raw) == 0) writer.write('\n');
+				break;
+
 			case node_doctype:
 				writer.write('<', '!', 'D', 'O', 'C');
 				writer.write('T', 'Y', 'P', 'E');
-- 
cgit v1.2.3