diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp
index cf509bee149e513f4bf2b3b63540ba2435b954e9..689f649d0a59ba24f56fc29f98c64327c34101b7 100644
--- a/indra/llcommon/llformat.cpp
+++ b/indra/llcommon/llformat.cpp
@@ -37,16 +37,40 @@
 
 #include <cstdarg>
 
-std::string llformat(const char *fmt, ...)
+// common used function with va_list argument
+// wrapper for vsnprintf to be called from llformatXXX functions.
+static void va_format(std::string& out, const char *fmt, va_list va)
 {
 	char tstr[1024];	/* Flawfinder: ignore */
-	va_list va;
-	va_start(va, fmt);
 #if LL_WINDOWS
 	_vsnprintf(tstr, 1024, fmt, va);
 #else
 	vsnprintf(tstr, 1024, fmt, va);	/* Flawfinder: ignore */
 #endif
+	out.assign(tstr);
+}
+
+std::string llformat(const char *fmt, ...)
+{
+	std::string res;
+	va_list va;
+	va_start(va, fmt);
+	va_format(res, fmt, va);
 	va_end(va);
-	return std::string(tstr);
+	return res;
+}
+
+std::string llformat_to_utf8(const char *fmt, ...)
+{
+	std::string res;
+	va_list va;
+	va_start(va, fmt);
+	va_format(res, fmt, va);
+	va_end(va);
+
+#if LL_WINDOWS
+	// made converting to utf8. See EXT-8318.
+	res = ll_convert_string_to_utf8_string(res);
+#endif
+	return res;
 }
diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h
index dc64edb26da3fdb31b9781cbdf291d4355a0b3e9..17d8b4a8ad803460c1c5c18bb2463f84ab46dc51 100644
--- a/indra/llcommon/llformat.h
+++ b/indra/llcommon/llformat.h
@@ -42,4 +42,8 @@
 
 std::string LL_COMMON_API llformat(const char *fmt, ...);
 
+// the same version as above but ensures that returned string is in utf8 on windows
+// to enable correct converting utf8_to_wstring.
+std::string LL_COMMON_API llformat_to_utf8(const char *fmt, ...);
+
 #endif // LL_LLFORMAT_H
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 1561bda2018d0539c9bce6ea5d597e44a3589a82..804c00fd6092ea20bb747721e1c5db14f1186c37 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -633,14 +633,14 @@ namespace snprintf_hack
 	}
 }
 
-std::string ll_convert_wide_to_string(const wchar_t* in)
+std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
 {
 	std::string out;
 	if(in)
 	{
 		int len_in = wcslen(in);
 		int len_out = WideCharToMultiByte(
-			CP_ACP,
+			code_page,
 			0,
 			in,
 			len_in,
@@ -655,7 +655,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in)
 		if(pout)
 		{
 			WideCharToMultiByte(
-				CP_ACP,
+				code_page,
 				0,
 				in,
 				len_in,
@@ -669,6 +669,31 @@ std::string ll_convert_wide_to_string(const wchar_t* in)
 	}
 	return out;
 }
+
+wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
+{
+	int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0);
+
+	// reserve place to NULL terminator
+	wchar_t* w_out = new wchar_t[output_str_len + 1];
+
+	memset(w_out, 0, output_str_len + 1);
+	MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len);
+
+	//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858.
+	w_out[output_str_len] = 0;
+
+	return w_out;
+}
+
+std::string ll_convert_string_to_utf8_string(const std::string& in)
+{
+	wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP);
+	std::string out_utf8 = ll_convert_wide_to_string(w_mesg, CP_UTF8);
+	delete[] w_mesg;
+
+	return out_utf8;
+}
 #endif // LL_WINDOWS
 
 long LLStringOps::sPacificTimeOffset = 0;
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 8071c8aa2d9e83e76048ba11f833a74eb409c7cf..41fac0f8cc413e9e5d8d659e1e1ec3a7d45354f5 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -564,7 +564,20 @@ using snprintf_hack::snprintf;
  *
  * This replaces the unsafe W2A macro from ATL.
  */
-LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in);
+LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page);
+
+/**
+ * Converts a string to wide string.
+ *
+ * It will allocate memory for result string with "new []". Don't forget to release it with "delete []".
+ */
+LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page);
+
+/**
+ * Converts incoming string into urf8 string
+ *
+ */
+LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);
 
 //@}
 #endif // LL_WINDOWS
diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp
index ed870d46d5fe058295610c2414c86f4e875f5f8e..9158bc70f5aa4d0c909413cf8f2d198b0172d4fc 100644
--- a/indra/llui/llresmgr.cpp
+++ b/indra/llui/llresmgr.cpp
@@ -298,11 +298,11 @@ void LLResMgr::getIntegerString( std::string& output, S32 input ) const
 		{
 			if (fraction == remaining_count)
 			{
-				fraction_string = llformat("%d%c", fraction, getThousandsSeparator());
+				fraction_string = llformat_to_utf8("%d%c", fraction, getThousandsSeparator());
 			}
 			else
 			{
-				fraction_string = llformat("%3.3d%c", fraction, getThousandsSeparator());
+				fraction_string = llformat_to_utf8("%3.3d%c", fraction, getThousandsSeparator());
 			}
 			output = fraction_string + output;
 		}
diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index 288423129915f5d14f9876688d404e0878239f52..01c750487e4477ef629bf4abae7f1f287a9d1e6f 100644
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
@@ -145,7 +145,7 @@ void LLCrashLoggerWindows::ProcessCaption(HWND hWnd)
 	TCHAR header[MAX_STRING];
 	std::string final;
 	GetWindowText(hWnd, templateText, sizeof(templateText));
-	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str());
+	final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());
 	ConvertLPCSTRToLPWSTR(final.c_str(), header);
 	SetWindowText(hWnd, header);
 }
@@ -158,7 +158,7 @@ void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem)
 	TCHAR header[MAX_STRING];
 	std::string final;
 	GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText));
-	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str());
+	final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());
 	ConvertLPCSTRToLPWSTR(final.c_str(), header);
 	SetDlgItemText(hWnd, nIDDlgItem, header);
 }
@@ -201,7 +201,7 @@ bool handle_button_click(WORD button_id)
 						wbuffer, // pointer to buffer for text
 						20000 // maximum size of string
 						);
-		std::string user_text(ll_convert_wide_to_string(wbuffer));
+		std::string user_text(ll_convert_wide_to_string(wbuffer, CP_ACP));
 		// Activate and show the window.
 		ShowWindow(gHwndProgress, SW_SHOW); 
 		// Try doing this second to make the progress window go frontmost.