From ae7b318e7f21d0d372d48a635ff1e2ea59c4acf6 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 22 Feb 2024 21:48:46 +0200
Subject: viewer#875 Crash at uri normalization

Note that crash happened when setting LLProgressView::setMessage
---
 indra/llcommon/lluriparser.cpp | 18 ++++++++++++------
 indra/llui/llurlentry.cpp      | 18 ++++++++++++------
 indra/llui/llurlregistry.cpp   |  6 ++++--
 3 files changed, 28 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index e4f229dd16..f79a98a56d 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -164,8 +164,10 @@ void LLUriParser::extractParts()
 #if LL_DARWIN
 typedef void(*sighandler_t)(int);
 jmp_buf return_to_normalize;
+static int sLastSignal = 0;
 void uri_signal_handler(int signal)
 {
+    sLastSignal = signal;
     // Apparently signal handler throwing an exception doesn't work.
     // This is ugly and unsafe due to not unwinding content of uriparser library,
     // but unless we have a way to catch this as NSexception, jump appears to be the only option.
@@ -179,8 +181,10 @@ S32 LLUriParser::normalize()
 	if (!mRes)
 	{
 #if LL_DARWIN
-        sighandler_t last_handler;
-        last_handler = signal(SIGILL, &uri_signal_handler);		// illegal instruction
+        sighandler_t last_sigill_handler, last_sigbus_handler;
+        last_sigill_handler = signal(SIGILL, &uri_signal_handler);		// illegal instruction
+        last_sigbus_handler = signal(SIGBUS, &uri_signal_handler);
+        
         if (setjmp(return_to_normalize))
         {
             // Issue: external library crashed via signal
@@ -194,8 +198,9 @@ S32 LLUriParser::normalize()
             // if this can be handled by NSexception, it needs to be remade
             llassert(0);
 
-            LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL;
-            signal(SIGILL, last_handler);
+            LL_WARNS() << "Uriparser crashed with " << sLastSignal << " , while processing: " << mNormalizedUri << LL_ENDL;
+            signal(SIGILL, last_sigill_handler);
+            signal(SIGBUS, last_sigbus_handler);
             return 1;
         }
 #endif
@@ -203,7 +208,8 @@ S32 LLUriParser::normalize()
         mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
 
 #if LL_DARWIN
-        signal(SIGILL, last_handler);
+        signal(SIGILL, last_sigill_handler);
+        signal(SIGBUS, last_sigbus_handler);
 #endif
 
         if (!mRes)
@@ -226,7 +232,7 @@ S32 LLUriParser::normalize()
         }
 	}
 
-	if(mTmpScheme)
+	if(mTmpScheme && mNormalizedUri.size() > 7)
 	{
 		mNormalizedUri = mNormalizedUri.substr(7);
 		mTmpScheme = false;
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 77e9edf5e5..05d821f5d8 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -234,14 +234,20 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
 
 std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
 {
+    if (url.empty())
+    {
+        return url;
+    }
 	LLUriParser up(escapeUrl(url));
-	up.normalize();
-
-	std::string label;
-	up.extractParts();
-	up.glueFirst(label);
+	if (up.normalize() == 0)
+    {
+        std::string label;
+        up.extractParts();
+        up.glueFirst(label);
 
-	return unescapeUrl(label);
+        return unescapeUrl(label);
+    }
+    return std::string();
 }
 
 std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 3bd7321777..f1df7699e2 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -221,8 +221,10 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
 		if (match_entry == mUrlEntryTrusted)
 		{
 			LLUriParser up(url);
-			up.normalize();
-			url = up.normalizedUri();
+			if (up.normalize() == 0)
+            {
+                url = up.normalizedUri();
+            }
 		}
 
 		match.setValues(match_start, match_end,
-- 
cgit v1.2.3