From 192e69156d4633c5c3978da88439175ae227a35b Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Sat, 7 Nov 2020 02:04:26 -0500
Subject: [PATCH] Fix broken usage of absl::format exposed by clang

---
 indra/llcommon/llsdserialize.cpp     | 13 ++++++++++---
 indra/llcommon/llsdserialize.h       |  4 +++-
 indra/llcommon/llsdserialize_xml.cpp |  2 +-
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index ba76ad559b7..c4ada39e3fc 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -1230,7 +1230,14 @@ void LLSDFormatter::boolalpha(bool alpha)
 
 void LLSDFormatter::realFormat(const std::string& format)
 {
-	mRealFormat = format;
+    if(!format.empty())
+    {
+        mRealFormat = absl::ParsedFormat<absl::FormatConversionCharSet::kFloating>::New(format);
+        if(!mRealFormat)
+        {
+            LL_WARNS() << "Invalid real format spec: " << format << LL_ENDL;
+        }
+    }
 }
 
 S32 LLSDFormatter::format(const LLSD& data, std::ostream& ostr) const
@@ -1246,7 +1253,7 @@ S32 LLSDFormatter::format(const LLSD& data, std::ostream& ostr, EFormatterOption
 
 void LLSDFormatter::formatReal(LLSD::Real real, std::ostream& ostr) const
 {
-	ostr << absl::StreamFormat(mRealFormat.c_str(), real);
+	ostr << absl::StreamFormat(*mRealFormat, real);
 }
 
 /**
@@ -1354,7 +1361,7 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr,
 
 	case LLSD::TypeReal:
 		ostr << "r";
-		if(mRealFormat.empty())
+		if(!mRealFormat)
 		{
 			ostr << data.asReal();
 		}
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index b24ef9d9c47..9702eca5733 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -34,6 +34,8 @@
 #include "llrefcount.h"
 #include "llsd.h"
 
+#include "absl/strings/str_format.h"
+
 /** 
  * @class LLSDParser
  * @brief Abstract base class for LLSD parsers.
@@ -500,7 +502,7 @@ class LL_COMMON_API LLSDFormatter : public LLRefCount
 	void formatReal(LLSD::Real real, std::ostream& ostr) const;
 
 	bool mBoolAlpha;
-	std::string mRealFormat;
+    std::unique_ptr<absl::ParsedFormat<absl::FormatConversionCharSet::kFloating> > mRealFormat;
 	EFormatterOptions mOptions;
 };
 
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 4a6a4a02fa6..d7dab88e33c 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -150,7 +150,7 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr,
 
 	case LLSD::TypeReal:
 		ostr << pre << "<real>";
-		if(mRealFormat.empty())
+		if(!mRealFormat)
 		{
 			ostr << data.asReal();
 		}
-- 
GitLab