Update googleurl to Chromium version db5425c75e7fc1080bd06737d059

The version is from Tue Jun 7 13:29:16 2022 +0000

Change-Id: Ic4570bc199652d6fed6a21884b9256b858bb197a
diff --git a/AUTHORS b/AUTHORS
index 5941416..a68e49b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -236,6 +236,7 @@
 Clemens Fruhwirth <clemens@endorphin.org>
 Clement Scheelfeldt Skau <clementskau@gmail.com>
 Clinton Staley <clintstaley@gmail.com>
+Cong Zuo <zckevinzc@gmail.com>
 Connor Pearson <cjp822@gmail.com>
 Conrad Irwin <conrad.irwin@gmail.com>
 Craig Schlenter <craig.schlenter@gmail.com>
@@ -269,6 +270,7 @@
 Darshini KN <kn.darshini@samsung.com>
 Dave Vandyke <kzar@kzar.co.uk>
 David Benjamin <davidben@mit.edu>
+David Brown <develop.david.brown@gmail.com>
 David Davidovic <david@davidovic.io>
 David Erceg <erceg.david@gmail.com>
 David Fox <david@davidjfox.com>
@@ -296,6 +298,7 @@
 Devlin Cronin <rdevlin.cronin@gmail.com>
 Dhi Aurrahman <dio@rockybars.com>
 Di Wu <meetwudi@gmail.com>
+Di Zhang <dizhangg@chromium.org>
 Diana Suvorova <diana.suvorova@gmail.com>
 Diego Fernández Santos <agujaydedal@gmail.com>
 Diego Ferreiro Val <elfogris@gmail.com>
@@ -470,6 +473,7 @@
 Ivan Naydonov <samogot@gmail.com>
 Ivan Sham <ivansham@amazon.com>
 Jack Bates <jack@nottheoilrig.com>
+Jacky Hu <flameddd@gmail.com>
 Jacob Clark <jacob.jh.clark@googlemail.com>
 Jacob Mandelson <jacob@mandelson.org>
 Jaehun Lim <ljaehun.lim@samsung.com>
@@ -571,6 +575,7 @@
 Jonathan Frazer <listedegarde@gmail.com>
 Jonathan Garbee <jonathan@garbee.me>
 Jonathan Hacker <jhacker@arcanefour.com>
+Jonathan Johnson <johnsonjonathan593@gmail.com>
 Jonathan Kingston <kingstonmailbox@gmail.com>
 Jonathan Shimonovich <jonathans@talon-sec.com>
 Jongdeok Kim <jongdeok.kim@navercorp.com>
@@ -733,12 +738,14 @@
 Manish Jethani <m.jethani@eyeo.com>
 Manojkumar Bhosale <manojkumar.bhosale@imgtec.com>
 Manuel Braun <thembrown@gmail.com>
+Manuel Lagana <manuel.lagana.dev@gmail.com>
 Mao Yujie <maojie0924@gmail.com>
 Mao Yujie <yujie.mao@intel.com>
 Marc des Garets <marc.desgarets@googlemail.com>
 Marcin Wiacek <marcin@mwiacek.com>
 Marco Rodrigues <gothicx@gmail.com>
 Marcos Caceres <marcos@marcosc.com>
+Marek Behún <kabel@kernel.org>
 Mariam Ali <alimariam@noogler.google.com>
 Mario Pistrich <m.pistrich@gmail.com>
 Mario Sanchez Prada <mario.prada@samsung.com>
@@ -936,6 +943,7 @@
 Qiankun Miao <qiankun.miao@intel.com>
 Qing Zhang <qing.zhang@intel.com>
 Qingmei Li <qingmei.li@vivo.com>
+Qiyao Yuan <qiyaoyuan@tencent.com>
 Radu Stavila <stavila@adobe.com>
 Radu Velea <radu.velea@intel.com>
 Rafael Antognolli <rafael.antognolli@intel.com>
@@ -975,6 +983,7 @@
 Robert Bear Travis <betravis@adobe.com>
 Robert Bradford <robert.bradford@intel.com>
 Robert Goldberg <goldberg@adobe.com>
+Robert Günzler <r@gnzler.io>
 Robert Hogan <robhogan@gmail.com>
 Robert O'Callahan <rocallahan@gmail.com>
 Robert Nagy <robert.nagy@gmail.com>
@@ -1001,6 +1010,7 @@
 Ryan Norton <rnorton10@gmail.com>
 Ryan Sleevi <ryan-chromium-dev@sleevi.com>
 Ryan Yoakum <ryoakum@skobalt.com>
+Rye Zhang <ryezhang@tencent.com>
 Ryo Ogawa <negibokken@gmail.com>
 Ryuan Choi <ryuan.choi@samsung.com>
 Saikrishna Arcot <saiarcot895@gmail.com>
@@ -1090,8 +1100,10 @@
 Simon Jackson <simon.jackson@sonocent.com>
 Simon La Macchia <smacchia@amazon.com>
 Siva Kumar Gunturi <siva.gunturi@samsung.com>
-Sohan Jyoti Ghosh <sohan.jyoti@huawei.com>
-Sohan Jyoti Ghosh <sohan.jyoti@samsung.com>
+Slava Aseev <nullptrnine@gmail.com>
+Sohan Jyoti Ghosh <sohanjg@chromium.org>
+Sohom Datta <sohom.datta@learner.manipal.edu>
+Sohom Datta <dattasohom1@gmail.com>
 Song Fangzhen <songfangzhen@bytedance.com>
 Song YeWen <ffmpeg@gmail.com>
 Sooho Park <sooho1000@gmail.com>
@@ -1174,6 +1186,7 @@
 Timo Gurr <timo.gurr@gmail.com>
 Timo Reimann <ttr314@googlemail.com>
 Timo Witte <timo.witte@gmail.com>
+Timothy Pearson <tpearson@raptorcs.com>
 Ting Shao <ting.shao@intel.com>
 Tobias Lippert <tobias.lippert@fastmail.com>
 Tobias Soppa <tobias@soppa.me>
@@ -1316,6 +1329,7 @@
 Zhenyu Liang <zhenyu.liang@intel.com>
 Zhenyu Shan <zhenyu.shan@intel.com>
 Zhifei Fang <facetothefate@gmail.com>
+Zhiyuan Ye <zhiyuanye@tencent.com>
 Zhuoyu Qian <zhuoyu.qian@samsung.com>
 Ziran Sun <ziran.sun@samsung.com>
 Zoltan Czirkos <czirkos.zoltan@gmail.com>
diff --git a/base/BUILD b/base/BUILD
index c77528b..f86c18b 100644
--- a/base/BUILD
+++ b/base/BUILD
@@ -32,6 +32,7 @@
         "functional/invoke.h",
         "functional/not_fn.h",
         "memory/raw_ptr.h",
+        "memory/raw_ptr_exclusion.h",
         "no_destructor.h",
         "ranges/algorithm.h",
         "ranges/functional.h",
diff --git a/base/compiler_specific.h b/base/compiler_specific.h
index 3a85453..12e09b5 100644
--- a/base/compiler_specific.h
+++ b/base/compiler_specific.h
@@ -24,6 +24,13 @@
 #define HAS_CPP_ATTRIBUTE(x) 0
 #endif
 
+// A wrapper around `__has_attribute`, similar to HAS_CPP_ATTRIBUTE.
+#if defined(__has_attribute)
+#define HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+#define HAS_ATTRIBUTE(x) 0
+#endif
+
 // A wrapper around `__has_builtin`, similar to HAS_CPP_ATTRIBUTE.
 #if defined(__has_builtin)
 #define HAS_BUILTIN(x) __has_builtin(x)
@@ -58,7 +65,7 @@
 // prevent code folding, see NO_CODE_FOLDING() in base/debug/alias.h.
 // Use like:
 //   void NOT_TAIL_CALLED FooBar();
-#if defined(__clang__) && __has_attribute(not_tail_called)
+#if defined(__clang__) && HAS_ATTRIBUTE(not_tail_called)
 #define NOT_TAIL_CALLED __attribute__((not_tail_called))
 #else
 #define NOT_TAIL_CALLED
@@ -126,11 +133,9 @@
 //   __attribute__((format(wprintf, format_param, dots_param)))
 
 // Sanitizers annotations.
-#if defined(__has_attribute)
-#if __has_attribute(no_sanitize)
+#if HAS_ATTRIBUTE(no_sanitize)
 #define NO_SANITIZE(what) __attribute__((no_sanitize(what)))
 #endif
-#endif
 #if !defined(NO_SANITIZE)
 #define NO_SANITIZE(what)
 #endif
@@ -238,7 +243,7 @@
 #endif
 #endif
 
-#if defined(__clang__) && __has_attribute(uninitialized)
+#if defined(__clang__) && HAS_ATTRIBUTE(uninitialized)
 // Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for
 // the specified variable.
 // Library-wide alternative is
@@ -285,13 +290,9 @@
 // In some cases it's desirable to remove this, e.g. on hot functions, or if
 // we have purposely changed the reference canary.
 #if defined(COMPILER_GCC) || defined(__clang__)
-#if defined(__has_attribute)
-#if __has_attribute(__no_stack_protector__)
+#if HAS_ATTRIBUTE(__no_stack_protector__)
 #define NO_STACK_PROTECTOR __attribute__((__no_stack_protector__))
-#else  // __has_attribute(__no_stack_protector__)
-#define NO_STACK_PROTECTOR __attribute__((__optimize__("-fno-stack-protector")))
-#endif
-#else  // defined(__has_attribute)
+#else
 #define NO_STACK_PROTECTOR __attribute__((__optimize__("-fno-stack-protector")))
 #endif
 #else
@@ -328,7 +329,7 @@
 #endif  // defined(__clang_analyzer__)
 
 // Use nomerge attribute to disable optimization of merging multiple same calls.
-#if defined(__clang__) && __has_attribute(nomerge)
+#if defined(__clang__) && HAS_ATTRIBUTE(nomerge)
 #define NOMERGE [[clang::nomerge]]
 #else
 #define NOMERGE
@@ -355,7 +356,7 @@
 // See also:
 //   https://clang.llvm.org/docs/AttributeReference.html#trivial-abi
 //   https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html
-#if defined(__clang__) && __has_attribute(trivial_abi)
+#if defined(__clang__) && HAS_ATTRIBUTE(trivial_abi)
 #define TRIVIAL_ABI [[clang::trivial_abi]]
 #else
 #define TRIVIAL_ABI
@@ -364,7 +365,7 @@
 // Marks a member function as reinitializing a moved-from variable.
 // See also
 // https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html#reinitialization
-#if defined(__clang__) && __has_attribute(reinitializes)
+#if defined(__clang__) && HAS_ATTRIBUTE(reinitializes)
 #define REINITIALIZES_AFTER_MOVE [[clang::reinitializes]]
 #else
 #define REINITIALIZES_AFTER_MOVE
@@ -373,11 +374,9 @@
 // Requires constant initialization. See constinit in C++20. Allows to rely on a
 // variable being initialized before execution, and not requiring a global
 // constructor.
-#if defined(__has_attribute)
-#if __has_attribute(require_constant_initialization)
+#if HAS_ATTRIBUTE(require_constant_initialization)
 #define CONSTINIT __attribute__((require_constant_initialization))
 #endif
-#endif
 #if !defined(CONSTINIT)
 #define CONSTINIT
 #endif
diff --git a/base/containers/contiguous_iterator.h b/base/containers/contiguous_iterator.h
index f17a8ed..6229efb 100644
--- a/base/containers/contiguous_iterator.h
+++ b/base/containers/contiguous_iterator.h
@@ -18,7 +18,10 @@
 namespace internal {
 
 template <typename T>
-struct PointsToObject : std::is_object<iter_value_t<T>> {};
+struct PointsToObject : std::true_type {};
+// std::iter_value_t is not defined for `T*` where T is not an object type.
+template <typename T>
+struct PointsToObject<T*> : std::is_object<T> {};
 
 // A pointer is a contiguous iterator.
 // Reference: https://wg21.link/iterator.traits#5
@@ -74,15 +77,16 @@
 
 // Check that the iterator points to an actual object, and is one of the
 // iterator types mentioned above.
+template <typename T, bool B = PointsToObject<T>::value>
+struct IsContiguousIteratorImpl : std::false_type {};
 template <typename T>
-struct IsContiguousIteratorImpl
-    : std::conjunction<PointsToObject<T>,
-                       std::disjunction<IsPointer<T>,
-                                        IsStringIter<T>,
-                                        IsArrayIter<T>,
-                                        IsVectorIter<T>,
-                                        IsValueArrayIter<T>,
-                                        IsCheckedContiguousIter<T>>> {};
+struct IsContiguousIteratorImpl<T, true>
+    : std::disjunction<IsPointer<T>,
+                       IsStringIter<T>,
+                       IsArrayIter<T>,
+                       IsVectorIter<T>,
+                       IsValueArrayIter<T>,
+                       IsCheckedContiguousIter<T>> {};
 
 }  // namespace internal
 
diff --git a/base/containers/span.h b/base/containers/span.h
index c0fb0b6..5bb30d1 100644
--- a/base/containers/span.h
+++ b/base/containers/span.h
@@ -7,7 +7,6 @@
 
 #include <stddef.h>
 
-#include <algorithm>
 #include <array>
 #include <iterator>
 #include <limits>
@@ -470,10 +469,19 @@
 }
 
 // Type-deducing helpers for constructing a span.
-template <int&... ExplicitArgumentBarrier, typename It, typename EndOrSize>
-constexpr auto make_span(It it, EndOrSize end_or_size) noexcept {
+template <int&... ExplicitArgumentBarrier, typename It>
+constexpr auto make_span(It it, size_t size) noexcept {
   using T = std::remove_reference_t<iter_reference_t<It>>;
-  return span<T>(it, end_or_size);
+  return span<T>(it, size);
+}
+
+template <int&... ExplicitArgumentBarrier,
+          typename It,
+          typename End,
+          typename = std::enable_if_t<!std::is_convertible_v<End, size_t>>>
+constexpr auto make_span(It it, End end) noexcept {
+  using T = std::remove_reference_t<iter_reference_t<It>>;
+  return span<T>(it, end);
 }
 
 // make_span utility function that deduces both the span's value_type and extent
@@ -488,7 +496,7 @@
   return span<T, Extent::value>(std::forward<Container>(container));
 }
 
-// make_span utility function that allows callers to explicit specify the span's
+// make_span utility functions that allow callers to explicit specify the span's
 // extent, the value_type is deduced automatically. This is useful when passing
 // a dynamically sized container to a method expecting static spans, when the
 // container is known to have the correct size.
@@ -496,13 +504,20 @@
 // Note: This will GURL_CHECK that N indeed matches size(container).
 //
 // Usage: auto static_span = gurl_base::make_span<N>(...);
+template <size_t N, int&... ExplicitArgumentBarrier, typename It>
+constexpr auto make_span(It it, size_t size) noexcept {
+  using T = std::remove_reference_t<iter_reference_t<It>>;
+  return span<T, N>(it, size);
+}
+
 template <size_t N,
           int&... ExplicitArgumentBarrier,
           typename It,
-          typename EndOrSize>
-constexpr auto make_span(It it, EndOrSize end_or_size) noexcept {
+          typename End,
+          typename = std::enable_if_t<!std::is_convertible_v<End, size_t>>>
+constexpr auto make_span(It it, End end) noexcept {
   using T = std::remove_reference_t<iter_reference_t<It>>;
-  return span<T, N>(it, end_or_size);
+  return span<T, N>(it, end);
 }
 
 template <size_t N, int&... ExplicitArgumentBarrier, typename Container>
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h
index ad53dc5..f1ef810 100644
--- a/base/memory/raw_ptr.h
+++ b/base/memory/raw_ptr.h
@@ -36,21 +36,11 @@
 #if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS)
 #include "base/allocator/partition_allocator/partition_tag.h"
 #include "base/allocator/partition_allocator/tagging.h"
+#include "polyfills/base/check_op.h"
 #endif  // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS)
 
 #if BUILDFLAG(IS_WIN)
-#include <windows.h>
-#endif
-
-#if defined(OFFICIAL_BUILD)
-// The annotation changed compiler output and increased binary size so disable
-// for official builds.
-// TODO(crbug.com/1320670): Remove when issue is resolved.
-#define RAW_PTR_EXCLUSION
-#else
-// Marks a field as excluded from the raw_ptr usage enforcement clang plugin.
-// Example: RAW_PTR_EXCLUSION Foo* foo_;
-#define RAW_PTR_EXCLUSION __attribute__((annotate("raw_ptr_exclusion")))
+#include "base/win/win_handle_types.h"
 #endif
 
 namespace cc {
@@ -114,7 +104,7 @@
     return wrapped_ptr;
   }
 
-  // Advance the wrapped pointer by |delta| bytes.
+  // Advance the wrapped pointer by `delta_elems`.
   template <typename T>
   static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elems) {
     return wrapped_ptr + delta_elems;
@@ -161,8 +151,8 @@
     // allocated by PartitionAlloc, from normal buckets pool.
     //
     // TODO(crbug.com/1307514): Allow direct-map buckets.
-    return IsManagedByPartitionAlloc(as_uintptr) &&
-           IsManagedByNormalBuckets(as_uintptr);
+    return partition_alloc::IsManagedByPartitionAlloc(as_uintptr) &&
+           partition_alloc::internal::IsManagedByNormalBuckets(as_uintptr);
   }
 
   // Returns pointer to the tag that protects are pointed by |ptr|.
@@ -255,10 +245,10 @@
     return static_cast<To*>(wrapped_ptr);
   }
 
-  // Advance the wrapped pointer by |delta| bytes.
+  // Advance the wrapped pointer by `delta_elems`.
   template <typename T>
-  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elem) {
-    return wrapped_ptr + delta_elem;
+  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elems) {
+    return wrapped_ptr + delta_elems;
   }
 
   // Returns a copy of a wrapped pointer, without making an assertion
@@ -305,7 +295,8 @@
 
   static ALWAYS_INLINE bool IsSupportedAndNotNull(uintptr_t address) {
     // This covers the nullptr case, as address 0 is never in GigaCage.
-    bool is_in_brp_pool = IsManagedByPartitionAllocBRPPool(address);
+    bool is_in_brp_pool =
+        partition_alloc::IsManagedByPartitionAllocBRPPool(address);
 
     // There are many situations where the compiler can prove that
     // ReleaseWrappedPtr is called on a value that is always nullptr, but the
@@ -366,7 +357,8 @@
     }
 #if !defined(PA_HAS_64_BITS_POINTERS)
     else {
-      AddressPoolManagerBitmap::BanSuperPageFromBRPPool(address);
+      partition_alloc::internal::AddressPoolManagerBitmap::
+          BanSuperPageFromBRPPool(address);
     }
 #endif
 
@@ -430,15 +422,15 @@
     return wrapped_ptr;
   }
 
-  // Advance the wrapped pointer by |delta| bytes.
+  // Advance the wrapped pointer by `delta_elems`.
   template <typename T>
-  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elem) {
+  static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elems) {
 #if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
     uintptr_t address = reinterpret_cast<uintptr_t>(wrapped_ptr);
     if (IsSupportedAndNotNull(address))
-      GURL_CHECK(IsValidDelta(address, delta_elem * sizeof(T)));
+      GURL_CHECK(IsValidDelta(address, delta_elems * sizeof(T)));
 #endif
-    T* new_wrapped_ptr = WrapRawPtr(wrapped_ptr + delta_elem);
+    T* new_wrapped_ptr = WrapRawPtr(wrapped_ptr + delta_elems);
     ReleaseWrappedPtr(wrapped_ptr);
     return new_wrapped_ptr;
   }
@@ -517,7 +509,7 @@
     return wrapped_ptr;
   }
 
-  // Advance the wrapped pointer by |delta| bytes.
+  // Advance the wrapped pointer by `delta_elems`.
   template <typename T>
   static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elems) {
     return wrapped_ptr + delta_elems;
diff --git a/base/memory/raw_ptr_exclusion.h b/base/memory/raw_ptr_exclusion.h
new file mode 100644
index 0000000..37e9eac
--- /dev/null
+++ b/base/memory/raw_ptr_exclusion.h
@@ -0,0 +1,21 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_MEMORY_RAW_PTR_EXCLUSION_H_
+#define BASE_MEMORY_RAW_PTR_EXCLUSION_H_
+
+#include "build/build_config.h"
+
+#if defined(OFFICIAL_BUILD)
+// The annotation changed compiler output and increased binary size so disable
+// for official builds.
+// TODO(crbug.com/1320670): Remove when issue is resolved.
+#define RAW_PTR_EXCLUSION
+#else
+// Marks a field as excluded from the raw_ptr usage enforcement clang plugin.
+// Example: RAW_PTR_EXCLUSION Foo* foo_;
+#define RAW_PTR_EXCLUSION __attribute__((annotate("raw_ptr_exclusion")))
+#endif
+
+#endif  // BASE_MEMORY_RAW_PTR_EXCLUSION_H_
diff --git a/base/strings/escape.cc b/base/strings/escape.cc
index 8324aae..011b79c 100644
--- a/base/strings/escape.cc
+++ b/base/strings/escape.cc
@@ -7,6 +7,8 @@
 #include <ostream>
 
 #include "polyfills/base/check_op.h"
+#include "base/feature_list.h"
+#include "base/features.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversion_utils.h"
@@ -210,7 +212,7 @@
 // |escaped_text| that corresponds to the unescaped character.
 bool UnescapeUTF8CharacterAtIndex(StringPiece escaped_text,
                                   size_t index,
-                                  uint32_t* code_point_out,
+                                  base_icu::UChar32* code_point_out,
                                   std::string* unescaped_out) {
   GURL_DCHECK(unescaped_out->empty());
 
@@ -404,7 +406,7 @@
   // Locations of adjusted text.
   for (size_t i = 0, max = escaped_text.size(); i < max;) {
     // Try to unescape the character.
-    uint32_t code_point;
+    base_icu::UChar32 code_point;
     std::string unescaped;
     if (!UnescapeUTF8CharacterAtIndex(escaped_text, i, &code_point,
                                       &unescaped)) {
@@ -540,6 +542,16 @@
   GURL_DCHECK(!(rules &
            ~(UnescapeRule::NORMAL | UnescapeRule::REPLACE_PLUS_WITH_SPACE)));
 
+  // If there are no '%' characters in the string, there will be nothing to
+  // unescape, so we can take the fast path.
+  if (gurl_base::FeatureList::IsEnabled(features::kOptimizeDataUrls) &&
+      escaped_text.find('%') == StringPiece::npos) {
+    std::string unescaped_text(escaped_text);
+    if (rules & UnescapeRule::REPLACE_PLUS_WITH_SPACE)
+      std::replace(unescaped_text.begin(), unescaped_text.end(), '+', ' ');
+    return unescaped_text;
+  }
+
   std::string unescaped_text;
 
   // The output of the unescaping is always smaller than the input, so we can
diff --git a/base/strings/safe_sprintf.h b/base/strings/safe_sprintf.h
index 478275e..8e6c922 100644
--- a/base/strings/safe_sprintf.h
+++ b/base/strings/safe_sprintf.h
@@ -175,7 +175,7 @@
     integer.width = sizeof(long long);
   }
   Arg(unsigned long long j) : type(UINT) {
-    integer.i = j;
+    integer.i = static_cast<int64_t>(j);
     integer.width = sizeof(long long);
   }
 
diff --git a/base/strings/string_number_conversions.cc b/base/strings/string_number_conversions.cc
index b0eeafd..929b650 100644
--- a/base/strings/string_number_conversions.cc
+++ b/base/strings/string_number_conversions.cc
@@ -155,19 +155,21 @@
 
 bool HexStringToBytes(StringPiece input, std::vector<uint8_t>* output) {
   GURL_DCHECK(output->empty());
-  return internal::HexStringToByteContainer(input, std::back_inserter(*output));
+  return internal::HexStringToByteContainer<uint8_t>(
+      input, std::back_inserter(*output));
 }
 
 bool HexStringToString(StringPiece input, std::string* output) {
   GURL_DCHECK(output->empty());
-  return internal::HexStringToByteContainer(input, std::back_inserter(*output));
+  return internal::HexStringToByteContainer<char>(input,
+                                                  std::back_inserter(*output));
 }
 
 bool HexStringToSpan(StringPiece input, gurl_base::span<uint8_t> output) {
   if (input.size() / 2 != output.size())
     return false;
 
-  return internal::HexStringToByteContainer(input, output.begin());
+  return internal::HexStringToByteContainer<uint8_t>(input, output.begin());
 }
 
 }  // namespace base
diff --git a/base/strings/string_number_conversions_internal.h b/base/strings/string_number_conversions_internal.h
index 6de9e2e..2abd324 100644
--- a/base/strings/string_number_conversions_internal.h
+++ b/base/strings/string_number_conversions_internal.h
@@ -252,7 +252,7 @@
   char buffer[32];
   double_conversion::StringBuilder builder(buffer, sizeof(buffer));
   GetDoubleToStringConverter()->ToShortest(value, &builder);
-  return ToString<StringT>(buffer, builder.position());
+  return ToString<StringT>(buffer, static_cast<size_t>(builder.position()));
 }
 
 template <typename STRING, typename CHAR>
@@ -263,8 +263,8 @@
       0.0, 0, nullptr, nullptr);
 
   int processed_characters_count;
-  output =
-      converter.StringToDouble(data, input.size(), &processed_characters_count);
+  output = converter.StringToDouble(data, checked_cast<int>(input.size()),
+                                    &processed_characters_count);
 
   // Cases to return false:
   //  - If the input string is empty, there was nothing to parse.
@@ -278,7 +278,7 @@
          !IsUnicodeWhitespace(input[0]);
 }
 
-template <typename OutIter>
+template <typename Char, typename OutIter>
 static bool HexStringToByteContainer(StringPiece input, OutIter output) {
   size_t count = input.size();
   if (count == 0 || (count % 2) != 0)
@@ -291,7 +291,7 @@
     if (!msb || !lsb) {
       return false;
     }
-    *(output++) = (*msb << 4) | *lsb;
+    *(output++) = static_cast<Char>((*msb << 4) | *lsb);
   }
   return true;
 }
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index 21ee624..68d6205 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -607,10 +607,10 @@
   // This is a custom hash function. We don't use the ones already defined for
   // string and std::u16string directly because it would require the string
   // constructors to be called, which we don't want.
-  std::size_t operator()(StringPieceType sp) const {
-    std::size_t result = 0;
+  size_t operator()(StringPieceType sp) const {
+    size_t result = 0;
     for (auto c : sp)
-      result = (result * 131) + c;
+      result = (result * 131) + static_cast<size_t>(c);
     return result;
   }
 };
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index 937c603..8729bf4 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -90,16 +90,6 @@
   return internal::CompareCaseInsensitiveASCIIT(a, b);
 }
 
-bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) {
-  return a.size() == b.size() &&
-         internal::CompareCaseInsensitiveASCIIT(a, b) == 0;
-}
-
-bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) {
-  return a.size() == b.size() &&
-         internal::CompareCaseInsensitiveASCIIT(a, b) == 0;
-}
-
 const std::string& EmptyString() {
   static const gurl_base::NoDestructor<std::string> s;
   return *s;
@@ -185,8 +175,7 @@
     int32_t prev = char_index;
     base_icu::UChar32 code_point = 0;
     CBU8_NEXT(data, char_index, truncation_length, code_point);
-    if (!IsValidCharacter(code_point) ||
-        !IsValidCodepoint(code_point)) {
+    if (!IsValidCharacter(code_point)) {
       char_index = prev - 1;
     } else {
       break;
@@ -301,24 +290,12 @@
   return internal::EndsWithT(str, search_for, case_sensitivity);
 }
 
-char HexDigitToInt(wchar_t c) {
+char HexDigitToInt(char c) {
   GURL_DCHECK(IsHexDigit(c));
   if (c >= '0' && c <= '9')
     return static_cast<char>(c - '0');
-  if (c >= 'A' && c <= 'F')
-    return static_cast<char>(c - 'A' + 10);
-  if (c >= 'a' && c <= 'f')
-    return static_cast<char>(c - 'a' + 10);
-  return 0;
-}
-
-bool IsUnicodeWhitespace(wchar_t c) {
-  // kWhitespaceWide is a NULL-terminated string
-  for (const wchar_t* cur = kWhitespaceWide; *cur; ++cur) {
-    if (*cur == c)
-      return true;
-  }
-  return false;
+  return (c >= 'A' && c <= 'F') ? static_cast<char>(c - 'A' + 10)
+                                : static_cast<char>(c - 'a' + 10);
 }
 
 static const char* const kByteStringsUnlocalized[] = {
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index cd90a94..435b5c6 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -12,6 +12,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <algorithm>
 #include <initializer_list>
 #include <string>
 #include <type_traits>
@@ -122,7 +123,7 @@
 template <typename CharT,
           typename = std::enable_if_t<std::is_integral<CharT>::value>>
 CharT ToUpperASCII(CharT c) {
-  return (c >= 'a' && c <= 'z') ? (c + ('A' - 'a')) : c;
+  return (c >= 'a' && c <= 'z') ? static_cast<CharT>(c + 'A' - 'a') : c;
 }
 
 // Converts the given string to it's ASCII-lowercase equivalent.
@@ -153,16 +154,37 @@
 //    0  (a == b)
 //    1  (a > b)
 // (unlike strcasecmp which can return values greater or less than 1/-1). For
-// full Unicode support, use gurl_base::i18n::ToLower or gurl_base::i18h::FoldCase
+// full Unicode support, use gurl_base::i18n::ToLower or gurl_base::i18n::FoldCase
 // and then just call the normal string operators on the result.
 BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b);
 BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b);
 
+namespace internal {
+template <typename CharT, typename CharU>
+inline bool EqualsCaseInsensitiveASCIIT(BasicStringPiece<CharT> a,
+                                        BasicStringPiece<CharU> b) {
+  return std::equal(a.begin(), a.end(), b.begin(), b.end(),
+                    [](auto lhs, auto rhs) {
+                      return ToLowerASCII(lhs) == ToLowerASCII(rhs);
+                    });
+}
+}  // namespace internal
+
 // Equality for ASCII case-insensitive comparisons. For full Unicode support,
-// use gurl_base::i18n::ToLower or gurl_base::i18h::FoldCase and then compare with either
+// use gurl_base::i18n::ToLower or gurl_base::i18n::FoldCase and then compare with either
 // == or !=.
-BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b);
-BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b);
+inline bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) {
+  return internal::EqualsCaseInsensitiveASCIIT(a, b);
+}
+inline bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) {
+  return internal::EqualsCaseInsensitiveASCIIT(a, b);
+}
+inline bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece b) {
+  return internal::EqualsCaseInsensitiveASCIIT(a, b);
+}
+inline bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece16 b) {
+  return internal::EqualsCaseInsensitiveASCIIT(a, b);
+}
 
 // These threadsafe functions return references to globally unique empty
 // strings.
@@ -395,11 +417,24 @@
 //    '4' -> 4
 //    'a' -> 10
 //    'B' -> 11
-// Assumes the input is a valid hex character. DCHECKs in debug builds if not.
-BASE_EXPORT char HexDigitToInt(wchar_t c);
+// Assumes the input is a valid hex character.
+BASE_EXPORT char HexDigitToInt(char c);
+inline char HexDigitToInt(char16_t c) {
+  GURL_DCHECK(IsHexDigit(c));
+  return HexDigitToInt(static_cast<char>(c));
+}
 
 // Returns true if it's a Unicode whitespace character.
-BASE_EXPORT bool IsUnicodeWhitespace(wchar_t c);
+template <typename Char>
+inline bool IsUnicodeWhitespace(Char c) {
+  // kWhitespaceWide is a NUL-terminated string
+  for (const auto* cur = kWhitespaceWide; *cur; ++cur) {
+    if (static_cast<typename std::make_unsigned_t<wchar_t>>(*cur) ==
+        static_cast<typename std::make_unsigned_t<Char>>(c))
+      return true;
+  }
+  return false;
+};
 
 // Return a byte string in human-readable format with a unit suffix. Not
 // appropriate for use in any UI; use of FormatBytes and friends in ui/base is
diff --git a/base/strings/string_util_internal.h b/base/strings/string_util_internal.h
index 2497c8d..173cfaa 100644
--- a/base/strings/string_util_internal.h
+++ b/base/strings/string_util_internal.h
@@ -26,7 +26,7 @@
       : parameter(parameter), offset(offset) {}
 
   // Index of the parameter.
-  uintptr_t parameter;
+  size_t parameter;
 
   // Starting position in the string.
   size_t offset;
@@ -147,7 +147,7 @@
   bool in_whitespace = true;
   bool already_trimmed = true;
 
-  int chars_written = 0;
+  size_t chars_written = 0;
   for (auto c : text) {
     if (IsUnicodeWhitespace(c)) {
       if (!in_whitespace) {
@@ -196,7 +196,7 @@
 
   // Prologue: align the input.
   while (!IsMachineWordAligned(characters) && characters < end)
-    all_char_bits |= *characters++;
+    all_char_bits |= static_cast<MachineWord>(*characters++);
   if (all_char_bits & non_ascii_bit_mask)
     return false;
 
@@ -222,19 +222,19 @@
 
   // Process the remaining bytes.
   while (characters < end)
-    all_char_bits |= *characters++;
+    all_char_bits |= static_cast<MachineWord>(*characters++);
 
   return !(all_char_bits & non_ascii_bit_mask);
 }
 
-template <bool (*Validator)(uint32_t)>
+template <bool (*Validator)(base_icu::UChar32)>
 inline bool DoIsStringUTF8(StringPiece str) {
-  const char* src = str.data();
-  int32_t src_len = static_cast<int32_t>(str.length());
-  int32_t char_index = 0;
+  const uint8_t* src = reinterpret_cast<const uint8_t*>(str.data());
+  size_t src_len = str.length();
+  size_t char_index = 0;
 
   while (char_index < src_len) {
-    int32_t code_point;
+    base_icu::UChar32 code_point;
     CBU8_NEXT(src, char_index, src_len, code_point);
     if (!Validator(code_point))
       return false;
@@ -583,10 +583,9 @@
             GURL_DLOG(ERROR) << "Invalid placeholder: $" << *i;
             continue;
           }
-          uintptr_t index = *i - '1';
+          size_t index = static_cast<size_t>(*i - '1');
           if (offsets) {
-            ReplacementOffset r_offset(index,
-                                       static_cast<int>(formatted.size()));
+            ReplacementOffset r_offset(index, formatted.size());
             r_offsets.insert(
                 ranges::upper_bound(r_offsets, r_offset, &CompareParameter),
                 r_offset);
diff --git a/base/strings/string_util_unittest.cc b/base/strings/string_util_unittest.cc
index b5d9a67..f41f6d8 100644
--- a/base/strings/string_util_unittest.cc
+++ b/base/strings/string_util_unittest.cc
@@ -1472,6 +1472,39 @@
   EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", "aSDF"));
   EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", "aSDF"));
   EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", "aSDFz"));
+
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"", u""));
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"Asdf", u"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"bsdf", u"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"Asdf", u"aSDFz"));
+
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"", ""));
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"Asdf", "aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"bsdf", "aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"Asdf", "aSDFz"));
+
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("", u""));
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", u"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", u"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", u"aSDFz"));
+
+  // The `WStringPiece` overloads are only defined on Windows.
+#if BUILDFLAG(IS_WIN)
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"", L""));
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"Asdf", L"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"bsdf", L"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"Asdf", L"aSDFz"));
+
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"", ""));
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"Asdf", "aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"bsdf", "aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"Asdf", "aSDFz"));
+
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("", L""));
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", L"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", L"aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", L"aSDFz"));
+#endif
 }
 
 TEST(StringUtilTest, IsUnicodeWhitespace) {
diff --git a/base/strings/string_util_win.cc b/base/strings/string_util_win.cc
index 9d475ba..7a9b891 100644
--- a/base/strings/string_util_win.cc
+++ b/base/strings/string_util_win.cc
@@ -24,11 +24,6 @@
   return internal::CompareCaseInsensitiveASCIIT(a, b);
 }
 
-bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b) {
-  return a.size() == b.size() &&
-         internal::CompareCaseInsensitiveASCIIT(a, b) == 0;
-}
-
 bool RemoveChars(WStringPiece input,
                  WStringPiece remove_chars,
                  std::wstring* output) {
diff --git a/base/strings/string_util_win.h b/base/strings/string_util_win.h
index 7c04176..fbf815b 100644
--- a/base/strings/string_util_win.h
+++ b/base/strings/string_util_win.h
@@ -117,7 +117,15 @@
 
 BASE_EXPORT int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b);
 
-BASE_EXPORT bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b);
+inline bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b) {
+  return internal::EqualsCaseInsensitiveASCIIT(a, b);
+}
+inline bool EqualsCaseInsensitiveASCII(WStringPiece a, StringPiece b) {
+  return internal::EqualsCaseInsensitiveASCIIT(a, b);
+}
+inline bool EqualsCaseInsensitiveASCII(StringPiece a, WStringPiece b) {
+  return internal::EqualsCaseInsensitiveASCIIT(a, b);
+}
 
 BASE_EXPORT bool RemoveChars(WStringPiece input,
                              WStringPiece remove_chars,
diff --git a/base/strings/utf_offset_string_conversions.cc b/base/strings/utf_offset_string_conversions.cc
index 6120b71..e6bb6d6 100644
--- a/base/strings/utf_offset_string_conversions.cc
+++ b/base/strings/utf_offset_string_conversions.cc
@@ -192,7 +192,7 @@
   bool success = true;
   int32_t src_len32 = static_cast<int32_t>(src_len);
   for (int32_t i = 0; i < src_len32; i++) {
-    uint32_t code_point;
+    base_icu::UChar32 code_point;
     size_t original_i = i;
     size_t chars_written = 0;
     if (ReadUnicodeCharacter(src, src_len32, &i, &code_point)) {
diff --git a/base/strings/utf_string_conversion_utils.cc b/base/strings/utf_string_conversion_utils.cc
index 9a4b4ca..76dd725 100644
--- a/base/strings/utf_string_conversion_utils.cc
+++ b/base/strings/utf_string_conversion_utils.cc
@@ -14,13 +14,10 @@
 bool ReadUnicodeCharacter(const char* src,
                           int32_t src_len,
                           int32_t* char_index,
-                          uint32_t* code_point_out) {
-  // U8_NEXT expects to be able to use -1 to signal an error, so we must
-  // use a signed type for code_point.  But this function returns false
-  // on error anyway, so code_point_out is unsigned.
-  int32_t code_point;
+                          base_icu::UChar32* code_point_out) {
+  base_icu::UChar32 code_point;
   CBU8_NEXT(src, *char_index, src_len, code_point);
-  *code_point_out = static_cast<uint32_t>(code_point);
+  *code_point_out = code_point;
 
   // The ICU macro above moves to the next char, we want to point to the last
   // char consumed.
@@ -33,7 +30,7 @@
 bool ReadUnicodeCharacter(const char16_t* src,
                           int32_t src_len,
                           int32_t* char_index,
-                          uint32_t* code_point) {
+                          base_icu::UChar32* code_point) {
   if (CBU16_IS_SURROGATE(src[*char_index])) {
     if (!CBU16_IS_SURROGATE_LEAD(src[*char_index]) ||
         *char_index + 1 >= src_len ||
@@ -58,7 +55,7 @@
 bool ReadUnicodeCharacter(const wchar_t* src,
                           int32_t src_len,
                           int32_t* char_index,
-                          uint32_t* code_point) {
+                          base_icu::UChar32* code_point) {
   // Conversion is easy since the source is 32-bit.
   *code_point = src[*char_index];
 
diff --git a/base/strings/utf_string_conversion_utils.h b/base/strings/utf_string_conversion_utils.h
index 640c7c6..877d264 100644
--- a/base/strings/utf_string_conversion_utils.h
+++ b/base/strings/utf_string_conversion_utils.h
@@ -14,26 +14,29 @@
 #include <string>
 
 #include "polyfills/base/base_export.h"
+#include "base/third_party/icu/icu_utf.h"
+#include "build/build_config.h"
 
 namespace gurl_base {
 
-inline bool IsValidCodepoint(uint32_t code_point) {
+inline bool IsValidCodepoint(base_icu::UChar32 code_point) {
   // Excludes code points that are not Unicode scalar values, i.e.
   // surrogate code points ([0xD800, 0xDFFF]). Additionally, excludes
   // code points larger than 0x10FFFF (the highest codepoint allowed).
   // Non-characters and unassigned code points are allowed.
   // https://unicode.org/glossary/#unicode_scalar_value
-  return code_point < 0xD800u ||
-         (code_point >= 0xE000u && code_point <= 0x10FFFFu);
+  return (code_point >= 0 && code_point < 0xD800) ||
+         (code_point >= 0xE000 && code_point <= 0x10FFFF);
 }
 
-inline bool IsValidCharacter(uint32_t code_point) {
+inline bool IsValidCharacter(base_icu::UChar32 code_point) {
   // Excludes non-characters (U+FDD0..U+FDEF, and all code points
   // ending in 0xFFFE or 0xFFFF) from the set of valid code points.
   // https://unicode.org/faq/private_use.html#nonchar1
-  return code_point < 0xD800u || (code_point >= 0xE000u &&
-      code_point < 0xFDD0u) || (code_point > 0xFDEFu &&
-      code_point <= 0x10FFFFu && (code_point & 0xFFFEu) != 0xFFFEu);
+  return (code_point >= 0 && code_point < 0xD800) ||
+         (code_point >= 0xE000 && code_point < 0xFDD0) ||
+         (code_point > 0xFDEF && code_point <= 0x10FFFF &&
+          (code_point & 0xFFFE) != 0xFFFE);
 }
 
 // ReadUnicodeCharacter --------------------------------------------------------
@@ -48,20 +51,20 @@
 BASE_EXPORT bool ReadUnicodeCharacter(const char* src,
                                       int32_t src_len,
                                       int32_t* char_index,
-                                      uint32_t* code_point_out);
+                                      base_icu::UChar32* code_point_out);
 
 // Reads a UTF-16 character. The usage is the same as the 8-bit version above.
 BASE_EXPORT bool ReadUnicodeCharacter(const char16_t* src,
                                       int32_t src_len,
                                       int32_t* char_index,
-                                      uint32_t* code_point);
+                                      base_icu::UChar32* code_point);
 
 #if defined(WCHAR_T_IS_UTF32)
 // Reads UTF-32 character. The usage is the same as the 8-bit version above.
 BASE_EXPORT bool ReadUnicodeCharacter(const wchar_t* src,
                                       int32_t src_len,
                                       int32_t* char_index,
-                                      uint32_t* code_point);
+                                      base_icu::UChar32* code_point);
 #endif  // defined(WCHAR_T_IS_UTF32)
 
 // WriteUnicodeCharacter -------------------------------------------------------
diff --git a/base/strings/utf_string_conversions.cc b/base/strings/utf_string_conversions.cc
index 8cf90f1..2124231 100644
--- a/base/strings/utf_string_conversions.cc
+++ b/base/strings/utf_string_conversions.cc
@@ -20,7 +20,7 @@
 
 namespace {
 
-constexpr int32_t kErrorCodePoint = 0xFFFD;
+constexpr base_icu::UChar32 kErrorCodePoint = 0xFFFD;
 
 // Size coefficient ----------------------------------------------------------
 // The maximum number of codeunits in the destination encoding corresponding to
@@ -71,17 +71,23 @@
                                          bool>;
 
 template <typename Char, EnableIfBitsAre<Char, 8> = true>
-void UnicodeAppendUnsafe(Char* out, int32_t* size, uint32_t code_point) {
-  CBU8_APPEND_UNSAFE(out, *size, code_point);
+void UnicodeAppendUnsafe(Char* out,
+                         size_t* size,
+                         base_icu::UChar32 code_point) {
+  CBU8_APPEND_UNSAFE(reinterpret_cast<uint8_t*>(out), *size, code_point);
 }
 
 template <typename Char, EnableIfBitsAre<Char, 16> = true>
-void UnicodeAppendUnsafe(Char* out, int32_t* size, uint32_t code_point) {
+void UnicodeAppendUnsafe(Char* out,
+                         size_t* size,
+                         base_icu::UChar32 code_point) {
   CBU16_APPEND_UNSAFE(out, *size, code_point);
 }
 
 template <typename Char, EnableIfBitsAre<Char, 32> = true>
-void UnicodeAppendUnsafe(Char* out, int32_t* size, uint32_t code_point) {
+void UnicodeAppendUnsafe(Char* out,
+                         size_t* size,
+                         base_icu::UChar32 code_point) {
   out[(*size)++] = code_point;
 }
 
@@ -91,14 +97,14 @@
 
 template <typename DestChar>
 bool DoUTFConversion(const char* src,
-                     int32_t src_len,
+                     size_t src_len,
                      DestChar* dest,
-                     int32_t* dest_len) {
+                     size_t* dest_len) {
   bool success = true;
 
-  for (int32_t i = 0; i < src_len;) {
-    int32_t code_point;
-    CBU8_NEXT(src, i, src_len, code_point);
+  for (size_t i = 0; i < src_len;) {
+    base_icu::UChar32 code_point;
+    CBU8_NEXT(reinterpret_cast<const uint8_t*>(src), i, src_len, code_point);
 
     if (!IsValidCodepoint(code_point)) {
       success = false;
@@ -113,12 +119,12 @@
 
 template <typename DestChar>
 bool DoUTFConversion(const char16_t* src,
-                     int32_t src_len,
+                     size_t src_len,
                      DestChar* dest,
-                     int32_t* dest_len) {
+                     size_t* dest_len) {
   bool success = true;
 
-  auto ConvertSingleChar = [&success](char16_t in) -> int32_t {
+  auto ConvertSingleChar = [&success](char16_t in) -> base_icu::UChar32 {
     if (!CBU16_IS_SINGLE(in) || !IsValidCodepoint(in)) {
       success = false;
       return kErrorCodePoint;
@@ -126,12 +132,12 @@
     return in;
   };
 
-  int32_t i = 0;
+  size_t i = 0;
 
   // Always have another symbol in order to avoid checking boundaries in the
   // middle of the surrogate pair.
-  while (i < src_len - 1) {
-    int32_t code_point;
+  while (i + 1 < src_len) {
+    base_icu::UChar32 code_point;
 
     if (CBU16_IS_LEAD(src[i]) && CBU16_IS_TRAIL(src[i + 1])) {
       code_point = CBU16_GET_SUPPLEMENTARY(src[i], src[i + 1]);
@@ -148,8 +154,9 @@
     UnicodeAppendUnsafe(dest, dest_len, code_point);
   }
 
-  if (i < src_len)
+  if (i < src_len) {
     UnicodeAppendUnsafe(dest, dest_len, ConvertSingleChar(src[i]));
+  }
 
   return success;
 }
@@ -158,13 +165,13 @@
 
 template <typename DestChar>
 bool DoUTFConversion(const wchar_t* src,
-                     int32_t src_len,
+                     size_t src_len,
                      DestChar* dest,
-                     int32_t* dest_len) {
+                     size_t* dest_len) {
   bool success = true;
 
-  for (int32_t i = 0; i < src_len; ++i) {
-    int32_t code_point = src[i];
+  for (size_t i = 0; i < src_len; ++i) {
+    base_icu::UChar32 code_point = src[i];
 
     if (!IsValidCodepoint(code_point)) {
       success = false;
@@ -197,12 +204,12 @@
   auto* dest = &(*dest_str)[0];
 
   // ICU requires 32 bit numbers.
-  int32_t src_len32 = static_cast<int32_t>(src_str.length());
-  int32_t dest_len32 = 0;
+  size_t src_len = src_str.length();
+  size_t dest_len = 0;
 
-  bool res = DoUTFConversion(src_str.data(), src_len32, dest, &dest_len32);
+  bool res = DoUTFConversion(src_str.data(), src_len, dest, &dest_len);
 
-  dest_str->resize(dest_len32);
+  dest_str->resize(dest_len);
   dest_str->shrink_to_fit();
 
   return res;
diff --git a/base/template_util.h b/base/template_util.h
index c00791b..17db620 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -6,6 +6,7 @@
 #define BASE_TEMPLATE_UTIL_H_
 
 #include <stddef.h>
+
 #include <iosfwd>
 #include <iterator>
 #include <type_traits>
@@ -15,10 +16,6 @@
 
 namespace gurl_base {
 
-template <class T> struct is_non_const_reference : std::false_type {};
-template <class T> struct is_non_const_reference<T&> : std::true_type {};
-template <class T> struct is_non_const_reference<const T&> : std::false_type {};
-
 namespace internal {
 
 // Uses expression SFINAE to detect whether using operator<< would work.
@@ -59,35 +56,6 @@
 
 }  // namespace internal
 
-// gurl_base::in_place_t is an implementation of std::in_place_t from
-// C++17. A tag type used to request in-place construction in template vararg
-// constructors.
-
-// Specification:
-// https://en.cppreference.com/w/cpp/utility/in_place
-struct in_place_t {};
-constexpr in_place_t in_place = {};
-
-// gurl_base::in_place_type_t is an implementation of std::in_place_type_t from
-// C++17. A tag type used for in-place construction when the type to construct
-// needs to be specified, such as with gurl_base::unique_any, designed to be a
-// drop-in replacement.
-
-// Specification:
-// http://en.cppreference.com/w/cpp/utility/in_place
-template <typename T>
-struct in_place_type_t {};
-
-template <typename T>
-struct is_in_place_type_t {
-  static constexpr bool value = false;
-};
-
-template <typename... Ts>
-struct is_in_place_type_t<in_place_type_t<Ts...>> {
-  static constexpr bool value = true;
-};
-
 namespace internal {
 
 // The indirection with std::is_enum<T> is required, because instantiating
@@ -145,8 +113,28 @@
 //
 // Reference: https://wg21.link/readable.traits#2
 template <typename Iter>
-using iter_value_t =
-    typename std::iterator_traits<remove_cvref_t<Iter>>::value_type;
+struct IterValueImpl {
+  using value_type = typename std::iterator_traits<Iter>::value_type;
+};
+
+template <typename T, bool Cond = false>
+struct IterValuePointerImpl {
+  // The `iterator_traits<T*>::value_type` member is not defined if T is not an
+  // object in C++20.
+};
+template <typename T>
+struct IterValuePointerImpl<T*, true> {
+  using value_type = typename std::iterator_traits<T*>::value_type;
+};
+
+template <typename T>
+struct IterValueImpl<T*> {
+  using value_type =
+      typename IterValuePointerImpl<T*, std::is_object_v<T>>::value_type;
+};
+
+template <typename Iter>
+using iter_value_t = typename IterValueImpl<remove_cvref_t<Iter>>::value_type;
 
 // Simplified implementation of C++20's std::iter_reference_t.
 // As opposed to std::iter_reference_t, this implementation does not restrict
diff --git a/build/build_config.h b/build/build_config.h
index 0102a93..a993e1e 100644
--- a/build/build_config.h
+++ b/build/build_config.h
@@ -16,10 +16,10 @@
 //
 //  Operating System:
 //    IS_AIX / IS_ANDROID / IS_ASMJS / IS_CHROMEOS / IS_FREEBSD / IS_FUCHSIA /
-//    IS_IOS / IS_LINUX / IS_MAC / IS_NACL / IS_NETBSD / IS_OPENBSD / IS_QNX /
-//    IS_SOLARIS / IS_WIN
+//    IS_IOS / IS_IOS_MACCATALYST / IS_LINUX / IS_MAC / IS_NACL / IS_NETBSD /
+//    IS_OPENBSD / IS_QNX / IS_SOLARIS / IS_WIN
 //  Operating System family:
-//    IS_APPLE: IOS or MAC
+//    IS_APPLE: IOS or MAC or IOS_MACCATALYST
 //    IS_BSD: FREEBSD or NETBSD or OPENBSD
 //    IS_POSIX: AIX or ANDROID or ASMJS or CHROMEOS or FREEBSD or IOS or LINUX
 //              or MAC or NACL or NETBSD or OPENBSD or QNX or SOLARIS
@@ -64,6 +64,11 @@
 #include <TargetConditionals.h>
 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
 #define OS_IOS 1
+// Catalyst is the technology that allows running iOS apps on macOS. These
+// builds are both OS_IOS and OS_IOS_MACCATALYST.
+#if defined(TARGET_OS_MACCATALYST) && TARGET_OS_MACCATALYST
+#define OS_IOS_MACCATALYST
+#endif  // defined(TARGET_OS_MACCATALYST) && TARGET_OS_MACCATALYST
 #else
 #define OS_MAC 1
 #endif  // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
@@ -180,6 +185,12 @@
 #define BUILDFLAG_INTERNAL_IS_IOS() (0)
 #endif
 
+#if defined(OS_IOS_MACCATALYST)
+#define BUILDFLAG_INTERNAL_IS_IOS_MACCATALYST() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_IOS_MACCATALYST() (0)
+#endif
+
 #if defined(OS_LINUX)
 #define BUILDFLAG_INTERNAL_IS_LINUX() (1)
 #else
diff --git a/copy.bara.sky b/copy.bara.sky
index 9741b8b..b1d8df5 100644
--- a/copy.bara.sky
+++ b/copy.bara.sky
@@ -26,6 +26,7 @@
         "base/functional/*.h",
         "base/i18n/uchar.h",
         "base/memory/raw_ptr.h",
+        "base/memory/raw_ptr_exclusion.h",
         "base/no_destructor.h",
         "base/ranges/*.h",
         "base/stl_util.h",
@@ -101,7 +102,6 @@
     # Fix some Perfetto includes.
     core.replace("perfetto/tracing/traced_value_forward.h", "perfetto/tracing/traced_value.h"),
 
-    core.replace("#include \"base/win/windows_types.h\"", "#include <windows.h>"),
     core.replace("#include \"base/strings/string_number_conversions_win.h\"", ""),
     core.replace("#include \"base/allocator/partition_allocator/partition_alloc_config.h\"", ""),
     core.replace("base/trace_event/base_tracing_forward.h", "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"),
diff --git a/url/gurl.cc b/url/gurl.cc
index 5c6b76c..1337666 100644
--- a/url/gurl.cc
+++ b/url/gurl.cc
@@ -439,12 +439,16 @@
 }
 
 std::string GURL::GetContent() const {
+  return std::string(GetContentPiece());
+}
+
+gurl_base::StringPiece GURL::GetContentPiece() const {
   if (!is_valid_)
-    return std::string();
-  std::string content = ComponentString(parsed_.GetContent());
+    return gurl_base::StringPiece();
+  url::Component content_component = parsed_.GetContent();
   if (!SchemeIs(url::kJavaScriptScheme) && parsed_.ref.len >= 0)
-    content.erase(content.size() - parsed_.ref.len - 1);
-  return content;
+    content_component.len -= parsed_.ref.len + 1;
+  return ComponentStringPiece(content_component);
 }
 
 bool GURL::HostIsIPAddress() const {
diff --git a/url/gurl.h b/url/gurl.h
index 63729ee..10ba992 100644
--- a/url/gurl.h
+++ b/url/gurl.h
@@ -278,6 +278,7 @@
   // It is an error to get the content of an invalid URL: the result will be an
   // empty string.
   std::string GetContent() const;
+  gurl_base::StringPiece GetContentPiece() const;
 
   // Returns true if the hostname is an IP address. Note: this function isn't
   // as cheap as a simple getter because it re-parses the hostname to verify.
diff --git a/url/gurl_unittest.cc b/url/gurl_unittest.cc
index 6dd1fc0..24e8f94 100644
--- a/url/gurl_unittest.cc
+++ b/url/gurl_unittest.cc
@@ -929,6 +929,7 @@
   for (const auto& test : cases) {
     GURL url(test.url);
     EXPECT_EQ(test.expected, url.GetContent()) << test.url;
+    EXPECT_EQ(test.expected, url.GetContentPiece()) << test.url;
   }
 }
 
diff --git a/url/origin.h b/url/origin.h
index 1b0a407..6769535 100644
--- a/url/origin.h
+++ b/url/origin.h
@@ -119,16 +119,9 @@
 // * The host component of an IPv6 address includes brackets, just like the URL
 //   representation.
 //
-// Usage:
-//
-// * Origins are generally constructed from an already-canonicalized GURL:
-//
-//     GURL url("https://example.com/");
-//     url::Origin origin = Origin::Create(url);
-//     origin.scheme(); // "https"
-//     origin.host(); // "example.com"
-//     origin.port(); // 443
-//     origin.opaque(); // false
+// * Constructing origins from GURLs (or from SchemeHostPort) is typically a red
+//   flag (this is true for `url::Origin::Create` but also to some extent for
+//   `url::Origin::Resolve`). See docs/security/origin-vs-url.md for more.
 //
 // * To answer the question "Are |this| and |that| "same-origin" with each
 //   other?", use |Origin::IsSameOriginWith|:
@@ -142,29 +135,46 @@
   // existing origins.
   Origin();
 
-  // Creates an Origin from |url|, as described at
-  // https://url.spec.whatwg.org/#origin, with the following additions:
+  // WARNING: Converting an URL into an Origin is usually a red flag. See
+  // //docs/security/origin-vs-url.md for more details. Some discussion about
+  // deprecating the Create method can be found in https://crbug.com/1270878.
   //
-  // 1. If |url| is invalid or non-standard, an opaque Origin is constructed.
+  // Creates an Origin from `url`, as described at
+  // https://url.spec.whatwg.org/#origin, with the following additions:
+  // 1. If `url` is invalid or non-standard, an opaque Origin is constructed.
   // 2. 'filesystem' URLs behave as 'blob' URLs (that is, the origin is parsed
   //    out of everything in the URL which follows the scheme).
   // 3. 'file' URLs all parse as ("file", "", 0).
   //
-  // Note that the returned Origin may have a different scheme and host from
-  // |url| (e.g. in case of blob URLs - see OriginTest.ConstructFromGURL).
+  // WARNING: `url::Origin::Create(url)` can give unexpected results if:
+  // 1) `url` is "about:blank", or "about:srcdoc" (returning unique, opaque
+  //    origin rather than the real origin of the frame)
+  // 2) `url` comes from a sandboxed frame (potentially returning a non-opaque
+  //    origin, when an opaque one is needed; see also
+  //    https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/)
+  // 3) Wrong `url` is used - e.g. in some navigations `base_url_for_data_url`
+  //    might need to be used instead of relying on
+  //    `content::NavigationHandle::GetURL`.
+  //
+  // WARNING: The returned Origin may have a different scheme and host from
+  // `url` (e.g. in case of blob URLs - see OriginTest.ConstructFromGURL).
+  //
+  // WARNING: data: URLs will be correctly be translated into opaque origins,
+  // but the precursor origin will be lost (unlike with `url::Origin::Resolve`).
   static Origin Create(const GURL& url);
 
-  // Creates an Origin for the resource |url| as if it were requested
-  // from the context of |base_origin|.  If |url| is standard
+  // Creates an Origin for the resource `url` as if it were requested
+  // from the context of `base_origin`. If `url` is standard
   // (in the sense that it embeds a complete origin, like http/https),
   // this returns the same value as would Create().
   //
-  // If |url| is "about:blank", this returns a copy of |base_origin|.
+  // If `url` is "about:blank" or "about:srcdoc", this returns a copy of
+  // `base_origin`.
   //
-  // Otherwise, returns a new opaque origin derived from |base_origin|.
+  // Otherwise, returns a new opaque origin derived from `base_origin`.
   // In this case, the resulting opaque origin will inherit the tuple
-  // (or precursor tuple) of |base_origin|, but will not be same origin
-  // with |base_origin|, even if |base_origin| is already opaque.
+  // (or precursor tuple) of `base_origin`, but will not be same origin
+  // with `base_origin`, even if `base_origin` is already opaque.
   static Origin Resolve(const GURL& url, const Origin& base_origin);
 
   // Copyable and movable.
@@ -222,9 +232,9 @@
   }
 
   // Non-opaque origin is "same-origin" with `url` if their schemes, hosts, and
-  // ports are exact matches.  Opaque origin is never "same-origin" with any
+  // ports are exact matches. Opaque origin is never "same-origin" with any
   // `url`.  about:blank, about:srcdoc, and invalid GURLs are never
-  // "same-origin" with any origin.  This method is a shorthand for
+  // "same-origin" with any origin. This method is a shorthand for
   // `origin.IsSameOriginWith(url::Origin::Create(url))`.
   //
   // See also CanBeDerivedFrom.
@@ -442,9 +452,9 @@
 
 COMPONENT_EXPORT(URL) bool IsSameOriginWith(const GURL& a, const GURL& b);
 
-// DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) copies |origin| into a new
-// stack-allocated variable named |<var_name>|.  This helps ensure that the
-// value of |origin| gets preserved in crash dumps.
+// DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) copies `origin` into a new
+// stack-allocated variable named `<var_name>`. This helps ensure that the
+// value of `origin` gets preserved in crash dumps.
 #define DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) \
   DEBUG_ALIAS_FOR_CSTR(var_name, (origin).Serialize().c_str(), 128)
 
diff --git a/url/scheme_host_port.h b/url/scheme_host_port.h
index 8d5acd9..70df243 100644
--- a/url/scheme_host_port.h
+++ b/url/scheme_host_port.h
@@ -133,7 +133,10 @@
   std::string Serialize() const;
 
   // Efficiently returns what GURL(Serialize()) would return, without needing to
-  // re-parse the URL.
+  // re-parse the URL. Note: this still performs allocations to copy data into
+  // GURL, so please avoid using this method if you only need to work on
+  // schemes, hosts, or ports individually.
+  // For example, see crrev.com/c/3637099/comments/782360d0_e14757be.
   GURL GetURL() const;
 
   // Two SchemeHostPort objects are "equal" iff their schemes, hosts, and ports
diff --git a/url/url_canon.h b/url/url_canon.h
index e935d7f..cab7d29 100644
--- a/url/url_canon.h
+++ b/url/url_canon.h
@@ -10,6 +10,7 @@
 
 #include "polyfills/base/component_export.h"
 #include "polyfills/base/export_template.h"
+#include "base/memory/raw_ptr_exclusion.h"
 #include "url/third_party/mozilla/url_parse.h"
 
 namespace url {
@@ -139,7 +140,7 @@
 
   // `buffer_` is not a raw_ptr<...> for performance reasons (based on analysis
   // of sampling profiler data).
-  T* buffer_;
+  RAW_PTR_EXCLUSION T* buffer_;
   int buffer_len_;
 
   // Used characters in the buffer.
diff --git a/url/url_canon_internal.cc b/url/url_canon_internal.cc
index 99541bd..bbb27a0 100644
--- a/url/url_canon_internal.cc
+++ b/url/url_canon_internal.cc
@@ -25,7 +25,7 @@
     if (static_cast<UCHAR>(source[i]) >= 0x80) {
       // ReadChar will fill the code point with kUnicodeReplacementCharacter
       // when the input is invalid, which is what we want.
-      unsigned code_point;
+      base_icu::UChar32 code_point;
       ReadUTFChar(source, &i, length, &code_point);
       AppendUTF8EscapedValue(code_point, output);
     } else {
@@ -233,7 +233,7 @@
     0,         // 0xE0 - 0xFF
 };
 
-const char16_t kUnicodeReplacementCharacter = 0xfffd;
+const base_icu::UChar32 kUnicodeReplacementCharacter = 0xfffd;
 
 void AppendStringOfType(const char* source, int length,
                         SharedCharTypes type,
@@ -248,8 +248,10 @@
   DoAppendStringOfType<char16_t, char16_t>(source, length, type, output);
 }
 
-bool ReadUTFChar(const char* str, int* begin, int length,
-                 unsigned* code_point_out) {
+bool ReadUTFChar(const char* str,
+                 int* begin,
+                 int length,
+                 base_icu::UChar32* code_point_out) {
   // This depends on ints and int32s being the same thing. If they're not, it
   // will fail to compile.
   // TODO(mmenke): This should probably be fixed.
@@ -264,7 +266,7 @@
 bool ReadUTFChar(const char16_t* str,
                  int* begin,
                  int length,
-                 unsigned* code_point_out) {
+                 base_icu::UChar32* code_point_out) {
   // This depends on ints and int32s being the same thing. If they're not, it
   // will fail to compile.
   // TODO(mmenke): This should probably be fixed.
@@ -293,7 +295,7 @@
                         CanonOutput* output) {
   bool success = true;
   for (int i = 0; i < input_len; i++) {
-    unsigned code_point;
+    base_icu::UChar32 code_point;
     success &= ReadUTFChar(input, &i, input_len, &code_point);
     AppendUTF8Value(code_point, output);
   }
@@ -305,7 +307,7 @@
                         CanonOutputT<char16_t>* output) {
   bool success = true;
   for (int i = 0; i < input_len; i++) {
-    unsigned code_point;
+    base_icu::UChar32 code_point;
     success &= ReadUTFChar(input, &i, input_len, &code_point);
     AppendUTF16Value(code_point, output);
   }
diff --git a/url/url_canon_internal.h b/url/url_canon_internal.h
index d674976..807ddc5 100644
--- a/url/url_canon_internal.h
+++ b/url/url_canon_internal.h
@@ -15,6 +15,7 @@
 
 #include "polyfills/base/component_export.h"
 #include "polyfills/base/notreached.h"
+#include "base/third_party/icu/icu_utf.h"
 #include "url/url_canon.h"
 
 namespace url {
@@ -139,7 +140,7 @@
 }
 
 // The character we'll substitute for undecodable or invalid characters.
-extern const char16_t kUnicodeReplacementCharacter;
+extern const base_icu::UChar32 kUnicodeReplacementCharacter;
 
 // UTF-8 functions ------------------------------------------------------------
 
@@ -155,7 +156,7 @@
 bool ReadUTFChar(const char* str,
                  int* begin,
                  int length,
-                 unsigned* code_point_out);
+                 base_icu::UChar32* code_point_out);
 
 // Generic To-UTF-8 converter. This will call the given append method for each
 // character that should be appended, with the given output method. Wrappers
@@ -163,8 +164,10 @@
 //
 // The char_value must have already been checked that it's a valid Unicode
 // character.
-template<class Output, void Appender(unsigned char, Output*)>
-inline void DoAppendUTF8(unsigned char_value, Output* output) {
+template <class Output, void Appender(unsigned char, Output*)>
+inline void DoAppendUTF8(base_icu::UChar32 char_value, Output* output) {
+  GURL_DCHECK(char_value >= 0);
+  GURL_DCHECK(char_value <= 0x10FFFF);
   if (char_value <= 0x7f) {
     Appender(static_cast<unsigned char>(char_value), output);
   } else if (char_value <= 0x7ff) {
@@ -181,7 +184,7 @@
              output);
     Appender(static_cast<unsigned char>(0x80 | (char_value & 0x3f)),
              output);
-  } else if (char_value <= 0x10FFFF) {  // Max Unicode code point.
+  } else {
     // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
     Appender(static_cast<unsigned char>(0xf0 | (char_value >> 18)),
              output);
@@ -189,11 +192,7 @@
              output);
     Appender(static_cast<unsigned char>(0x80 | ((char_value >> 6) & 0x3f)),
              output);
-    Appender(static_cast<unsigned char>(0x80 | (char_value & 0x3f)),
-             output);
-  } else {
-    // Invalid UTF-8 character (>20 bits).
-    GURL_NOTREACHED();
+    Appender(static_cast<unsigned char>(0x80 | (char_value & 0x3f)), output);
   }
 }
 
@@ -207,7 +206,7 @@
 // Writes the given character to the output as UTF-8. This does NO checking
 // of the validity of the Unicode characters; the caller should ensure that
 // the value it is appending is valid to append.
-inline void AppendUTF8Value(unsigned char_value, CanonOutput* output) {
+inline void AppendUTF8Value(base_icu::UChar32 char_value, CanonOutput* output) {
   DoAppendUTF8<CanonOutput, AppendCharToOutput>(char_value, output);
 }
 
@@ -215,7 +214,8 @@
 // characters (even when they are ASCII). This does NO checking of the
 // validity of the Unicode characters; the caller should ensure that the value
 // it is appending is valid to append.
-inline void AppendUTF8EscapedValue(unsigned char_value, CanonOutput* output) {
+inline void AppendUTF8EscapedValue(base_icu::UChar32 char_value,
+                                   CanonOutput* output) {
   DoAppendUTF8<CanonOutput, AppendEscapedChar>(char_value, output);
 }
 
@@ -233,10 +233,10 @@
 bool ReadUTFChar(const char16_t* str,
                  int* begin,
                  int length,
-                 unsigned* code_point_out);
+                 base_icu::UChar32* code_point_out);
 
 // Equivalent to U16_APPEND_UNSAFE in ICU but uses our output method.
-inline void AppendUTF16Value(unsigned code_point,
+inline void AppendUTF16Value(base_icu::UChar32 code_point,
                              CanonOutputT<char16_t>* output) {
   if (code_point > 0xffff) {
     output->push_back(static_cast<char16_t>((code_point >> 10) + 0xd7c0));
@@ -274,7 +274,7 @@
   // UTF-16 input. ReadUTFChar will handle invalid characters for us and give
   // us the kUnicodeReplacementCharacter, so we don't have to do special
   // checking after failure, just pass through the failure to the caller.
-  unsigned char_value;
+  base_icu::UChar32 char_value;
   bool success = ReadUTFChar(str, begin, length, &char_value);
   AppendUTF8EscapedValue(char_value, output);
   return success;
@@ -286,7 +286,7 @@
   // ReadUTF8Char will handle invalid characters for us and give us the
   // kUnicodeReplacementCharacter, so we don't have to do special checking
   // after failure, just pass through the failure to the caller.
-  unsigned ch;
+  base_icu::UChar32 ch;
   bool success = ReadUTFChar(str, begin, length, &ch);
   AppendUTF8EscapedValue(ch, output);
   return success;
diff --git a/url/url_canon_stdstring.h b/url/url_canon_stdstring.h
index e9adc43..d8b94ec 100644
--- a/url/url_canon_stdstring.h
+++ b/url/url_canon_stdstring.h
@@ -13,6 +13,7 @@
 
 #include "base/compiler_specific.h"
 #include "polyfills/base/component_export.h"
+#include "base/memory/raw_ptr_exclusion.h"
 #include "base/strings/string_piece.h"
 #include "url/url_canon.h"
 
@@ -50,7 +51,7 @@
  protected:
   // `str_` is not a raw_ptr<...> for performance reasons (based on analysis of
   // sampling profiler data and tab_search:top100:2020).
-  std::string* str_;
+  RAW_PTR_EXCLUSION std::string* str_;
 };
 
 // An extension of the Replacements class that allows the setters to use
diff --git a/url/url_util.cc b/url/url_util.cc
index 26657f7..f56323e 100644
--- a/url/url_util.cc
+++ b/url/url_util.cc
@@ -151,9 +151,9 @@
                                      const char* compare_to) {
   if (!component.is_nonempty())
     return compare_to[0] == 0;  // When component is empty, match empty scheme.
-  return gurl_base::LowerCaseEqualsASCII(
-      typename CharToStringPiece<CHAR>::Piece(
-          &spec[component.begin], component.len),
+  return gurl_base::EqualsCaseInsensitiveASCII(
+      typename CharToStringPiece<CHAR>::Piece(&spec[component.begin],
+                                              component.len),
       compare_to);
 }
 
@@ -168,9 +168,10 @@
     return false;  // Empty or invalid schemes are non-standard.
 
   for (const SchemeWithType& scheme_with_type : schemes) {
-    if (gurl_base::LowerCaseEqualsASCII(typename CharToStringPiece<CHAR>::Piece(
-                                       &spec[scheme.begin], scheme.len),
-                                   scheme_with_type.scheme)) {
+    if (gurl_base::EqualsCaseInsensitiveASCII(
+            typename CharToStringPiece<CHAR>::Piece(&spec[scheme.begin],
+                                                    scheme.len),
+            scheme_with_type.scheme)) {
       *type = scheme_with_type.type;
       return true;
     }
@@ -838,14 +839,14 @@
       // next_ch will point to the last character of the decoded
       // character.
       int next_character = i;
-      unsigned code_point;
+      base_icu::UChar32 code_point;
       if (ReadUTFChar(unescaped_chars.data(), &next_character,
                       unescaped_chars.length(), &code_point)) {
         // Valid UTF-8 character, convert to UTF-16.
         AppendUTF16Value(code_point, output);
         i = next_character;
       } else if (mode == DecodeURLMode::kUTF8) {
-        GURL_DCHECK_EQ(code_point, 0xFFFDU);
+        GURL_DCHECK_EQ(code_point, 0xFFFD);
         AppendUTF16Value(code_point, output);
         i = next_character;
       } else {