From 10213f994f64de1f50e1ff6b9b5f43be549d19cb Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 7 Apr 2017 20:29:24 +0300
Subject: [PATCH] MAINT-6283 Names that contain 'http:' or 'https:' were
 causing new line in chat history

---
 indra/llcommon/lluri.cpp    |  7 ++++---
 indra/llcommon/lluri.h      |  8 ++++++++
 indra/newview/lllogchat.cpp | 35 ++++++++++++++++++++++++++++-------
 3 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 9f12d49244d..758b98e1439 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -40,7 +40,8 @@
 #include <boost/algorithm/string/find_iterator.hpp>
 #include <boost/algorithm/string/finder.hpp>
 
-void encode_character(std::ostream& ostr, std::string::value_type val)
+// static
+void LLURI::encodeCharacter(std::ostream& ostr, std::string::value_type val)
 {
 	ostr << "%"
 
@@ -95,7 +96,7 @@ std::string LLURI::escape(
 			}
 			else
 			{
-				encode_character(ostr, c);
+				encodeCharacter(ostr, c);
 			}
 		}
 	}
@@ -106,7 +107,7 @@ std::string LLURI::escape(
 			c = *it;
 			if(allowed.find(c) == std::string::npos)
 			{
-				encode_character(ostr, c);
+				encodeCharacter(ostr, c);
 			}
 			else
 			{
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index c82a666e48c..9e44cc7da2a 100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -120,6 +120,14 @@ class LL_COMMON_API LLURI
 
 	/** @name Escaping Utilities */
 	//@{
+	/**
+	 * @brief 'Escape' symbol into stream
+	 *
+	 * @param ostr Output stream.
+	 * @param val Symbol to encode.
+	 */
+	static void encodeCharacter(std::ostream& ostr, std::string::value_type val);
+
 	/**
 	 * @brief Escape the string passed except for unreserved
 	 *
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index b9194c6c67b..e310bbb0627 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -67,7 +67,8 @@ const std::string LL_IM_FROM("from");
 const std::string LL_IM_FROM_ID("from_id");
 const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
 
-const static std::string IM_SEPARATOR(": ");
+const static char IM_SYMBOL_SEPARATOR(':');
+const static std::string IM_SEPARATOR(std::string() + IM_SYMBOL_SEPARATOR + " ");
 const static std::string NEW_LINE("\n");
 const static std::string NEW_LINE_SPACE_PREFIX("\n ");
 const static std::string TWO_SPACES("  ");
@@ -838,7 +839,7 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 	}
 
 	if (im[LL_IM_TIME].isDefined())
-{
+	{
 		std::string timestamp = im[LL_IM_TIME].asString();
 		boost::trim(timestamp);
 		ostr << '[' << timestamp << ']' << TWO_SPACES;
@@ -851,9 +852,29 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 	{
 		std::string from = im[LL_IM_FROM].asString();
 		boost::trim(from);
-		if (from.size())
+
+		std::size_t found = from.find(IM_SYMBOL_SEPARATOR);
+		std::size_t len = from.size();
+		std::size_t start = 0;
+		while (found != std::string::npos)
+		{
+			std::size_t sub_len = found - start;
+			if (sub_len > 0)
+			{
+				ostr << from.substr(start, sub_len);
+			}
+			LLURI::encodeCharacter(ostr, IM_SYMBOL_SEPARATOR);
+			start = found + 1;
+			found = from.find(IM_SYMBOL_SEPARATOR, start);
+		}
+		if (start < len)
+		{
+			std::string str_end = from.substr(start, len - start);
+			ostr << str_end;
+		}
+		if (len > 0)
 		{
-			ostr << from << IM_SEPARATOR;
+			ostr << IM_SEPARATOR;
 		}
 	}
 
@@ -865,7 +886,7 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX);
 		ostr << im_text;
 	}
-	}
+}
 
 bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params)
 {
@@ -912,7 +933,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	if (!boost::regex_match(stuff, name_and_text, NAME_AND_TEXT)) return false;
 
 	bool has_name = name_and_text[IDX_NAME].matched;
-	std::string name = name_and_text[IDX_NAME];
+	std::string name = LLURI::unescape(name_and_text[IDX_NAME]);
 
 	//we don't need a name/text separator
 	if (has_name && name.length() && name[name.length()-1] == ':')
@@ -933,7 +954,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 		U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER);
 		if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length()))
 		{
-			im[LL_IM_FROM] = stuff.substr(0, divider_pos);
+			im[LL_IM_FROM] = LLURI::unescape(stuff.substr(0, divider_pos));
 			im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
 			return true;
 		}
-- 
GitLab