From 3e322df4fb71cbeff27aab85bb48c7da595b548c Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Sun, 28 Jul 2024 16:27:42 -0400
Subject: Replace liburiparser with boost::url

---
 indra/llcommon/CMakeLists.txt  |   2 -
 indra/llcommon/lluriparser.cpp | 168 ++++++++++++-----------------------------
 indra/llcommon/lluriparser.h   |  27 ++++---
 3 files changed, 60 insertions(+), 137 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 95e991c246..8e43627a5f 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -10,7 +10,6 @@ include(Boost)
 include(LLSharedLibs)
 include(Copy3rdPartyLibs)
 include(ZLIBNG)
-include(URIPARSER)
 include(Tracy)
 
 
@@ -278,7 +277,6 @@ target_link_libraries(
         ll::expat
         ll::zlib-ng
         ll::boost
-        ll::uriparser
         ll::oslibraries
         ll::tracy
     )
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index 2ebb7fc742..33a48d970d 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -29,12 +29,7 @@
 #include "linden_common.h"
 #include "lluriparser.h"
 
-#if LL_DARWIN
-#include <signal.h>
-#include <setjmp.h>
-#endif
-
-LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)
+LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(false)
 {
     if (u.find("://") == std::string::npos)
     {
@@ -42,36 +37,52 @@ LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedT
         mTmpScheme = true;
     }
 
-    mNormalizedUri += u.c_str();
+    mNormalizedUri.append(u);
 
     mRes = parse();
 }
 
 LLUriParser::~LLUriParser()
 {
-    uriFreeUriMembersA(&mUri);
 }
 
-S32 LLUriParser::parse()
+bool LLUriParser::parse()
 {
-    mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL);
+    try
+    {
+        auto res = boost::urls::parse_uri(mNormalizedUri);
+        if (res)
+        {
+            mUri = *res;
+            mRes = true;
+        }
+        else
+        {
+            mRes = false;
+        }
+    }
+    catch (const std::length_error&)
+    {
+        LL_WARNS() << "Failed to parse uri due to exceeding uri_view max_size" << LL_ENDL;
+        mRes = false;
+    }
     return mRes;
 }
 
-const char * LLUriParser::scheme() const
+const std::string& LLUriParser::scheme() const
 {
-    return mScheme.c_str();
+    return mScheme;
 }
 
-void LLUriParser::sheme(const std::string& s)
+void LLUriParser::scheme(const std::string& s)
 {
     mTmpScheme = !s.size();
     mScheme = s;
 }
 
-const char * LLUriParser::port() const
+const std::string& LLUriParser::port() const
 {
-    return mPort.c_str();
+    return mPort;
 }
 
 void LLUriParser::port(const std::string& s)
@@ -79,9 +90,9 @@ void LLUriParser::port(const std::string& s)
     mPort = s;
 }
 
-const char * LLUriParser::host() const
+const std::string& LLUriParser::host() const
 {
-    return mHost.c_str();
+    return mHost;
 }
 
 void LLUriParser::host(const std::string& s)
@@ -89,9 +100,9 @@ void LLUriParser::host(const std::string& s)
     mHost = s;
 }
 
-const char * LLUriParser::path() const
+const std::string& LLUriParser::path() const
 {
-    return mPath.c_str();
+    return mPath;
 }
 
 void LLUriParser::path(const std::string& s)
@@ -99,9 +110,9 @@ void LLUriParser::path(const std::string& s)
     mPath = s;
 }
 
-const char * LLUriParser::query() const
+const std::string& LLUriParser::query() const
 {
-    return mQuery.c_str();
+    return mQuery;
 }
 
 void LLUriParser::query(const std::string& s)
@@ -109,9 +120,9 @@ void LLUriParser::query(const std::string& s)
     mQuery = s;
 }
 
-const char * LLUriParser::fragment() const
+const std::string& LLUriParser::fragment() const
 {
-    return mFragment.c_str();
+    return mFragment;
 }
 
 void LLUriParser::fragment(const std::string& s)
@@ -119,19 +130,6 @@ void LLUriParser::fragment(const std::string& s)
     mFragment = s;
 }
 
-void LLUriParser::textRangeToString(UriTextRangeA& textRange, std::string& str)
-{
-    if (textRange.first != NULL && textRange.afterLast != NULL && textRange.first < textRange.afterLast)
-    {
-        const ptrdiff_t len = textRange.afterLast - textRange.first;
-        str.assign(textRange.first, static_cast<std::string::size_type>(len));
-    }
-    else
-    {
-        str = LLStringUtil::null;
-    }
-}
-
 void LLUriParser::extractParts()
 {
     if (mTmpScheme || mNormalizedTmp)
@@ -140,96 +138,24 @@ void LLUriParser::extractParts()
     }
     else
     {
-        textRangeToString(mUri.scheme, mScheme);
+        mScheme = mUri.scheme();
     }
 
-    textRangeToString(mUri.hostText, mHost);
-    textRangeToString(mUri.portText, mPort);
-    textRangeToString(mUri.query, mQuery);
-    textRangeToString(mUri.fragment, mFragment);
-
-    UriPathSegmentA * pathHead = mUri.pathHead;
-    while (pathHead)
-    {
-        std::string partOfPath;
-        textRangeToString(pathHead->text, partOfPath);
-
-        mPath += '/';
-        mPath += partOfPath;
-
-        pathHead = pathHead->next;
-    }
+    mHost = mUri.host();
+    mPort = mUri.port();
+    mQuery = mUri.query();
+    mFragment = mUri.fragment();
+    mPath = mUri.path();
 }
 
-#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.
-    longjmp(return_to_normalize, 1 /*setjmp will return this value*/);
-}
-#endif
-
-S32 LLUriParser::normalize()
+bool LLUriParser::normalize()
 {
     mNormalizedTmp = mTmpScheme;
-    if (!mRes)
+    if (mRes)
     {
-#if LL_DARWIN
-        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
-            // If you encountered this, please try to figure out what's wrong:
-            // 1. Verify that library's input is 'sane'
-            // 2. Check if we have an NSexception to work with (unlikely)
-            // 3. See if passing same string causes exception to repeat
-            //
-            // Crash happens at uriNormalizeSyntaxExA
-            // Warning!!! This does not properly unwind stack,
-            // if this can be handled by NSexception, it needs to be remade
-            llassert(0);
-
-            LL_WARNS() << "Uriparser crashed with " << sLastSignal << " , while processing: " << mNormalizedUri << LL_ENDL;
-            signal(SIGILL, last_sigill_handler);
-            signal(SIGBUS, last_sigbus_handler);
-            return 1;
-        }
-#endif
-
-        mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
-
-#if LL_DARWIN
-        signal(SIGILL, last_sigill_handler);
-        signal(SIGBUS, last_sigbus_handler);
-#endif
-
-        if (!mRes)
-        {
-            S32 chars_required;
-            mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
-
-            if (!mRes)
-            {
-                chars_required++;
-                std::vector<char> label_buf(chars_required);
-                mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
-
-                if (!mRes)
-                {
-                    mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
-                    mTmpScheme = false;
-                }
-            }
-        }
+        mUri.normalize_scheme().normalize_authority();
+        mNormalizedUri = mUri.buffer().substr(mTmpScheme ? 7 : 0);
+        mTmpScheme = false;
     }
 
     if(mTmpScheme && mNormalizedUri.size() > 7)
@@ -302,7 +228,7 @@ bool LLUriParser::test() const
     return uri == mNormalizedUri;
 }
 
-const char * LLUriParser::normalizedUri() const
+const std::string& LLUriParser::normalizedUri() const
 {
-    return mNormalizedUri.c_str();
+    return mNormalizedUri;
 }
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index 77eb4031d5..61d613f399 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -30,7 +30,7 @@
 #define LL_LLURIPARSER_H
 
 #include <string>
-#include "uriparser/Uri.h"
+#include "boost/url.hpp"
 
 class LL_COMMON_API LLUriParser
 {
@@ -38,36 +38,35 @@ public:
     LLUriParser(const std::string& u);
     ~LLUriParser();
 
-    const char * scheme() const;
-    void sheme (const std::string& s);
+    const std::string& scheme() const;
+    void scheme (const std::string& s);
 
-    const char * port() const;
+    const std::string& port() const;
     void port (const std::string& s);
 
-    const char * host() const;
+    const std::string& host() const;
     void host (const std::string& s);
 
-    const char * path() const;
+    const std::string& path() const;
     void path (const std::string& s);
 
-    const char * query() const;
+    const std::string& query() const;
     void query (const std::string& s);
 
-    const char * fragment() const;
+    const std::string& fragment() const;
     void fragment (const std::string& s);
 
-    const char * normalizedUri() const;
+    const std::string& normalizedUri() const;
 
     void extractParts();
     void glue(std::string& uri) const;
     void glueFirst(std::string& uri, bool use_scheme = true) const;
     void glueSecond(std::string& uri) const;
     bool test() const;
-    S32 normalize();
+    bool normalize();
 
 private:
-    S32 parse();
-    void textRangeToString(UriTextRangeA& textRange, std::string& str);
+    bool parse();
     std::string mScheme;
     std::string mHost;
     std::string mPort;
@@ -76,9 +75,9 @@ private:
     std::string mFragment;
     std::string mNormalizedUri;
 
-    UriUriA mUri;
+    boost::url mUri;
 
-    S32 mRes;
+    bool mRes;
     bool mTmpScheme;
     bool mNormalizedTmp;
 };
-- 
cgit v1.2.3