Commit e5ba4940 authored by Hajime Hoshi's avatar Hajime Hoshi Committed by Commit Bot

autofill: Make MatchesPattern thread-safe

MatchesPattern can be called from multiple threads on single process
mode, and this caused crash on ASAN-built Chromium. This CL fixes this
issue by making MatchesPattern thread-safe.

Bug: 812182
Change-Id: Ibbb3df96264e28fffd0b8e0581f36c6294e02036
Reviewed-on: https://chromium-review.googlesource.com/921302
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#539084}
parent 56e621aa
...@@ -8,18 +8,23 @@ ...@@ -8,18 +8,23 @@
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
#include "base/lazy_instance.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/threading/thread_local.h"
#include "third_party/icu/source/i18n/unicode/regex.h" #include "third_party/icu/source/i18n/unicode/regex.h"
namespace { namespace {
// A singleton class that serves as a cache of compiled regex patterns. // A thread-local class that serves as a cache of compiled regex patterns.
//
// The regexp state can be accessed from multiple threads in single process
// mode, and this class offers per-thread instance instead of per-process
// singleton instance (https://crbug.com/812182).
class AutofillRegexes { class AutofillRegexes {
public: public:
static AutofillRegexes* GetInstance(); static AutofillRegexes* ThreadSpecificInstance();
// Returns the compiled regex matcher corresponding to |pattern|. // Returns the compiled regex matcher corresponding to |pattern|.
icu::RegexMatcher* GetMatcher(const base::string16& pattern); icu::RegexMatcher* GetMatcher(const base::string16& pattern);
...@@ -27,7 +32,6 @@ class AutofillRegexes { ...@@ -27,7 +32,6 @@ class AutofillRegexes {
private: private:
AutofillRegexes(); AutofillRegexes();
~AutofillRegexes(); ~AutofillRegexes();
friend struct base::DefaultSingletonTraits<AutofillRegexes>;
// Maps patterns to their corresponding regex matchers. // Maps patterns to their corresponding regex matchers.
std::unordered_map<base::string16, std::unique_ptr<icu::RegexMatcher>> std::unordered_map<base::string16, std::unique_ptr<icu::RegexMatcher>>
...@@ -36,15 +40,22 @@ class AutofillRegexes { ...@@ -36,15 +40,22 @@ class AutofillRegexes {
DISALLOW_COPY_AND_ASSIGN(AutofillRegexes); DISALLOW_COPY_AND_ASSIGN(AutofillRegexes);
}; };
base::LazyInstance<base::ThreadLocalPointer<AutofillRegexes>>::Leaky
g_autofill_regexes_tls = LAZY_INSTANCE_INITIALIZER;
// static // static
AutofillRegexes* AutofillRegexes::GetInstance() { AutofillRegexes* AutofillRegexes::ThreadSpecificInstance() {
return base::Singleton<AutofillRegexes>::get(); if (g_autofill_regexes_tls.Pointer()->Get())
return g_autofill_regexes_tls.Pointer()->Get();
return new AutofillRegexes;
} }
AutofillRegexes::AutofillRegexes() { AutofillRegexes::AutofillRegexes() {
g_autofill_regexes_tls.Pointer()->Set(this);
} }
AutofillRegexes::~AutofillRegexes() { AutofillRegexes::~AutofillRegexes() {
g_autofill_regexes_tls.Pointer()->Set(nullptr);
} }
icu::RegexMatcher* AutofillRegexes::GetMatcher(const base::string16& pattern) { icu::RegexMatcher* AutofillRegexes::GetMatcher(const base::string16& pattern) {
...@@ -72,7 +83,7 @@ namespace autofill { ...@@ -72,7 +83,7 @@ namespace autofill {
bool MatchesPattern(const base::string16& input, bool MatchesPattern(const base::string16& input,
const base::string16& pattern) { const base::string16& pattern) {
icu::RegexMatcher* matcher = icu::RegexMatcher* matcher =
AutofillRegexes::GetInstance()->GetMatcher(pattern); AutofillRegexes::ThreadSpecificInstance()->GetMatcher(pattern);
icu::UnicodeString icu_input(FALSE, input.data(), input.length()); icu::UnicodeString icu_input(FALSE, input.data(), input.length());
matcher->reset(icu_input); matcher->reset(icu_input);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment