fix: make sure hunspell file is not destroyed in UI thread (#23631)

This commit is contained in:
Cheng Zhao 2020-05-19 22:55:23 +09:00 committed by GitHub
parent 01579cc8ed
commit 38a04214e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 148 additions and 0 deletions

View file

@ -95,3 +95,4 @@ breakpad_treat_node_processes_as_browser_processes.patch
upload_list_add_loadsync_method.patch
breakpad_allow_getting_string_values_for_crash_keys.patch
crash_allow_disabling_compression_on_linux.patch
fix_hunspell_crash.patch

View file

@ -0,0 +1,147 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: Make sure hunspell file is not destroyed in UI thread
Submitted to Chromium at:
https://chromium-review.googlesource.com/c/chromium/src/+/2206199/1
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
index 653ef44ff095015ef25cc59bf42f9fbd9d907160..d6f9bf8e0d2cf2e52698d4d132361a5d7118d00c 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
@@ -93,21 +93,28 @@ bool SaveDictionaryData(std::unique_ptr<std::string> data,
} // namespace
-SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile() {
-}
+SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile(
+ base::TaskRunner* task_runner) : task_runner_(task_runner) {}
SpellcheckHunspellDictionary::DictionaryFile::~DictionaryFile() {
+ if (file.IsValid()) {
+ task_runner_->PostTask(FROM_HERE,
+ base::BindOnce(&CloseDictionary, std::move(file)));
+ }
}
SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile(
DictionaryFile&& other)
- : path(other.path), file(std::move(other.file)) {}
+ : path(other.path),
+ file(std::move(other.file)),
+ task_runner_(std::move(other.task_runner_)) {}
SpellcheckHunspellDictionary::DictionaryFile&
SpellcheckHunspellDictionary::DictionaryFile::operator=(
DictionaryFile&& other) {
path = other.path;
file = std::move(other.file);
+ task_runner_ = std::move(other.task_runner_);
return *this;
}
@@ -121,15 +128,10 @@ SpellcheckHunspellDictionary::SpellcheckHunspellDictionary(
use_browser_spellchecker_(false),
browser_context_(browser_context),
spellcheck_service_(spellcheck_service),
- download_status_(DOWNLOAD_NONE) {}
+ download_status_(DOWNLOAD_NONE),
+ dictionary_file_(task_runner_.get()) {}
SpellcheckHunspellDictionary::~SpellcheckHunspellDictionary() {
- if (dictionary_file_.file.IsValid()) {
- task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CloseDictionary, std::move(dictionary_file_.file)));
- }
-
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Disable the language from platform spellchecker.
if (spellcheck::UseBrowserSpellChecker())
@@ -324,7 +326,8 @@ void SpellcheckHunspellDictionary::DownloadDictionary(GURL url) {
#if !defined(OS_ANDROID)
// static
SpellcheckHunspellDictionary::DictionaryFile
-SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
+SpellcheckHunspellDictionary::OpenDictionaryFile(base::TaskRunner* task_runner,
+ const base::FilePath& path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
@@ -335,7 +338,7 @@ SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
// For systemwide installations on Windows, the default directory may not
// have permissions for download. In that case, the alternate directory for
// download is chrome::DIR_USER_DATA.
- DictionaryFile dictionary;
+ DictionaryFile dictionary(task_runner);
#if defined(OS_WIN)
// Check if the dictionary exists in the fallback location. If so, use it
@@ -377,7 +380,7 @@ SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
// static
SpellcheckHunspellDictionary::DictionaryFile
SpellcheckHunspellDictionary::InitializeDictionaryLocation(
- const std::string& language) {
+ base::TaskRunner* task_runner, const std::string& language) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
@@ -392,7 +395,7 @@ SpellcheckHunspellDictionary::InitializeDictionaryLocation(
base::FilePath dict_path =
spellcheck::GetVersionedFileName(language, dict_dir);
- return OpenDictionaryFile(dict_path);
+ return OpenDictionaryFile(task_runner, dict_path);
}
void SpellcheckHunspellDictionary::InitializeDictionaryLocationComplete(
@@ -481,7 +484,8 @@ void SpellcheckHunspellDictionary::PlatformSupportsLanguageComplete(
#if !defined(OS_ANDROID) && BUILDFLAG(USE_RENDERER_SPELLCHECKER)
base::PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
- base::BindOnce(&InitializeDictionaryLocation, language_),
+ base::BindOnce(&InitializeDictionaryLocation,
+ base::RetainedRef(task_runner_.get()), language_),
base::BindOnce(
&SpellcheckHunspellDictionary::InitializeDictionaryLocationComplete,
weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
index 4662bdc08b54304a7f8b2995f60fea9dc5617fff..7679f526c05980889adb2f6a8a0c20dd7f5415c3 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
@@ -99,7 +99,7 @@ class SpellcheckHunspellDictionary
// blocking sequence.
struct DictionaryFile {
public:
- DictionaryFile();
+ explicit DictionaryFile(base::TaskRunner* task_runner);
~DictionaryFile();
DictionaryFile(DictionaryFile&& other);
@@ -112,6 +112,9 @@ class SpellcheckHunspellDictionary
base::File file;
private:
+ // Task runner where the file is created.
+ scoped_refptr<base::TaskRunner> task_runner_;
+
DISALLOW_COPY_AND_ASSIGN(DictionaryFile);
};
@@ -126,11 +129,12 @@ class SpellcheckHunspellDictionary
#if !defined(OS_ANDROID)
// Figures out the location for the dictionary, verifies its contents, and
// opens it.
- static DictionaryFile OpenDictionaryFile(const base::FilePath& path);
+ static DictionaryFile OpenDictionaryFile(base::TaskRunner* task_runner,
+ const base::FilePath& path);
// Gets the default location for the dictionary file.
static DictionaryFile InitializeDictionaryLocation(
- const std::string& language);
+ base::TaskRunner* task_runner, const std::string& language);
// The reply point for PostTaskAndReplyWithResult, called after the dictionary
// file has been initialized.