Browse Source

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

Co-authored-by: Cheng Zhao <[email protected]>
trop[bot] 4 years ago
parent
commit
a65fe57342
2 changed files with 149 additions and 0 deletions
  1. 1 0
      patches/chromium/.patches
  2. 148 0
      patches/chromium/fix_hunspell_crash.patch

+ 1 - 0
patches/chromium/.patches

@@ -100,3 +100,4 @@ cherry-pick-7101418f85a0.patch
 cherry-pick-38990b7d56e6.patch
 cherry-pick-67864c214770.patch
 cherry-pick-86c02c5dcd37.patch
+fix_hunspell_crash.patch

+ 148 - 0
patches/chromium/fix_hunspell_crash.patch

@@ -0,0 +1,148 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Cheng Zhao <[email protected]>
+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 67ec4e285d9bf6b9de300845b2c53bda435e5784..74d403aeb1739d0424874a702e64cfd8c3fe4fcb 100644
+--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
++++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
+@@ -91,21 +91,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,16 +128,10 @@ SpellcheckHunspellDictionary::SpellcheckHunspellDictionary(
+ #if !defined(OS_ANDROID)
+       spellcheck_service_(spellcheck_service),
+ #endif
+-      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 +325,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 +337,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 +379,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 +394,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(
+@@ -480,7 +482,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 633ec3a96b39824fc9bcf374e59eb80148a2ae27..bfb90905ee045d8f08dbd0b348204b41fd185f41 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.