From b6ac642db2213cf4207dddc47a1fe1490de0cc6e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 2 Jun 2021 23:26:48 +0300 Subject: SL-15243 Unicode URL validation --- indra/llui/llurlentry.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++----- indra/llui/llurlentry.h | 2 +- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 20dda54771..29a6e86819 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -181,11 +181,51 @@ bool LLUrlEntryBase::isLinkDisabled() const return globally_disabled; } -bool LLUrlEntryBase::isWikiLinkCorrect(std::string url) -{ - LLWString label = utf8str_to_wstring(getLabelFromWikiLink(url)); - label.erase(std::remove(label.begin(), label.end(), L'\u200B'), label.end()); - return (LLUrlRegistry::instance().hasUrl(wstring_to_utf8str(label))) ? false : true; +bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const +{ + LLWString wlabel = utf8str_to_wstring(getLabelFromWikiLink(labeled_url)); + wlabel.erase(std::remove(wlabel.begin(), wlabel.end(), L'\u200B'), wlabel.end()); + + // Unicode URL validation, see SL-15243 + std::replace_if(wlabel.begin(), + wlabel.end(), + [](const llwchar &chr) + { + return (chr == L'\u2024') // "One Dot Leader" + || (chr == L'\uFE52') // "Small Full Stop" + || (chr == L'\uFF0E') // "Fullwidth Full Stop" + // Not a decomposition, but suficiently similar + || (chr == L'\u05C5'); // "Hebrew Mark Lower Dot" + }, + L'\u002E'); // Dot "Full Stop" + + std::replace_if(wlabel.begin(), + wlabel.end(), + [](const llwchar &chr) + { + return (chr == L'\u02D0') // "Modifier Letter Colon" + || (chr == L'\uFF1A') // "Fullwidth Colon" + || (chr == L'\uFE55'); // "Small Colon" + }, + L'\u003A'); // Colon + + std::replace_if(wlabel.begin(), + wlabel.end(), + [](const llwchar &chr) + { + return (chr == L'\uFF0F'); // "Fullwidth Solidus" + }, + L'\u002F'); // Solidus + + std::string label = wstring_to_utf8str(wlabel); + if ((label.find(".com") != std::string::npos + || label.find("www.") != std::string::npos) + && label.find("://") == std::string::npos) + { + label = "http://" + label; + } + + return (LLUrlRegistry::instance().hasUrl(label)) ? false : true; } std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 4af1ab5096..102e0a4fd9 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -105,7 +105,7 @@ public: bool isLinkDisabled() const; - bool isWikiLinkCorrect(std::string url); + bool isWikiLinkCorrect(const std::string &url) const; virtual bool isSLURLvalid(const std::string &url) const { return TRUE; }; -- cgit v1.2.3