summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
authorjshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-29 17:33:55 +0000
committerjshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-29 17:33:55 +0000
commite43c9252f52bda966fed505dd248a0aae035d4fa (patch)
tree32c194fab32a122534c49a239f7512d0c73f065c /net/base
parent9d8a4642dad84e5bc0ca124ed5201a051045a547 (diff)
downloadchromium_src-e43c9252f52bda966fed505dd248a0aae035d4fa.zip
chromium_src-e43c9252f52bda966fed505dd248a0aae035d4fa.tar.gz
chromium_src-e43c9252f52bda966fed505dd248a0aae035d4fa.tar.bz2
Make IsIDNComponentSafe in net/base/net_util.cc thread-safe with a lock.
DCHECK is fired in the IDN safety check-code (IsIDNCOmponentSafe). It turned out that FormatURL (that leads to IsIDNComponentSafe) is called from both the UI thread and the history thread. BUG=NONE TEST=Build a debug build. Put multiple langauges to the Accept-Language list (Options | Advanced | Fonts&Language button | Languages tab). Browse to a few IDN sites and try to type a website url in the omnibox. Review URL: http://codereview.chromium.org/159213 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21963 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r--net/base/net_util.cc77
1 files changed, 41 insertions, 36 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 03c4e4b..0280338 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -29,6 +29,7 @@
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/file_util.h"
+#include "base/lock.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
@@ -526,6 +527,45 @@ void SetExemplarSetForLang(const std::string& lang, UnicodeSet* lang_set) {
map.insert(std::make_pair(lang, lang_set));
}
+static Lock lang_set_lock;
+
+// Returns true if all the characters in component_characters are used by
+// the language |lang|.
+bool IsComponentCoveredByLang(const UnicodeSet& component_characters,
+ const std::string& lang) {
+ static const UnicodeSet kASCIILetters(0x61, 0x7a); // [a-z]
+ UnicodeSet* lang_set;
+ // We're called from both the UI thread and the history thread.
+ {
+ AutoLock lock(lang_set_lock);
+ if (!GetExemplarSetForLang(lang, &lang_set)) {
+ UErrorCode status = U_ZERO_ERROR;
+ ULocaleData* uld = ulocdata_open(lang.c_str(), &status);
+ // TODO(jungshik) Turn this check on when the ICU data file is
+ // rebuilt with the minimal subset of locale data for languages
+ // to which Chrome is not localized but which we offer in the list
+ // of languages selectable for Accept-Languages. With the rebuilt ICU
+ // data, ulocdata_open never should fall back to the default locale.
+ // (issue 2078)
+ // DCHECK(U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING);
+ if (U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING) {
+ lang_set = reinterpret_cast<UnicodeSet *>(
+ ulocdata_getExemplarSet(uld, NULL, 0,
+ ULOCDATA_ES_STANDARD, &status));
+ // If |lang| is compatible with ASCII Latin letters, add them.
+ if (IsCompatibleWithASCIILetters(lang))
+ lang_set->addAll(kASCIILetters);
+ } else {
+ lang_set = new UnicodeSet(1, 0);
+ }
+ lang_set->freeze();
+ SetExemplarSetForLang(lang, lang_set);
+ ulocdata_close(uld);
+ }
+ }
+ return !lang_set->isEmpty() && lang_set->containsAll(component_characters);
+}
+
// Returns true if the given Unicode host component is safe to display to the
// user.
bool IsIDNComponentSafe(const char16* str,
@@ -594,47 +634,12 @@ bool IsIDNComponentSafe(const char16* str,
// the remainder.
component_characters.removeAll(common_characters);
- UnicodeSet ascii_letters(0x61, 0x7a); // [a-z]
bool safe = false;
std::string languages_list(WideToASCII(languages));
StringTokenizer t(languages_list, ",");
while (t.GetNext()) {
- // Locking here may not be that bad, For now, probably
- // we're called only in the UI thread.
- // TODO(jungshik): Add locking if we use it in another
- // thread and DCHECK is triggered.
- static MessageLoop* loop = MessageLoop::current();
- DCHECK(loop == MessageLoop::current());
- std::string lang = t.token();
- UnicodeSet* lang_set;
- if (!GetExemplarSetForLang(lang, &lang_set)) {
- status = U_ZERO_ERROR;
- ULocaleData* uld = ulocdata_open(lang.c_str(), &status);
- // TODO(jungshik) Turn this check on when the ICU data file is
- // rebuilt with the minimal subset of locale data for languages
- // to which Chrome is not localized but which we offer in the list
- // of languages selectable for Accept-Languages. With the rebuilt ICU
- // data, ulocdata_open never should fall back to the default locale.
- // (issue 2078)
- // DCHECK(U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING);
- if (U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING) {
- lang_set = reinterpret_cast<UnicodeSet *>(
- ulocdata_getExemplarSet(uld, NULL, 0,
- ULOCDATA_ES_STANDARD, &status));
- // If |lang| is compatible with ASCII Latin letters, add them.
- if (IsCompatibleWithASCIILetters(lang))
- lang_set->addAll(ascii_letters);
- } else {
- lang_set = new UnicodeSet(1, 0);
- }
- lang_set->freeze();
- SetExemplarSetForLang(lang, lang_set);
- ulocdata_close(uld);
- }
- if (!lang_set->isEmpty() && lang_set->containsAll(component_characters)) {
- safe = true;
+ if (safe = IsComponentCoveredByLang(component_characters, t.token()))
break;
- }
}
return safe;
}