EXT-944 EXT-1026: reverting my previous fix for these crashes.
This didn't work on Windows because wchar_t is 2 bytes on that platform, not 4 bytes (whereas llwchar is 4 bytes everywhere). Boost's regex methods need to work on wchar_t, but I believe that using a UTF-16 string would still be prone to crashing on Windows as UTF-16 is still a variable-length encoding. Besides, trying to compile a UTF-16 solution generates weird link errors. Instead, I'm going to fix this problem a different way. And I'm starting by reverting the previous attempt. Thanks Win32.master
parent
658849ee95
commit
47abd55908
|
|
@ -429,7 +429,7 @@ LLContextMenu *LLTextBase::createUrlContextMenu(const std::string &in_url)
|
|||
// work out the XUI menu file to use for this url
|
||||
LLUrlMatch match;
|
||||
std::string url = in_url;
|
||||
if (! LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match))
|
||||
if (! LLUrlRegistry::instance().findUrl(url, match))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ LLWString LLTextBox::getWrappedText(const LLStringExplicit& in_text, F32 max_wid
|
|||
|
||||
// find the next Url in the text string
|
||||
LLUrlMatch match;
|
||||
while ( LLUrlRegistry::instance().findUrl(wtext, match))
|
||||
while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(wtext), match))
|
||||
{
|
||||
S32 start = match.getStart();
|
||||
S32 end = match.getEnd() + 1;
|
||||
|
|
@ -573,7 +573,7 @@ void LLTextBox::updateDisplayTextAndSegments()
|
|||
LLWString text = mText.getWString();
|
||||
|
||||
// find the next Url in the text string
|
||||
while ( LLUrlRegistry::instance().findUrl(text, match,
|
||||
while ( LLUrlRegistry::instance().findUrl(wstring_to_utf8str(text), match,
|
||||
boost::bind(&LLTextBox::onUrlLabelUpdated, this, _1, _2)) )
|
||||
{
|
||||
// work out the char offset for the start/end of the url
|
||||
|
|
|
|||
|
|
@ -3525,7 +3525,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
|
|||
|
||||
S32 start=0,end=0;
|
||||
LLUrlMatch match;
|
||||
LLWString text = utf8str_to_wstring(new_text);
|
||||
std::string text = new_text;
|
||||
while ( LLUrlRegistry::instance().findUrl(text, match,
|
||||
boost::bind(&LLTextEditor::onUrlLabelUpdated, this, _1, _2)) )
|
||||
{
|
||||
|
|
@ -3549,8 +3549,8 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
|
|||
{
|
||||
part = (S32)LLTextParser::MIDDLE;
|
||||
}
|
||||
std::string subtext = wstring_to_utf8str(text.substr(0,start));
|
||||
appendHighlightedText(subtext, allow_undo, prepend_newline, part, style_params);
|
||||
std::string subtext=text.substr(0,start);
|
||||
appendHighlightedText(subtext,allow_undo, prepend_newline, part, style_params);
|
||||
prepend_newline = false;
|
||||
}
|
||||
|
||||
|
|
@ -3595,8 +3595,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
|
|||
}
|
||||
}
|
||||
if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END;
|
||||
if (end < (S32)text.length()) appendHighlightedText(wstring_to_utf8str(text), allow_undo,
|
||||
prepend_newline, part, style_params);
|
||||
if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, style_params);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -4138,7 +4137,7 @@ void LLTextEditor::updateLinkSegments()
|
|||
LLUrlMatch match;
|
||||
LLStyleSP style = static_cast<LLStyleSP>(segment->getStyle());
|
||||
std::string url_label = getText().substr(segment->getStart(), segment->getEnd()-segment->getStart());
|
||||
if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url_label), match))
|
||||
if (LLUrlRegistry::instance().findUrl(url_label, match))
|
||||
{
|
||||
LLStringUtil::trim(url_label);
|
||||
style->setLinkHREF(url_label);
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ void LLUrlAction::clickAction(std::string url)
|
|||
void LLUrlAction::teleportToLocation(std::string url)
|
||||
{
|
||||
LLUrlMatch match;
|
||||
if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match))
|
||||
if (LLUrlRegistry::instance().findUrl(url, match))
|
||||
{
|
||||
if (! match.getLocation().empty())
|
||||
{
|
||||
|
|
@ -129,7 +129,7 @@ void LLUrlAction::copyURLToClipboard(std::string url)
|
|||
void LLUrlAction::copyLabelToClipboard(std::string url)
|
||||
{
|
||||
LLUrlMatch match;
|
||||
if (LLUrlRegistry::instance().findUrl(utf8str_to_wstring(url), match))
|
||||
if (LLUrlRegistry::instance().findUrl(url, match))
|
||||
{
|
||||
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab
|
|||
//
|
||||
LLUrlEntryHTTP::LLUrlEntryHTTP()
|
||||
{
|
||||
mPattern = boost::wregex(L"https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_http.xml";
|
||||
mTooltip = LLTrans::getString("TooltipHttpUrl");
|
||||
//mIcon = "gear.tga";
|
||||
|
|
@ -166,8 +166,8 @@ std::string LLUrlEntryHTTP::getLabel(const std::string &url, const LLUrlLabelCal
|
|||
//
|
||||
LLUrlEntryHTTPLabel::LLUrlEntryHTTPLabel()
|
||||
{
|
||||
mPattern = boost::wregex(L"\\[https?://\\S+[ \t]+[^\\]]+\\]",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("\\[https?://\\S+[ \t]+[^\\]]+\\]",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_http.xml";
|
||||
mTooltip = LLTrans::getString("TooltipHttpUrl");
|
||||
}
|
||||
|
|
@ -188,8 +188,8 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string)
|
|||
LLUrlEntrySLURL::LLUrlEntrySLURL()
|
||||
{
|
||||
// see http://slurl.com/about.php for details on the SLURL format
|
||||
mPattern = boost::wregex(L"http://slurl.com/secondlife/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("http://slurl.com/secondlife/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_slurl.xml";
|
||||
mTooltip = LLTrans::getString("TooltipSLURL");
|
||||
}
|
||||
|
|
@ -260,8 +260,8 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
|
|||
//
|
||||
LLUrlEntryAgent::LLUrlEntryAgent()
|
||||
{
|
||||
mPattern = boost::wregex(L"secondlife:///app/agent/[\\da-f-]+/about",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/about",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_agent.xml";
|
||||
mTooltip = LLTrans::getString("TooltipAgentUrl");
|
||||
}
|
||||
|
|
@ -302,8 +302,8 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
|
|||
//
|
||||
LLUrlEntryGroup::LLUrlEntryGroup()
|
||||
{
|
||||
mPattern = boost::wregex(L"secondlife:///app/group/[\\da-f-]+/about",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/about",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_group.xml";
|
||||
mTooltip = LLTrans::getString("TooltipGroupUrl");
|
||||
}
|
||||
|
|
@ -344,8 +344,8 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
|
|||
///
|
||||
LLUrlEntryParcel::LLUrlEntryParcel()
|
||||
{
|
||||
mPattern = boost::wregex(L"secondlife:///app/parcel/[\\da-f-]+/about",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_parcel.xml";
|
||||
mTooltip = LLTrans::getString("TooltipParcelUrl");
|
||||
}
|
||||
|
|
@ -360,8 +360,8 @@ std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelC
|
|||
//
|
||||
LLUrlEntryPlace::LLUrlEntryPlace()
|
||||
{
|
||||
mPattern = boost::wregex(L"secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_slurl.xml";
|
||||
mTooltip = LLTrans::getString("TooltipSLURL");
|
||||
}
|
||||
|
|
@ -416,8 +416,8 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
|
|||
//
|
||||
LLUrlEntryTeleport::LLUrlEntryTeleport()
|
||||
{
|
||||
mPattern = boost::wregex(L"secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_teleport.xml";
|
||||
mTooltip = LLTrans::getString("TooltipTeleportUrl");
|
||||
}
|
||||
|
|
@ -488,8 +488,8 @@ std::string LLUrlEntryTeleport::getLocation(const std::string &url) const
|
|||
///
|
||||
LLUrlEntryObjectIM::LLUrlEntryObjectIM()
|
||||
{
|
||||
mPattern = boost::wregex(L"secondlife:///app/objectim/[\\da-f-]+\\??\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\\??\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_objectim.xml";
|
||||
mTooltip = LLTrans::getString("TooltipObjectIMUrl");
|
||||
}
|
||||
|
|
@ -532,8 +532,8 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
|
|||
//
|
||||
LLUrlEntrySL::LLUrlEntrySL()
|
||||
{
|
||||
mPattern = boost::wregex(L"secondlife://(\\w+)?(:\\d+)?/\\S+",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("secondlife://(\\w+)?(:\\d+)?/\\S+",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_slapp.xml";
|
||||
mTooltip = LLTrans::getString("TooltipSLAPP");
|
||||
}
|
||||
|
|
@ -549,8 +549,8 @@ std::string LLUrlEntrySL::getLabel(const std::string &url, const LLUrlLabelCallb
|
|||
//
|
||||
LLUrlEntrySLLabel::LLUrlEntrySLLabel()
|
||||
{
|
||||
mPattern = boost::wregex(L"\\[secondlife://\\S+[ \t]+[^\\]]+\\]",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mPattern = boost::regex("\\[secondlife://\\S+[ \t]+[^\\]]+\\]",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_slapp.xml";
|
||||
mTooltip = LLTrans::getString("TooltipSLAPP");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
virtual ~LLUrlEntryBase();
|
||||
|
||||
/// Return the regex pattern that matches this Url
|
||||
boost::wregex getPattern() const { return mPattern; }
|
||||
boost::regex getPattern() const { return mPattern; }
|
||||
|
||||
/// Return the url from a string that matched the regex
|
||||
virtual std::string getUrl(const std::string &string);
|
||||
|
|
@ -102,7 +102,7 @@ protected:
|
|||
LLUrlLabelSignal *signal;
|
||||
} LLUrlEntryObserver;
|
||||
|
||||
boost::wregex mPattern;
|
||||
boost::regex mPattern;
|
||||
std::string mIcon;
|
||||
std::string mMenuName;
|
||||
std::string mTooltip;
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ void LLUrlRegistry::registerUrl(LLUrlEntryBase *url)
|
|||
}
|
||||
}
|
||||
|
||||
static bool matchRegex(const wchar_t *text, boost::wregex regex, U32 &start, U32 &end)
|
||||
static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &end)
|
||||
{
|
||||
boost::wcmatch result;
|
||||
boost::cmatch result;
|
||||
bool found;
|
||||
|
||||
// regex_search can potentially throw an exception, so check for it
|
||||
|
|
@ -107,7 +107,7 @@ static bool matchRegex(const wchar_t *text, boost::wregex regex, U32 &start, U32
|
|||
}
|
||||
// ignore a terminating ')' when Url contains no matching '('
|
||||
// see DEV-19842 for details
|
||||
else if (text[end] == ')' && LLWString(text+start, end-start).find('(') == std::string::npos)
|
||||
else if (text[end] == ')' && std::string(text+start, end-start).find('(') == std::string::npos)
|
||||
{
|
||||
end--;
|
||||
}
|
||||
|
|
@ -115,10 +115,10 @@ static bool matchRegex(const wchar_t *text, boost::wregex regex, U32 &start, U32
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
|
||||
bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
|
||||
{
|
||||
// avoid costly regexes if there is clearly no URL in the text
|
||||
if (text.find(L"://") == std::string::npos)
|
||||
if (text.find("://") == std::string::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
|
|||
if (match_entry)
|
||||
{
|
||||
// fill in the LLUrlMatch object and return it
|
||||
std::string url = wstring_to_utf8str(text.substr(match_start, match_end - match_start + 1));
|
||||
std::string url = text.substr(match_start, match_end - match_start + 1);
|
||||
match.setValues(match_start, match_end,
|
||||
match_entry->getUrl(url),
|
||||
match_entry->getLabel(url, cb),
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "llurlentry.h"
|
||||
#include "llurlmatch.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llstring.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
@ -75,7 +74,7 @@ public:
|
|||
|
||||
/// get the next Url in an input string, starting at a given character offset
|
||||
/// your callback is invoked if the matched Url's label changes in the future
|
||||
bool findUrl(const LLWString &text, LLUrlMatch &match,
|
||||
bool findUrl(const std::string &text, LLUrlMatch &match,
|
||||
const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -44,19 +44,17 @@ namespace
|
|||
|
||||
namespace tut
|
||||
{
|
||||
void testRegex(const std::string &testname, boost::wregex regex,
|
||||
void testRegex(const std::string &testname, boost::regex regex,
|
||||
const char *text, const std::string &expected)
|
||||
{
|
||||
std::string url = "";
|
||||
boost::wcmatch result;
|
||||
LLWString wtext = utf8str_to_wstring(text);
|
||||
const wchar_t *wctext = wtext.c_str();
|
||||
bool found = boost::regex_search(wctext, result, regex);
|
||||
boost::cmatch result;
|
||||
bool found = boost::regex_search(text, result, regex);
|
||||
if (found)
|
||||
{
|
||||
S32 start = static_cast<U32>(result[0].first - wctext);
|
||||
S32 end = static_cast<U32>(result[0].second - wctext);
|
||||
url = wstring_to_utf8str(wtext.substr(start, end-start));
|
||||
S32 start = static_cast<U32>(result[0].first - text);
|
||||
S32 end = static_cast<U32>(result[0].second - text);
|
||||
url = std::string(text+start, end-start);
|
||||
}
|
||||
ensure_equals(testname, url, expected);
|
||||
}
|
||||
|
|
@ -68,7 +66,7 @@ namespace tut
|
|||
// test LLUrlEntryHTTP - standard http Urls
|
||||
//
|
||||
LLUrlEntryHTTP url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("no valid url", r,
|
||||
"htp://slurl.com/",
|
||||
|
|
@ -147,7 +145,7 @@ namespace tut
|
|||
// test LLUrlEntryHTTPLabel - wiki-style http Urls with labels
|
||||
//
|
||||
LLUrlEntryHTTPLabel url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("invalid wiki url [1]", r,
|
||||
"[http://www.example.org]",
|
||||
|
|
@ -189,7 +187,7 @@ namespace tut
|
|||
// test LLUrlEntrySLURL - second life URLs
|
||||
//
|
||||
LLUrlEntrySLURL url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("no valid slurl [1]", r,
|
||||
"htp://slurl.com/secondlife/Ahern/50/50/50/",
|
||||
|
|
@ -261,7 +259,7 @@ namespace tut
|
|||
// test LLUrlEntryAgent - secondlife://app/agent Urls
|
||||
//
|
||||
LLUrlEntryAgent url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("Invalid Agent Url", r,
|
||||
"secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about",
|
||||
|
|
@ -287,7 +285,7 @@ namespace tut
|
|||
// test LLUrlEntryGroup - secondlife://app/group Urls
|
||||
//
|
||||
LLUrlEntryGroup url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("Invalid Group Url", r,
|
||||
"secondlife:///app/group/00005ff3-4044-c79f-XXXX-fb28ae0df991/about",
|
||||
|
|
@ -313,7 +311,7 @@ namespace tut
|
|||
// test LLUrlEntryPlace - secondlife://<location> URLs
|
||||
//
|
||||
LLUrlEntryPlace url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("no valid slurl [1]", r,
|
||||
"secondlife://Ahern/FOO/50/",
|
||||
|
|
@ -361,7 +359,7 @@ namespace tut
|
|||
// test LLUrlEntryParcel - secondlife://app/parcel Urls
|
||||
//
|
||||
LLUrlEntryParcel url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("Invalid Classified Url", r,
|
||||
"secondlife:///app/parcel/0000060e-4b39-e00b-XXXX-d98b1934e3a8/about",
|
||||
|
|
@ -386,7 +384,7 @@ namespace tut
|
|||
// test LLUrlEntryTeleport - secondlife://app/teleport URLs
|
||||
//
|
||||
LLUrlEntryTeleport url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("no valid teleport [1]", r,
|
||||
"http://slurl.com/secondlife/Ahern/50/50/50/",
|
||||
|
|
@ -462,7 +460,7 @@ namespace tut
|
|||
// test LLUrlEntrySL - general secondlife:// URLs
|
||||
//
|
||||
LLUrlEntrySL url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("no valid slapp [1]", r,
|
||||
"http:///app/",
|
||||
|
|
@ -500,7 +498,7 @@ namespace tut
|
|||
// test LLUrlEntrySLLabel - general secondlife:// URLs with labels
|
||||
//
|
||||
LLUrlEntrySLLabel url;
|
||||
boost::wregex r = url.getPattern();
|
||||
boost::regex r = url.getPattern();
|
||||
|
||||
testRegex("invalid wiki url [1]", r,
|
||||
"[secondlife:///app/]",
|
||||
|
|
|
|||
Loading…
Reference in New Issue