From 59bf1d8cd97a1643b88b44374885c319c79269f5 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Thu, 9 May 2024 11:31:10 +0200 Subject: [PATCH] Fix curl compatibility issues with colorize_url (#14615) Also move the escape code safety check to guiOpenURL. --- src/gui/guiOpenURL.cpp | 19 ++++++++++++++----- src/unittest/test_utilities.cpp | 8 +++++--- src/util/colorize.cpp | 17 +++++++---------- src/util/colorize.h | 12 ++++++++++-- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/gui/guiOpenURL.cpp b/src/gui/guiOpenURL.cpp index 547d52c17..33be88162 100644 --- a/src/gui/guiOpenURL.cpp +++ b/src/gui/guiOpenURL.cpp @@ -42,6 +42,19 @@ GUIOpenURLMenu::GUIOpenURLMenu(gui::IGUIEnvironment* env, { } +static std::string maybe_colorize_url(const std::string &url) +{ + // Forbid escape codes in URL + if (url.find('\x1b') != std::string::npos) { + throw std::runtime_error("URL contains escape codes"); + } + +#ifdef HAVE_COLORIZE_URL + return colorize_url(url); +#else + return url; +#endif +} void GUIOpenURLMenu::regenerateGui(v2u32 screensize) { @@ -70,16 +83,12 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize) */ bool ok = true; std::string text; -#ifdef USE_CURL try { - text = colorize_url(url); + text = maybe_colorize_url(url); } catch (const std::exception &e) { text = std::string(e.what()) + " (url = " + url + ")"; ok = false; } -#else - text = url; -#endif /* Add stuff diff --git a/src/unittest/test_utilities.cpp b/src/unittest/test_utilities.cpp index 910d785f2..996b418e3 100644 --- a/src/unittest/test_utilities.cpp +++ b/src/unittest/test_utilities.cpp @@ -728,16 +728,18 @@ void TestUtilities::testIsBlockInSight() void TestUtilities::testColorizeURL() { -#if USE_CURL +#ifdef HAVE_COLORIZE_URL #define RED COLOR_CODE("#faa") #define GREY COLOR_CODE("#aaa") #define WHITE COLOR_CODE("#fff") std::string result = colorize_url("http://example.com/"); - UASSERT(result == (GREY "http://" WHITE "example.com" GREY "/")); + UASSERTEQ(auto, result, (GREY "http://" WHITE "example.com" GREY "/")); result = colorize_url(u8"https://u:p@wikipedi\u0430.org:1234/heIIoll?a=b#c"); - UASSERT(result == + UASSERTEQ(auto, result, (GREY "https://u:p@" WHITE "wikipedi" RED "%d0%b0" WHITE ".org" GREY ":1234/heIIoll?a=b#c")); +#else + warningstream << "Test skipped." << std::endl; #endif } diff --git a/src/util/colorize.cpp b/src/util/colorize.cpp index 8fc33b561..873ec06fc 100644 --- a/src/util/colorize.cpp +++ b/src/util/colorize.cpp @@ -17,7 +17,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "colorize.h" -#if USE_CURL +#ifdef HAVE_COLORIZE_URL #include #include "log.h" @@ -26,18 +26,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. std::string colorize_url(const std::string &url) { - // Forbid escape codes in URL - if (url.find('\x1b') != std::string::npos) { - throw std::runtime_error("Unable to open URL as it contains escape codes"); - } - auto urlHandleRAII = std::unique_ptr( curl_url(), curl_url_cleanup); CURLU *urlHandle = urlHandleRAII.get(); auto rc = curl_url_set(urlHandle, CURLUPART_URL, url.c_str(), 0); if (rc != CURLUE_OK) { - throw std::runtime_error("Unable to open URL as it is not valid"); + throw std::runtime_error("URL is not valid"); } auto url_get = [&] (CURLUPart what) -> std::string { @@ -56,7 +51,11 @@ std::string colorize_url(const std::string &url) auto path = url_get(CURLUPART_PATH); auto query = url_get(CURLUPART_QUERY); auto fragment = url_get(CURLUPART_FRAGMENT); +#if LIBCURL_VERSION_NUM >= 0x074100 auto zoneid = url_get(CURLUPART_ZONEID); +#else + std::string zoneid; +#endif std::ostringstream os; @@ -75,9 +74,7 @@ std::string colorize_url(const std::string &url) // Print hostname, escaping unsafe characters os << white; bool was_alphanum = true; - std::string host_s = host; - for (size_t i = 0; i < host_s.size(); i++) { - char c = host_s[i]; + for (char c : host) { bool is_alphanum = isalnum(c) || ispunct(c); if (is_alphanum == was_alphanum) { // skip diff --git a/src/util/colorize.h b/src/util/colorize.h index 3cde3e3dc..cb7ae7c30 100644 --- a/src/util/colorize.h +++ b/src/util/colorize.h @@ -23,11 +23,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define COLOR_CODE(color) "\x1b(c@" color ")" #if USE_CURL +#include +// curl_url functions since 7.62.0 +#if LIBCURL_VERSION_NUM >= 0x073e00 +#define HAVE_COLORIZE_URL +#endif +#endif + +#ifdef HAVE_COLORIZE_URL /** - * Colorize URL to highlight the hostname and any unsafe characters + * Colorize URL to highlight the hostname and any unsafe characters. * - * Throws an exception if the url is invalid + * Throws an exception if the url is invalid. */ std::string colorize_url(const std::string &url);