diff --git a/CHANGELOG b/CHANGELOG
index 62a763231..c3b50c8d4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,10 @@
# Nmap Changelog ($Id$); -*-text-*-
+o We now escape newlines, carriage returns, and tabs (\n\r\t) in XML
+ output. While those are allowed in XML attributes, they get
+ normalized which can make formatting the output difficult for
+ applications which parse Nmap XML. [Joao Medeiros, David, Fyodor]
+
o Add Famtech Radmin remote control software probe and signatures to
the Nmap version detection DB. [Tom Sellers, Fyodor]
diff --git a/output.cc b/output.cc
index 81184f64c..ef21b2027 100644
--- a/output.cc
+++ b/output.cc
@@ -794,6 +794,12 @@ char* formatScriptOutput(struct script_scan_result ssr) {
}
#endif /* NOLUA */
+
+/* Note that this escapes newlines, which is generally needed in
+ attributes to avoid parser normalization, but might not be needed
+ or desirable in XML content outside of attributes. So if we find
+ some cases where we don't want \r\n\t escaped, we'll have to add a
+ parameter to control this. */
char* xml_convert (const char* str) {
char *temp, ch=0, prevch = 0, *p;
int strl = strlen(str);
@@ -802,6 +808,15 @@ char* xml_convert (const char* str) {
for (p = temp;(prevch = ch, ch = *str);str++) {
char *a;
switch (ch) {
+ case '\t':
+ a = " ";
+ break;
+ case '\r':
+ a = "
";
+ break;
+ case '\n':
+ a = "
";
+ break;
case '<':
a = "<";
break;
@@ -1632,7 +1647,7 @@ void printosscanoutput(Target *currenths) {
currenths->v4hostip(), distance, currenths->MACAddress(),
FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
false));
- log_write(LOG_XML,"\n", xml_osfp);
+ log_write(LOG_XML,"\n", xml_osfp);
free(xml_osfp);
}