summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-06-02 23:26:48 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-06-03 19:50:08 +0300
commitb6ac642db2213cf4207dddc47a1fe1490de0cc6e (patch)
tree152f58e40a2f1489384aaf3960330d3c44f62805 /indra/llui
parentd14ebd1f52a878ef7ae17f3a633a4f24297d1fca (diff)
SL-15243 Unicode URL validation
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llurlentry.cpp50
-rw-r--r--indra/llui/llurlentry.h2
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; };