From 1adfaa081fd27d653619c84c520c16516c530ab1 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 1 Jun 2016 16:56:04 +0300
Subject: [PATCH] MAINT-6446 Correct password length handling

---
 indra/llcommon/llstring.cpp                   | 27 +++++++++++++++++++
 indra/llcommon/llstring.h                     | 11 ++++++++
 indra/llui/lllineeditor.cpp                   |  7 +----
 .../skins/default/xui/en/panel_login.xml      |  2 +-
 .../default/xui/en/panel_login_first.xml      |  2 +-
 5 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f3b8999883a..c45db3b1859 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -576,6 +576,33 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len)
 	}
 }
 
+std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len)
+{
+    if (0 == symbol_len)
+    {
+        return std::string();
+    }
+    if ((S32)utf8str.length() <= symbol_len)
+    {
+        return utf8str;
+    }
+    else
+    {
+        int len = 0, byteIndex = 0;
+        const char* aStr = utf8str.c_str();
+        size_t origSize = utf8str.size();
+
+        for (byteIndex = 0; len < symbol_len && byteIndex < origSize; byteIndex++)
+        {
+            if ((aStr[byteIndex] & 0xc0) != 0x80)
+            {
+                len += 1;
+            }
+        }
+        return utf8str.substr(0, byteIndex);
+    }
+}
+
 std::string utf8str_substChar(
 	const std::string& utf8str,
 	const llwchar target_char,
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 393f6d7a8c1..a40db0f8cc7 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -563,6 +563,17 @@ LL_COMMON_API S32 utf8str_compare_insensitive(
 	const std::string& lhs,
 	const std::string& rhs);
 
+/**
+* @brief Properly truncate a utf8 string to a maximum character count.
+*
+* If symbol_len is longer than the string passed in, the return
+* value == utf8str.
+* @param utf8str A valid utf8 string to truncate.
+* @param symbol_len The maximum number of symbols in the return value.
+* @return Returns a valid utf8 string with symbol count <= max_len.
+*/
+LL_COMMON_API std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len);
+
 /**
  * @brief Replace all occurences of target_char with replace_char
  *
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index a08cf91a69d..492c9315d13 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -400,12 +400,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
 
 	if (mMaxLengthChars)
 	{
-		LLWString truncated_wstring = utf8str_to_wstring(truncated_utf8);
-		if (truncated_wstring.size() > (U32)mMaxLengthChars)
-		{
-			truncated_wstring = truncated_wstring.substr(0, mMaxLengthChars);
-		}
-		mText.assign(wstring_to_utf8str(truncated_wstring));
+		mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars));
 	}
 
 	if (all_selected)
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index ae8e78a9d68..ded814bbebc 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -67,7 +67,7 @@
     follows="left|top"
     height="32"
     left_pad="-11"
-    max_length_bytes="64"
+    max_length_chars="16"
     text_pad_left="8"
     name="password_edit"
     label="Password"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index dc6e27a1ee5..35b80c56abe 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -124,7 +124,7 @@
             width="200"
             height="32"
             left="220"
-            max_length_bytes="64"
+            max_length_chars="16"
             name="password_edit"
             label="Password"
             text_pad_left="8"
-- 
GitLab