//components/spellcheck: Fix 64-bit truncation issues

Bug: 633312, 879657
Change-Id: I25aa719c1632b7cf6b8191ce1523a6f230b98142
Reviewed-on: https://chromium-review.googlesource.com/c/1450592
Reviewed-by: Mike West <[email protected]>
Reviewed-by: Tim Volodine <[email protected]>
Commit-Queue: Mike West <[email protected]>
Auto-Submit: Raul Tambre <[email protected]>
Cr-Commit-Position: refs/heads/master@{#630726}
diff --git a/components/spellcheck/browser/spellcheck_host_metrics.cc b/components/spellcheck/browser/spellcheck_host_metrics.cc
index bfd92be..1565b64 100644
--- a/components/spellcheck/browser/spellcheck_host_metrics.cc
+++ b/components/spellcheck/browser/spellcheck_host_metrics.cc
@@ -8,6 +8,7 @@
 
 #include "base/md5.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/numerics/safe_conversions.h"
 
 SpellCheckHostMetrics::SpellCheckHostMetrics()
     : misspelled_word_count_(0),
@@ -18,7 +19,7 @@
       last_suggestion_show_count_(-1),
       replaced_word_count_(0),
       last_replaced_word_count_(-1),
-      last_unique_word_count_(-1),
+      last_unique_word_count_(0),
       start_time_(base::TimeTicks::Now()) {
   const uint64_t kHistogramTimerDurationInMinutes = 30;
   recording_timer_.Start(FROM_HERE,
@@ -32,7 +33,8 @@
 
 // static
 void SpellCheckHostMetrics::RecordCustomWordCountStats(size_t count) {
-  UMA_HISTOGRAM_COUNTS_1M("SpellCheck.CustomWords", count);
+  UMA_HISTOGRAM_COUNTS_1M("SpellCheck.CustomWords",
+                          base::saturated_cast<int>(count));
 }
 
 void SpellCheckHostMetrics::RecordEnabledStats(bool enabled) {
@@ -79,7 +81,7 @@
     size_t checked_words_per_hour = spellchecked_word_count_ *
         base::TimeDelta::FromHours(1).InSeconds() / since_start.InSeconds();
     UMA_HISTOGRAM_COUNTS_1M("SpellCheck.CheckedWordsPerHour",
-                            checked_words_per_hour);
+                            base::saturated_cast<int>(checked_words_per_hour));
   }
 }
 
@@ -133,10 +135,11 @@
     last_replaced_word_count_ = replaced_word_count_;
   }
 
-  if (((int)checked_word_hashes_.size()) != last_unique_word_count_) {
-    DCHECK((int)checked_word_hashes_.size() > last_unique_word_count_);
-    UMA_HISTOGRAM_COUNTS_1M("SpellCheck.UniqueWords",
-                            checked_word_hashes_.size());
+  if (checked_word_hashes_.size() != last_unique_word_count_) {
+    DCHECK(checked_word_hashes_.size() > last_unique_word_count_);
+    UMA_HISTOGRAM_COUNTS_1M(
+        "SpellCheck.UniqueWords",
+        base::saturated_cast<int>(checked_word_hashes_.size()));
     last_unique_word_count_ = checked_word_hashes_.size();
   }
 
diff --git a/components/spellcheck/browser/spellcheck_host_metrics.h b/components/spellcheck/browser/spellcheck_host_metrics.h
index 795e258..08e1e401 100644
--- a/components/spellcheck/browser/spellcheck_host_metrics.h
+++ b/components/spellcheck/browser/spellcheck_host_metrics.h
@@ -85,7 +85,7 @@
   int last_replaced_word_count_;
 
   // Last recorded number of unique words.
-  int last_unique_word_count_;
+  size_t last_unique_word_count_;
 
   // Time when first spellcheck happened.
   base::TimeTicks start_time_;
diff --git a/components/spellcheck/renderer/BUILD.gn b/components/spellcheck/renderer/BUILD.gn
index f5db20f..d993ecf 100644
--- a/components/spellcheck/renderer/BUILD.gn
+++ b/components/spellcheck/renderer/BUILD.gn
@@ -57,10 +57,6 @@
   if (!is_android) {
     deps += [ "//third_party/hunspell" ]
   }
-
-  if (is_win) {
-    cflags = [ "/wd4267" ]  # conversion from 'size_t' to 'int' on x64 (crbug.com/633312)
-  }
 }
 
 source_set("unit_tests") {
@@ -105,8 +101,4 @@
   if (is_mac && !is_ios) {
     deps += [ "//third_party/hunspell" ]
   }
-
-  if (is_win) {
-    cflags = [ "/wd4267" ]  # conversion from 'size_t' to 'int' on x64 (crbug.com/633312)
-  }
 }
diff --git a/components/spellcheck/renderer/custom_dictionary_engine.cc b/components/spellcheck/renderer/custom_dictionary_engine.cc
index e00b7ec..0e2fe22 100644
--- a/components/spellcheck/renderer/custom_dictionary_engine.cc
+++ b/components/spellcheck/renderer/custom_dictionary_engine.cc
@@ -35,15 +35,12 @@
     dictionary_.erase(base::UTF8ToUTF16(word));
 }
 
-bool CustomDictionaryEngine::SpellCheckWord(
-    const base::string16& text,
-    int misspelling_start,
-    int misspelling_len) {
+bool CustomDictionaryEngine::SpellCheckWord(const base::string16& text,
+                                            size_t misspelling_start,
+                                            size_t misspelling_len) {
   // The text to be checked is empty on OSX(async) right now.
   // TODO(groby): Fix as part of async hook-up. (http://crbug.com/178241)
-  return
-      misspelling_start >= 0 &&
-      misspelling_len > 0 &&
-      size_t(misspelling_start + misspelling_len) <= text.length() &&
-      dictionary_.count(text.substr(misspelling_start, misspelling_len)) > 0;
+  return misspelling_len > 0 &&
+         misspelling_start + misspelling_len <= text.length() &&
+         dictionary_.count(text.substr(misspelling_start, misspelling_len)) > 0;
 }
diff --git a/components/spellcheck/renderer/custom_dictionary_engine.h b/components/spellcheck/renderer/custom_dictionary_engine.h
index 52e37e6..33af501 100644
--- a/components/spellcheck/renderer/custom_dictionary_engine.h
+++ b/components/spellcheck/renderer/custom_dictionary_engine.h
@@ -26,8 +26,8 @@
   // |misspelling_start| and |misspelling_len| to indicate a misspelling.
   // Returns true if there are no misspellings, otherwise returns false.
   bool SpellCheckWord(const base::string16& text,
-                      int misspelling_start,
-                      int misspelling_len);
+                      size_t misspelling_start,
+                      size_t misspelling_len);
 
   // Update custom dictionary words.
   void OnCustomDictionaryChanged(const std::set<std::string>& words_added,
diff --git a/components/spellcheck/renderer/spellcheck.cc b/components/spellcheck/renderer/spellcheck.cc
index 67e8aa82..7ffa316 100644
--- a/components/spellcheck/renderer/spellcheck.cc
+++ b/components/spellcheck/renderer/spellcheck.cc
@@ -244,11 +244,11 @@
 
 bool SpellCheck::SpellCheckWord(
     const base::char16* text_begin,
-    int position_in_text,
-    int text_length,
+    size_t position_in_text,
+    size_t text_length,
     int tag,
-    int* misspelling_start,
-    int* misspelling_len,
+    size_t* misspelling_start,
+    size_t* misspelling_len,
     std::vector<base::string16>* optional_suggestions) {
   DCHECK(text_length >= position_in_text);
   DCHECK(misspelling_start && misspelling_len) << "Out vars must be given.";
@@ -260,10 +260,10 @@
 
   // These are for holding misspelling or skippable word positions and lengths
   // between calls to SpellcheckLanguage::SpellCheckWord.
-  int possible_misspelling_start;
-  int possible_misspelling_len;
+  size_t possible_misspelling_start;
+  size_t possible_misspelling_len;
   // The longest sequence of text that all languages agree is skippable.
-  int agreed_skippable_len;
+  size_t agreed_skippable_len;
   // A vector of vectors containing spelling suggestions from different
   // languages.
   std::vector<std::vector<base::string16>> suggestions_list;
@@ -356,8 +356,8 @@
   // position and length of the first misspelled word and returns false when
   // the text includes misspelled words. Therefore, we just repeat calling the
   // function until it returns true to check the whole text.
-  int misspelling_start = 0;
-  int misspelling_length = 0;
+  size_t misspelling_start = 0;
+  size_t misspelling_length = 0;
   while (position_in_text <= length) {
     if (SpellCheckWord(text.c_str(), position_in_text, length, kNoTag,
                        &misspelling_start, &misspelling_length, nullptr)) {
@@ -369,7 +369,8 @@
             text, misspelling_start, misspelling_length)) {
       textcheck_results.push_back(
           WebTextCheckingResult(blink::kWebTextDecorationTypeSpelling,
-                                misspelling_start, misspelling_length));
+                                base::checked_cast<int>(misspelling_start),
+                                base::checked_cast<int>(misspelling_length)));
     }
     position_in_text = misspelling_start + misspelling_length;
   }
@@ -485,8 +486,8 @@
       // Double-check misspelled words with out spellchecker and attach grammar
       // markers to them if our spellchecker tells us they are correct words,
       // i.e. they are probably contextually-misspelled words.
-      int unused_misspelling_start = 0;
-      int unused_misspelling_length = 0;
+      size_t unused_misspelling_start = 0;
+      size_t unused_misspelling_length = 0;
       if (decoration == SpellCheckResult::SPELLING &&
           SpellCheckWord(misspelled_word.c_str(), kNoOffset,
                          misspelled_word.length(), kNoTag,
diff --git a/components/spellcheck/renderer/spellcheck.h b/components/spellcheck/renderer/spellcheck.h
index 44c1168..e12e4f9 100644
--- a/components/spellcheck/renderer/spellcheck.h
+++ b/components/spellcheck/renderer/spellcheck.h
@@ -86,11 +86,11 @@
   // If optional_suggestions is NULL, suggested words will not be looked up.
   // Note that doing suggest lookups can be slow.
   bool SpellCheckWord(const base::char16* text_begin,
-                      int position_in_text,
-                      int text_length,
+                      size_t position_in_text,
+                      size_t text_length,
                       int tag,
-                      int* misspelling_start,
-                      int* misspelling_len,
+                      size_t* misspelling_start,
+                      size_t* misspelling_len,
                       std::vector<base::string16>* optional_suggestions);
 
   // SpellCheck a paragraph.
diff --git a/components/spellcheck/renderer/spellcheck_language.cc b/components/spellcheck/renderer/spellcheck_language.cc
index a518c43..391e36a 100644
--- a/components/spellcheck/renderer/spellcheck_language.cc
+++ b/components/spellcheck/renderer/spellcheck_language.cc
@@ -34,16 +34,16 @@
 
 SpellcheckLanguage::SpellcheckWordResult SpellcheckLanguage::SpellCheckWord(
     const base::char16* text_begin,
-    int position_in_text,
-    int text_length,
+    size_t position_in_text,
+    size_t text_length,
     int tag,
-    int* skip_or_misspelling_start,
-    int* skip_or_misspelling_len,
+    size_t* skip_or_misspelling_start,
+    size_t* skip_or_misspelling_len,
     std::vector<base::string16>* optional_suggestions) {
-  int remaining_text_len = text_length - position_in_text;
-  DCHECK(remaining_text_len >= 0);
+  DCHECK_GE(text_length, position_in_text);
   DCHECK(skip_or_misspelling_start && skip_or_misspelling_len)
       << "Out vars must be given.";
+  size_t remaining_text_len = text_length - position_in_text;
 
   // Do nothing if we need to delay initialization. (Rather than blocking,
   // report the word as correctly spelled.)
@@ -60,8 +60,8 @@
     return IS_CORRECT;  // No input means always spelled correctly.
 
   base::string16 word;
-  int word_start;
-  int word_length;
+  size_t word_start;
+  size_t word_length;
   if (!text_iterator_.IsInitialized() &&
       !text_iterator_.Initialize(&character_attributes_, true)) {
       // We failed to initialize text_iterator_, return as spelled correctly.
@@ -126,8 +126,8 @@
   contraction_iterator_.SetText(contraction.c_str(), contraction.length());
 
   base::string16 word;
-  int word_start;
-  int word_length;
+  size_t word_start;
+  size_t word_length;
 
   DCHECK(platform_spelling_engine_);
   for (SpellcheckWordIterator::WordIteratorStatus status =
diff --git a/components/spellcheck/renderer/spellcheck_language.h b/components/spellcheck/renderer/spellcheck_language.h
index 98bcf60..082ce80 100644
--- a/components/spellcheck/renderer/spellcheck_language.h
+++ b/components/spellcheck/renderer/spellcheck_language.h
@@ -58,15 +58,15 @@
   //   |skip_or_misspelling_start| and |skip_or_misspelling_len| are then set to
   //   the position and length of the misspelled word. In addition, finds the
   //   suggested words for a given misspelled word and puts them into
-  //   |*optional_suggestions|. If optional_suggestions is NULL, suggested words
-  //   will not be looked up. Note that doing suggest lookups can be slow.
+  //   |*optional_suggestions|. If optional_suggestions is nullptr, suggested
+  //   words will not be looked up. Note that doing suggest lookups can be slow.
   SpellcheckWordResult SpellCheckWord(
       const base::char16* text_begin,
-      int position_in_text,
-      int text_length,
+      size_t position_in_text,
+      size_t text_length,
       int tag,
-      int* skip_or_misspelling_start,
-      int* skip_or_misspelling_len,
+      size_t* skip_or_misspelling_start,
+      size_t* skip_or_misspelling_len,
       std::vector<base::string16>* optional_suggestions);
 
   // Initialize |spellcheck_| if that hasn't happened yet.
diff --git a/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc b/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
index f356798..62bbdac 100644
--- a/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
+++ b/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
@@ -31,8 +31,8 @@
   // A string of text for checking.
   const wchar_t* input;
   // The position and the length of the first misspelled word, if any.
-  int expected_misspelling_start;
-  int expected_misspelling_length;
+  size_t expected_misspelling_start;
+  size_t expected_misspelling_length;
 };
 
 base::FilePath GetHunspellDirectory() {
@@ -82,8 +82,8 @@
     ReinitializeSpellCheck(languages);
 
     for (size_t i = 0; i < num_test_cases; ++i) {
-      int misspelling_start = 0;
-      int misspelling_length = 0;
+      size_t misspelling_start = 0;
+      size_t misspelling_length = 0;
       static_cast<blink::WebTextCheckClient*>(provider())
           ->CheckSpelling(blink::WebString::FromUTF16(
                               base::WideToUTF16(test_cases[i].input)),
@@ -225,8 +225,8 @@
     // A string of text for checking.
     const wchar_t* input;
     // The position and the length of the first invalid word.
-    int expected_misspelling_start;
-    int expected_misspelling_length;
+    size_t expected_misspelling_start;
+    size_t expected_misspelling_length;
     // A comma separated string of suggested words that should occur, in their
     // expected order.
     const wchar_t* expected_suggestions;
@@ -240,8 +240,8 @@
 
   for (size_t i = 0; i < base::size(kTestCases); ++i) {
     blink::WebVector<blink::WebString> suggestions;
-    int misspelling_start;
-    int misspelling_length;
+    size_t misspelling_start;
+    size_t misspelling_length;
     static_cast<blink::WebTextCheckClient*>(provider())
         ->CheckSpelling(
             blink::WebString::FromUTF16(base::WideToUTF16(kTestCases[i].input)),
diff --git a/components/spellcheck/renderer/spellcheck_provider.cc b/components/spellcheck/renderer/spellcheck_provider.cc
index 67b3a96e..ad3325e 100644
--- a/components/spellcheck/renderer/spellcheck_provider.cc
+++ b/components/spellcheck/renderer/spellcheck_provider.cc
@@ -161,8 +161,8 @@
 
 void SpellCheckProvider::CheckSpelling(
     const WebString& text,
-    int& offset,
-    int& length,
+    size_t& offset,
+    size_t& length,
     WebVector<WebString>* optional_suggestions) {
   base::string16 word = text.Utf16();
   std::vector<base::string16> suggestions;
@@ -176,9 +176,11 @@
         suggestions.begin(), suggestions.end(), web_suggestions.begin(),
         [](const base::string16& s) { return WebString::FromUTF16(s); });
     *optional_suggestions = web_suggestions;
-    UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check.suggestions", word.size());
+    UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check.suggestions",
+                            base::saturated_cast<int>(word.size()));
   } else {
-    UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check", word.size());
+    UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check",
+                            base::saturated_cast<int>(word.size()));
     // If optional_suggestions is not requested, the API is called
     // for marking.  So we use this for counting markable words.
     GetSpellCheckHost().NotifyChecked(word, 0 < length);
@@ -189,7 +191,8 @@
     const WebString& text,
     WebTextCheckingCompletion* completion) {
   RequestTextChecking(text.Utf16(), completion);
-  UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.async", text.length());
+  UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.async",
+                          base::saturated_cast<int>(text.length()));
 }
 
 #if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
@@ -226,11 +229,10 @@
 }
 #endif
 
-bool SpellCheckProvider::HasWordCharacters(
-    const base::string16& text,
-    int index) const {
+bool SpellCheckProvider::HasWordCharacters(const base::string16& text,
+                                           size_t index) const {
   const base::char16* data = text.data();
-  int length = text.length();
+  size_t length = text.length();
   while (index < length) {
     uint32_t code = 0;
     U16_NEXT(data, index, length, code);
diff --git a/components/spellcheck/renderer/spellcheck_provider.h b/components/spellcheck/renderer/spellcheck_provider.h
index 2a5f671..392186a 100644
--- a/components/spellcheck/renderer/spellcheck_provider.h
+++ b/components/spellcheck/renderer/spellcheck_provider.h
@@ -90,8 +90,8 @@
   bool IsSpellCheckingEnabled() const override;
   void CheckSpelling(
       const blink::WebString& text,
-      int& offset,
-      int& length,
+      size_t& offset,
+      size_t& length,
       blink::WebVector<blink::WebString>* optional_suggestions) override;
   void RequestCheckingOfText(
       const blink::WebString& text,
@@ -106,7 +106,7 @@
 
   // Returns whether |text| has word characters, i.e. whether a spellchecker
   // needs to check this text.
-  bool HasWordCharacters(const base::string16& text, int index) const;
+  bool HasWordCharacters(const base::string16& text, size_t index) const;
 
 #if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
   void OnRespondTextCheck(
diff --git a/components/spellcheck/renderer/spellcheck_unittest.cc b/components/spellcheck/renderer/spellcheck_unittest.cc
index 12866ada..0d84e85 100644
--- a/components/spellcheck/renderer/spellcheck_unittest.cc
+++ b/components/spellcheck/renderer/spellcheck_unittest.cc
@@ -188,8 +188,8 @@
     //   * false: the input string has one or more invalid words.
     bool expected_result;
     // The position and the length of the first invalid word.
-    int misspelling_start;
-    int misspelling_length;
+    size_t misspelling_start;
+    size_t misspelling_length;
   } kTestCases[] = {
     // Empty strings.
     {L"", true},
@@ -406,12 +406,11 @@
     size_t input_length = 0;
     if (kTestCases[i].input)
       input_length = wcslen(kTestCases[i].input);
-    int misspelling_start;
-    int misspelling_length;
+    size_t misspelling_start;
+    size_t misspelling_length;
     bool result = spell_check()->SpellCheckWord(
-        base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset,
-        static_cast<int>(input_length), kNoTag, &misspelling_start,
-        &misspelling_length, nullptr);
+        base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset, input_length,
+        kNoTag, &misspelling_start, &misspelling_length, nullptr);
 
     EXPECT_EQ(kTestCases[i].expected_result, result);
     EXPECT_EQ(kTestCases[i].misspelling_start, misspelling_start);
@@ -455,12 +454,11 @@
     size_t input_length = 0;
     if (test_case.input)
       input_length = wcslen(test_case.input);
-    int misspelling_start;
-    int misspelling_length;
+    size_t misspelling_start;
+    size_t misspelling_length;
     bool result = spell_check()->SpellCheckWord(
-        base::WideToUTF16(test_case.input).c_str(), kNoOffset,
-        static_cast<int>(input_length), kNoTag, &misspelling_start,
-        &misspelling_length, &suggestions);
+        base::WideToUTF16(test_case.input).c_str(), kNoOffset, input_length,
+        kNoTag, &misspelling_start, &misspelling_length, &suggestions);
 
     // Check for spelling.
     EXPECT_EQ(test_case.expected_result, result);
@@ -830,12 +828,11 @@
     if (kTestCases[i].input)
       input_length = wcslen(kTestCases[i].input);
 
-    int misspelling_start = 0;
-    int misspelling_length = 0;
+    size_t misspelling_start = 0;
+    size_t misspelling_length = 0;
     bool result = spell_check()->SpellCheckWord(
-        base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset,
-        static_cast<int>(input_length), kNoTag, &misspelling_start,
-        &misspelling_length, nullptr);
+        base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset, input_length,
+        kNoTag, &misspelling_start, &misspelling_length, nullptr);
 
     EXPECT_TRUE(result)
         << "\""
@@ -844,8 +841,8 @@
         << "\" is misspelled in "
         << kTestCases[i].language
         << ".";
-    EXPECT_EQ(0, misspelling_start);
-    EXPECT_EQ(0, misspelling_length);
+    EXPECT_EQ(0u, misspelling_start);
+    EXPECT_EQ(0u, misspelling_length);
   }
 }
 
@@ -887,14 +884,14 @@
     ReinitializeSpellCheck(kTestCases[i].language);
 
     base::string16 word(base::WideToUTF16(kTestCases[i].input));
-    int word_length = static_cast<int>(word.length());
-    int misspelling_start = 0;
-    int misspelling_length = 0;
+    size_t word_length = word.length();
+    size_t misspelling_start = 0;
+    size_t misspelling_length = 0;
     bool result = spell_check()->SpellCheckWord(
         word.c_str(), kNoOffset, word_length, kNoTag, &misspelling_start,
         &misspelling_length, nullptr);
     EXPECT_FALSE(result);
-    EXPECT_EQ(0, misspelling_start);
+    EXPECT_EQ(0u, misspelling_start);
     EXPECT_EQ(word_length, misspelling_length);
   }
 }
@@ -1298,12 +1295,12 @@
       if (kTestCases[i].input)
         input_length = strlen(kTestCases[i].input);
 
-      int misspelling_start = 0;
-      int misspelling_length = 0;
+      size_t misspelling_start = 0;
+      size_t misspelling_length = 0;
       bool result = spell_check()->SpellCheckWord(
           base::ASCIIToUTF16(kTestCases[i].input).c_str(), kNoOffset,
-          static_cast<int>(input_length), kNoTag, &misspelling_start,
-          &misspelling_length, nullptr);
+          input_length, kNoTag, &misspelling_start, &misspelling_length,
+          nullptr);
 
       EXPECT_EQ(kTestCases[i].should_pass, result) << kTestCases[i].input <<
           " in " << kLocales[j];
@@ -1342,12 +1339,12 @@
 
     // First check that the NOSUGGEST flag didn't mark this word as not being in
     // the dictionary.
-    int misspelling_start = 0;
-    int misspelling_length = 0;
+    size_t misspelling_start = 0;
+    size_t misspelling_length = 0;
     bool result = spell_check()->SpellCheckWord(
         base::ASCIIToUTF16(test_case.suggestion).c_str(), kNoOffset,
-        static_cast<int>(suggestion_length), kNoTag, &misspelling_start,
-        &misspelling_length, nullptr);
+        suggestion_length, kNoTag, &misspelling_start, &misspelling_length,
+        nullptr);
 
     EXPECT_EQ(test_case.should_pass, result)
         << test_case.suggestion << " in " << test_case.locale;
@@ -1360,7 +1357,7 @@
       input_length = strlen(test_case.input);
     result = spell_check()->SpellCheckWord(
         base::ASCIIToUTF16(test_case.input).c_str(), kNoOffset,
-        static_cast<int>(input_length), kNoTag, &misspelling_start,
+        input_length, kNoTag, &misspelling_start,
         &misspelling_length, &suggestions);
     // Input word should be a misspelling.
     EXPECT_FALSE(result) << test_case.input << " is not a misspelling in "
@@ -1443,8 +1440,8 @@
   };
 
   for (size_t i = 0; i < base::size(kTestCases); ++i) {
-    int misspelling_start = 0;
-    int misspelling_length = 0;
+    size_t misspelling_start = 0;
+    size_t misspelling_length = 0;
     std::vector<base::string16> suggestions;
     EXPECT_FALSE(spell_check()->SpellCheckWord(
         base::ASCIIToUTF16(kTestCases[i].misspelled).c_str(),
diff --git a/components/spellcheck/renderer/spellcheck_worditerator.cc b/components/spellcheck/renderer/spellcheck_worditerator.cc
index 00351e19..8fe8a6d 100644
--- a/components/spellcheck/renderer/spellcheck_worditerator.cc
+++ b/components/spellcheck/renderer/spellcheck_worditerator.cc
@@ -364,8 +364,8 @@
 
 SpellcheckWordIterator::WordIteratorStatus SpellcheckWordIterator::GetNextWord(
     base::string16* word_string,
-    int* word_start,
-    int* word_length) {
+    size_t* word_start,
+    size_t* word_length) {
   DCHECK(!!text_);
 
   word_string->clear();
@@ -414,8 +414,8 @@
   iterator_.reset();
 }
 
-bool SpellcheckWordIterator::Normalize(int input_start,
-                                       int input_length,
+bool SpellcheckWordIterator::Normalize(size_t input_start,
+                                       size_t input_length,
                                        base::string16* output_string) const {
   // We use NFKC (Normalization Form, Compatible decomposition, followed by
   // canonical Composition) defined in Unicode Standard Annex #15 to normalize
@@ -424,7 +424,8 @@
   // spellchecker and we need manual normalization as well. The normalized
   // text does not have to be NUL-terminated since its characters are copied to
   // string16, which adds a NUL character when we need.
-  icu::UnicodeString input(FALSE, &text_[input_start], input_length);
+  icu::UnicodeString input(FALSE, &text_[input_start],
+                           base::checked_cast<int32_t>(input_length));
   UErrorCode status = U_ZERO_ERROR;
   icu::UnicodeString output;
   icu::Normalizer::normalize(input, UNORM_NFKC, 0, output, status);
diff --git a/components/spellcheck/renderer/spellcheck_worditerator.h b/components/spellcheck/renderer/spellcheck_worditerator.h
index ea2f038..cf3d6cf 100644
--- a/components/spellcheck/renderer/spellcheck_worditerator.h
+++ b/components/spellcheck/renderer/spellcheck_worditerator.h
@@ -165,8 +165,10 @@
   //    length into |word_string|, |word_start|, and |word_length| respectively.
   //
   //  - Returns IS_END_OF_TEXT if the iterator has reached the end of |text_|.
-  SpellcheckWordIterator::WordIteratorStatus
-  GetNextWord(base::string16* word_string, int* word_start, int* word_length);
+  SpellcheckWordIterator::WordIteratorStatus GetNextWord(
+      base::string16* word_string,
+      size_t* word_start,
+      size_t* word_length);
 
   // Releases all the resources attached to this object.
   void Reset();
@@ -179,8 +181,8 @@
   // alternative characters supported by our spellchecker. This function also
   // calls SpellcheckWordIterator::OutputChar() to filter out false-positive
   // characters.
-  bool Normalize(int input_start,
-                 int input_length,
+  bool Normalize(size_t input_start,
+                 size_t input_length,
                  base::string16* output_string) const;
 
   // The pointer to the input string from which we are extracting words.
diff --git a/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc b/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc
index e415d5e..4ab4c4f3 100644
--- a/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc
+++ b/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc
@@ -35,8 +35,8 @@
 
 WordIteratorStatus GetNextNonSkippableWord(SpellcheckWordIterator* iterator,
                                            base::string16* word_string,
-                                           int* word_start,
-                                           int* word_length) {
+                                           size_t* word_start,
+                                           size_t* word_length) {
   WordIteratorStatus status = SpellcheckWordIterator::IS_SKIPPABLE;
   while (status == SpellcheckWordIterator::IS_SKIPPABLE)
     status = iterator->GetNextWord(word_string, word_start, word_length);
@@ -174,7 +174,7 @@
         base::string16(1, ' '), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
 
     base::string16 actual_word;
-    int actual_start, actual_len;
+    size_t actual_start, actual_len;
     size_t index = 0;
     for (SpellcheckWordIterator::WordIteratorStatus status =
              iterator.GetNextWord(&actual_word, &actual_start, &actual_len);
@@ -210,13 +210,13 @@
   // iterator.GetNextWord() calls get stuck in an infinite loop. Therefore, this
   // test succeeds if this call returns without timeouts.
   base::string16 actual_word;
-  int actual_start, actual_len;
+  size_t actual_start, actual_len;
   WordIteratorStatus status = GetNextNonSkippableWord(
       &iterator, &actual_word, &actual_start, &actual_len);
 
   EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_END_OF_TEXT, status);
-  EXPECT_EQ(0, actual_start);
-  EXPECT_EQ(0, actual_len);
+  EXPECT_EQ(0u, actual_start);
+  EXPECT_EQ(0u, actual_len);
 }
 
 // Vertify our SpellcheckWordIterator can treat ASCII numbers as word characters
@@ -274,7 +274,7 @@
     EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length()));
 
     base::string16 actual_word;
-    int actual_start, actual_len;
+    size_t actual_start, actual_len;
     WordIteratorStatus status = GetNextNonSkippableWord(
         &iterator, &actual_word, &actual_start, &actual_len);
 
@@ -319,15 +319,14 @@
     EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length()));
 
     base::string16 actual_word;
-    int actual_start, actual_len;
+    size_t actual_start, actual_len;
     WordIteratorStatus status = GetNextNonSkippableWord(
         &iterator, &actual_word, &actual_start, &actual_len);
 
     EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_WORD, status);
     EXPECT_EQ(expected_word, actual_word);
-    EXPECT_LE(0, actual_start);
-    EXPECT_EQ(expected_word.length(),
-              static_cast<base::string16::size_type>(actual_len));
+    EXPECT_LE(0u, actual_start);
+    EXPECT_EQ(expected_word.length(), actual_len);
   }
 }
 
diff --git a/content/shell/test_runner/mock_spell_check.cc b/content/shell/test_runner/mock_spell_check.cc
index db07974..3b7c9e1 100644
--- a/content/shell/test_runner/mock_spell_check.cc
+++ b/content/shell/test_runner/mock_spell_check.cc
@@ -32,8 +32,8 @@
 MockSpellCheck::~MockSpellCheck() {}
 
 bool MockSpellCheck::SpellCheckWord(const blink::WebString& text,
-                                    int* misspelled_offset,
-                                    int* misspelled_length) {
+                                    size_t* misspelled_offset,
+                                    size_t* misspelled_length) {
   DCHECK(misspelled_offset);
   DCHECK(misspelled_length);
 
diff --git a/content/shell/test_runner/mock_spell_check.h b/content/shell/test_runner/mock_spell_check.h
index 160c638..6e361ba 100644
--- a/content/shell/test_runner/mock_spell_check.h
+++ b/content/shell/test_runner/mock_spell_check.h
@@ -38,8 +38,8 @@
   // For example, when the given text is "   zz zz", this function sets 3 to
   // misspelledOffset and 2 to misspelledLength, respectively.
   bool SpellCheckWord(const blink::WebString& text,
-                      int* misspelled_offset,
-                      int* misspelled_length);
+                      size_t* misspelled_offset,
+                      size_t* misspelled_length);
 
   // Checks whether the specified text can be spell checked immediately using
   // the spell checker cache.
diff --git a/content/shell/test_runner/spell_check_client.cc b/content/shell/test_runner/spell_check_client.cc
index 25857c99..effb4e8 100644
--- a/content/shell/test_runner/spell_check_client.cc
+++ b/content/shell/test_runner/spell_check_client.cc
@@ -50,8 +50,8 @@
 
 void SpellCheckClient::CheckSpelling(
     const blink::WebString& text,
-    int& misspelled_offset,
-    int& misspelled_length,
+    size_t& misspelled_offset,
+    size_t& misspelled_length,
     blink::WebVector<blink::WebString>* optional_suggestions) {
   if (!enabled_) {
     misspelled_offset = 0;
@@ -94,13 +94,13 @@
   if (!last_requested_text_checking_completion_)
     return;
   std::vector<blink::WebTextCheckingResult> results;
-  int offset = 0;
+  size_t offset = 0;
   if (!spell_check_.IsMultiWordMisspelling(last_requested_text_check_string_,
                                            &results)) {
     base::string16 text = last_requested_text_check_string_.Utf16();
     while (text.length()) {
-      int misspelled_position = 0;
-      int misspelled_length = 0;
+      size_t misspelled_position = 0;
+      size_t misspelled_length = 0;
       spell_check_.SpellCheckWord(blink::WebString::FromUTF16(text),
                                   &misspelled_position, &misspelled_length);
       if (!misspelled_length)
diff --git a/content/shell/test_runner/spell_check_client.h b/content/shell/test_runner/spell_check_client.h
index 1145cf3f5..53a9295 100644
--- a/content/shell/test_runner/spell_check_client.h
+++ b/content/shell/test_runner/spell_check_client.h
@@ -44,8 +44,8 @@
   bool IsSpellCheckingEnabled() const override;
   void CheckSpelling(
       const blink::WebString& text,
-      int& offset,
-      int& length,
+      size_t& offset,
+      size_t& length,
       blink::WebVector<blink::WebString>* optional_suggestions) override;
   void RequestCheckingOfText(
       const blink::WebString& text,
diff --git a/third_party/blink/public/web/web_text_check_client.h b/third_party/blink/public/web/web_text_check_client.h
index d4a7371..cb8c59f 100644
--- a/third_party/blink/public/web/web_text_check_client.h
+++ b/third_party/blink/public/web/web_text_check_client.h
@@ -24,8 +24,8 @@
   // error, then upon return misspelledLength is 0. If optional_suggestions
   // is given, then it will be filled with suggested words (not a cheap step).
   virtual void CheckSpelling(const WebString& text,
-                             int& misspelled_offset,
-                             int& misspelled_length,
+                             size_t& misspelled_offset,
+                             size_t& misspelled_length,
                              WebVector<WebString>* optional_suggestions) {}
 
   // Requests asynchronous spelling and grammar checking, whose result should be
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
index 24f8140..f093d73be 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
+++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -620,9 +620,9 @@
     int word_end = iterator->next();
     if (word_end < 0)
       break;
-    int word_length = word_end - word_start;
-    int misspelling_location = -1;
-    int misspelling_length = 0;
+    size_t word_length = word_end - word_start;
+    size_t misspelling_location = 0;
+    size_t misspelling_length = 0;
     if (WebTextCheckClient* text_checker_client = GetTextCheckerClient()) {
       // SpellCheckWord will write (0, 0) into the output vars, which is what
       // our caller expects if the word is spelled correctly.
@@ -633,7 +633,7 @@
       misspelling_location = 0;
     }
     if (misspelling_length > 0) {
-      DCHECK_GE(misspelling_location, 0);
+      DCHECK_GE(misspelling_location, 0u);
       DCHECK_LE(misspelling_location + misspelling_length, word_length);
       TextCheckingResult misspelling;
       misspelling.decoration = kTextDecorationTypeSpelling;
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc
index 214bb03e..e444a94 100644
--- a/third_party/blink/renderer/core/page/context_menu_controller.cc
+++ b/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -408,7 +408,7 @@
       description.Split('\n', suggestions);
       data.dictionary_suggestions = suggestions;
     } else if (spell_checker.GetTextCheckerClient()) {
-      int misspelled_offset, misspelled_length;
+      size_t misspelled_offset, misspelled_length;
       spell_checker.GetTextCheckerClient()->CheckSpelling(
           data.misspelled_word, misspelled_offset, misspelled_length,
           &data.dictionary_suggestions);