Update googleurl with the latest code from upstream

This updates to Chromium revision 08e460691f1e6de2b7432b527c71f0de94553643
from Tue Sep 05 16:36:25 2023

Change-Id: If47cb6c0c87f2926735d5680b652a7e1b71f7dab
diff --git a/AUTHORS b/AUTHORS
index a0f5060..6714ac1 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -45,6 +45,7 @@
 Aiden Grossman <aidengrossmanpso@gmail.com>
 Ajay Berwal <a.berwal@samsung.com>
 Ajay Berwal <ajay.berwal@samsung.com>
+Ajay Sharma <ajay.sh@samsung.com>
 Ajith Kumar V <ajith.v@samsung.com>
 Akos Kiss <akiss@inf.u-szeged.hu>
 Aku Kotkavuo <a.kotkavuo@partner.samsung.com>
@@ -63,6 +64,7 @@
 Alex Scheele <alexscheele@gmail.com>
 Alexander Douglas <agdoug@amazon.com>
 Alexander Forrence <alex.forrence@gmail.com>
+Alexander Frick <alex313031@gmail.com>
 Alexander Guettler <alexander@guettler.io>
 Alexander Rezepkin <etu@vivaldi.net>
 Alexander Shalamov <alexander.shalamov@intel.com>
@@ -161,6 +163,7 @@
 Ashutosh  <codingtosh@gmail.com>
 Asish Singh <asish.singh@samsung.com>
 Attila Dusnoki <dati91@gmail.com>
+Avi Mathur <avi.mathur009@gmail.com>
 Avinaash Doreswamy <avi.nitk@samsung.com>
 Axel Chong <haxatron1@gmail.com>
 Ayush Dubey <dubeyaayush07@gmail.com>
@@ -246,6 +249,7 @@
 Charles Vaughn <cvaughn@gmail.com>
 Cheng Zhao <zcbenz@gmail.com>
 Cheng Yu <yuzichengcode@gmail.com>
+Chenguang Shao <chenguangshao1@gmail.com>
 Choongwoo Han <cwhan.tunz@gmail.com>
 Choudhury M. Shamsujjoha <choudhury.s@samsung.com>
 Chris Dalton <chris@rive.app>
@@ -329,6 +333,7 @@
 Deomid rojer Ryabkov <rojer9@gmail.com>
 Derek Halman <d.halman@gmail.com>
 Devlin Cronin <rdevlin.cronin@gmail.com>
+Dheeraj Kumar <dh.kumar@samsung.com>
 Dhi Aurrahman <dio@rockybars.com>
 Di Wu <meetwudi@gmail.com>
 Diana Suvorova <diana.suvorova@gmail.com>
@@ -470,6 +475,7 @@
 Heeyoun Lee <heeyoun.lee@samsung.com>
 Henrique de Carvalho <decarv.henrique@gmail.com>
 Henrique Limas <henrique.ramos.limas@gmail.com>
+Henry Lim <henry@limhenry.xyz>
 Hikari Fujimoto <hikari.p.fujimoto@gmail.com>
 Himanshu Joshi <h.joshi@samsung.com>
 Himanshu Nayak <himanshu.nayak@amd.corp-partner.google.com>
@@ -566,6 +572,7 @@
 Jared Wein <weinjared@gmail.com>
 Jari Karppanen <jkarp@amazon.com>
 Jason Gronn <jasontopia03@gmail.com>
+Javayhu <javayhu@gmail.com>
 Jay Oster <jay@kodewerx.org>
 Jay Soffian <jaysoffian@gmail.com>
 Jeado Ko <haibane84@gmail.com>
@@ -680,6 +687,7 @@
 JungJik Lee <jungjik.lee@samsung.com>
 Jungkee Song <jungkee.song@samsung.com>
 Junmin Zhu <junmin.zhu@intel.com>
+Junsang Mo <mojunsang26@gmail.com>
 Junsong Li <ljs.darkfish@gmail.com>
 Jun Wang <wangjuna@uniontech.com>
 Jun Zeng <hjunzeng6@gmail.com>
@@ -844,6 +852,7 @@
 Martin Persson <mnpn03@gmail.com>
 Martin Rogalla <martin@martinrogalla.com>
 Martina Kollarova <martina.kollarova@intel.com>
+Martino Fontana <tinozzo123@gmail.com>
 Masahiro Yado <yado.masa@gmail.com>
 Masaru Nishida <msr.i386@gmail.com>
 Masayuki Wakizaka <mwakizaka0108@gmail.com>
@@ -1419,6 +1428,7 @@
 Yizhou Jiang <yizhou.jiang@intel.com>
 Yoav Weiss <yoav@yoav.ws>
 Yoav Zilberberg <yoav.zilberberg@gmail.com>
+Yogesh <yogesh.dabas@samsung.com>
 Yoichiro Hibara <hibarayoichiro871@gmail.com>
 Yong Ling <yongling@tencent.com>
 Yong Shin <sy3620@gmail.com>
@@ -1482,6 +1492,7 @@
 Zsolt Borbely <zsborbely.u-szeged@partner.samsung.com>
 方觉 (Fang Jue) <fangjue23303@gmail.com>
 迷渡 <justjavac@gmail.com>
+郑苏波 (Super Zheng) <superzheng@tencent.com>
 # Please DO NOT APPEND here. See comments at the top of the file.
 # END individuals section.
 
@@ -1559,6 +1570,7 @@
 Torchmobile Inc. Upwork <*@cloud.upwork.com>
 Venture 3 Systems LLC <*@venture3systems.com>
 Vewd Software AS <*@vewd.com>
+Vikas Mundra <vikas.mundra@samsung.com>
 Vivaldi Technologies AS <*@vivaldi.com>
 Wacom <*@wacom.com>
 Whist Technologies <*@whist.com>
diff --git a/base/containers/span.h b/base/containers/span.h
index a218045..83069d6 100644
--- a/base/containers/span.h
+++ b/base/containers/span.h
@@ -248,9 +248,6 @@
   using reference = T&;
   using const_reference = const T&;
   using iterator = CheckedContiguousIterator<T>;
-  // TODO(https://crbug.com/828324): Drop the const_iterator typedef once gMock
-  // supports containers without this nested type.
-  using const_iterator = iterator;
   using reverse_iterator = std::reverse_iterator<iterator>;
   static constexpr size_t extent = Extent;
 
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index 6e4ea0f..31feafc 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -10,8 +10,6 @@
 #ifndef BASE_STRINGS_STRING_PIECE_H_
 #define BASE_STRINGS_STRING_PIECE_H_
 
-#include <functional>
-
 // Many files including this header rely on these being included due to IWYU
 // violations. Preserve the includes for now. As code is migrated away from this
 // header, we can incrementally fix the IWYU violations.
@@ -24,13 +22,4 @@
 #include "base/strings/utf_ostream_operators.h"
 #include "build/build_config.h"
 
-namespace gurl_base {
-
-// Historically, `std::hash` did not support `gurl_base::StringPiece`. Now
-// `gurl_base::StringPiece` is `std::string_view`, so this is no longer necessary.
-// Replace uses of this type with the default hasher.
-using StringPieceHash = std::hash<StringPiece>;
-
-}  // namespace base
-
 #endif  // BASE_STRINGS_STRING_PIECE_H_
diff --git a/base/strings/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc
index b77edbd..a6fcbbb 100644
--- a/base/strings/string_piece_unittest.cc
+++ b/base/strings/string_piece_unittest.cc
@@ -684,6 +684,7 @@
   }
 }
 
+#if defined(_LIBCPP_ENABLE_ASSERTIONS)
 TEST(StringPieceTest, OutOfBoundsDeath) {
   {
     constexpr StringPiece piece;
@@ -725,6 +726,7 @@
   int length = -1;
   ASSERT_DEATH_IF_SUPPORTED({ StringPiece piece("hello", length); }, "");
 }
+#endif  // defined(_LIBCPP_ENABLE_ASSERTIONS)
 
 TEST(StringPieceTest, ConstexprData) {
   {
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index 4a7638b..1633f7f 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -4,7 +4,6 @@
 
 #include "base/strings/string_util.h"
 
-#include <ctype.h>
 #include <errno.h>
 #include <math.h>
 #include <stdarg.h>
@@ -14,7 +13,6 @@
 #include <string.h>
 #include <time.h>
 #include <wchar.h>
-#include <wctype.h>
 
 #include <limits>
 #include <type_traits>
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index d40c11b..29936fa 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -7,7 +7,6 @@
 #ifndef BASE_STRINGS_STRING_UTIL_H_
 #define BASE_STRINGS_STRING_UTIL_H_
 
-#include <ctype.h>
 #include <stdarg.h>   // va_list
 #include <stddef.h>
 #include <stdint.h>
diff --git a/base/strings/string_util_impl_helpers.h b/base/strings/string_util_impl_helpers.h
index fb15c87..948463b 100644
--- a/base/strings/string_util_impl_helpers.h
+++ b/base/strings/string_util_impl_helpers.h
@@ -519,7 +519,7 @@
     const bool is_strict_mode,
     std::vector<size_t>* offsets) {
   size_t substitutions = subst.size();
-  GURL_DCHECK_LT(substitutions, 11U);
+  GURL_DCHECK_LT(substitutions, 10U);
 
   size_t sub_length = 0;
   for (const auto& cur : subst) {
diff --git a/base/strings/stringprintf.cc b/base/strings/stringprintf.cc
index 9509aff..1913fdc 100644
--- a/base/strings/stringprintf.cc
+++ b/base/strings/stringprintf.cc
@@ -38,13 +38,6 @@
                       va_list argptr) {
   return gurl_base::vswprintf(buffer, buf_size, format, argptr);
 }
-inline int vsnprintfT(char16_t* buffer,
-                      size_t buf_size,
-                      const char16_t* format,
-                      va_list argptr) {
-  return gurl_base::vswprintf(reinterpret_cast<wchar_t*>(buffer), buf_size,
-                         reinterpret_cast<const wchar_t*>(format), argptr);
-}
 #endif
 
 // Templatized backend for StringPrintF/StringAppendF. This does not finalize
@@ -135,15 +128,6 @@
   va_end(ap);
   return result;
 }
-
-std::u16string StringPrintf(const char16_t* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  std::u16string result;
-  StringAppendV(&result, format, ap);
-  va_end(ap);
-  return result;
-}
 #endif
 
 std::string StringPrintV(const char* format, va_list ap) {
@@ -152,38 +136,6 @@
   return result;
 }
 
-const std::string& SStringPrintf(std::string* dst, const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  dst->clear();
-  StringAppendV(dst, format, ap);
-  va_end(ap);
-  return *dst;
-}
-
-#if BUILDFLAG(IS_WIN)
-const std::wstring& SStringPrintf(std::wstring* dst,
-                                  const wchar_t* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  dst->clear();
-  StringAppendV(dst, format, ap);
-  va_end(ap);
-  return *dst;
-}
-
-const std::u16string& SStringPrintf(std::u16string* dst,
-                                    const char16_t* format,
-                                    ...) {
-  va_list ap;
-  va_start(ap, format);
-  dst->clear();
-  StringAppendV(dst, format, ap);
-  va_end(ap);
-  return *dst;
-}
-#endif
-
 void StringAppendF(std::string* dst, const char* format, ...) {
   va_list ap;
   va_start(ap, format);
@@ -198,13 +150,6 @@
   StringAppendV(dst, format, ap);
   va_end(ap);
 }
-
-void StringAppendF(std::u16string* dst, const char16_t* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  StringAppendV(dst, format, ap);
-  va_end(ap);
-}
 #endif
 
 void StringAppendV(std::string* dst, const char* format, va_list ap) {
@@ -215,10 +160,6 @@
 void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap) {
   StringAppendVT(dst, format, ap);
 }
-
-void StringAppendV(std::u16string* dst, const char16_t* format, va_list ap) {
-  StringAppendVT(dst, format, ap);
-}
 #endif
 
 }  // namespace base
diff --git a/base/strings/stringprintf.h b/base/strings/stringprintf.h
index b393c93..5266a13 100644
--- a/base/strings/stringprintf.h
+++ b/base/strings/stringprintf.h
@@ -21,12 +21,9 @@
 #if BUILDFLAG(IS_WIN)
 // Note: Unfortunately compile time checking of the format string for UTF-16
 // strings is not supported by any compiler, thus these functions should be used
-// carefully and sparingly. Also applies to SStringPrintf and StringAppendV
-// below.
+// carefully and sparingly. Also applies to StringAppendV below.
 [[nodiscard]] BASE_EXPORT std::wstring StringPrintf(const wchar_t* format, ...)
     WPRINTF_FORMAT(1, 2);
-[[nodiscard]] BASE_EXPORT std::u16string StringPrintf(const char16_t* format,
-                                                      ...) WPRINTF_FORMAT(1, 2);
 #endif
 
 // Return a C++ string given vprintf-like input.
@@ -34,27 +31,12 @@
                                                    va_list ap)
     PRINTF_FORMAT(1, 0);
 
-// Store result into a supplied string and return it.
-BASE_EXPORT const std::string& SStringPrintf(std::string* dst,
-                                             const char* format,
-                                             ...) PRINTF_FORMAT(2, 3);
-#if BUILDFLAG(IS_WIN)
-BASE_EXPORT const std::wstring& SStringPrintf(std::wstring* dst,
-                                              const wchar_t* format,
-                                              ...) WPRINTF_FORMAT(2, 3);
-BASE_EXPORT const std::u16string& SStringPrintf(std::u16string* dst,
-                                                const char16_t* format,
-                                                ...) WPRINTF_FORMAT(2, 3);
-#endif
-
 // Append result to a supplied string.
 BASE_EXPORT void StringAppendF(std::string* dst, const char* format, ...)
     PRINTF_FORMAT(2, 3);
 #if BUILDFLAG(IS_WIN)
 BASE_EXPORT void StringAppendF(std::wstring* dst, const wchar_t* format, ...)
     WPRINTF_FORMAT(2, 3);
-BASE_EXPORT void StringAppendF(std::u16string* dst, const char16_t* format, ...)
-    WPRINTF_FORMAT(2, 3);
 #endif
 
 // Lower-level routine that takes a va_list and appends to a specified
@@ -65,9 +47,6 @@
 BASE_EXPORT void StringAppendV(std::wstring* dst,
                                const wchar_t* format,
                                va_list ap) WPRINTF_FORMAT(2, 0);
-BASE_EXPORT void StringAppendV(std::u16string* dst,
-                               const char16_t* format,
-                               va_list ap) WPRINTF_FORMAT(2, 0);
 #endif
 
 }  // namespace base
diff --git a/base/strings/stringprintf_unittest.cc b/base/strings/stringprintf_unittest.cc
index c137095..45fa9c6 100644
--- a/base/strings/stringprintf_unittest.cc
+++ b/base/strings/stringprintf_unittest.cc
@@ -37,7 +37,6 @@
   EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w'));
 #if BUILDFLAG(IS_WIN)
   EXPECT_EQ(L"123hello w", StringPrintf(L"%3d%2ls %1lc", 123, L"hello", 'w'));
-  EXPECT_EQ(u"123hello w", StringPrintf(u"%3d%2ls %1lc", 123, u"hello", 'w'));
 #endif
 }
 
@@ -50,10 +49,6 @@
   std::wstring valuew(L"Hello");
   StringAppendF(&valuew, L"%ls", L"");
   EXPECT_EQ(L"Hello", valuew);
-
-  std::u16string value16(u"Hello");
-  StringAppendF(&value16, u"%ls", u"");
-  EXPECT_EQ(u"Hello", value16);
 #endif
 }
 
@@ -66,10 +61,6 @@
   std::wstring valuew(L"Hello");
   StringAppendF(&valuew, L" %ls", L"World");
   EXPECT_EQ(L"Hello World", valuew);
-
-  std::u16string value16(u"Hello");
-  StringAppendF(&value16, u" %ls", u"World");
-  EXPECT_EQ(u"Hello World", value16);
 #endif
 }
 
@@ -82,10 +73,6 @@
   std::wstring valuew(L"Hello");
   StringAppendF(&valuew, L" %d", 123);
   EXPECT_EQ(L"Hello 123", valuew);
-
-  std::u16string value16(u"Hello");
-  StringAppendF(&value16, u" %d", 123);
-  EXPECT_EQ(u"Hello 123", value16);
 #endif
 }
 
@@ -105,22 +92,11 @@
   for (int i = 1; i < 3; i++) {
     src[kSrcLen - i] = 0;
     std::string out;
-    SStringPrintf(&out, "%s", src);
-    EXPECT_STREQ(src, out.c_str());
+    EXPECT_EQ(src, StringPrintf("%s", src));
 
 #if BUILDFLAG(IS_WIN)
     srcw[kSrcLen - i] = 0;
-    std::wstring outw;
-    SStringPrintf(&outw, L"%ls", srcw);
-    EXPECT_STREQ(srcw, outw.c_str());
-
-    src16[kSrcLen - i] = 0;
-    std::u16string out16;
-    SStringPrintf(&out16, u"%ls", src16);
-    // EXPECT_STREQ does not support const char16_t* strings yet.
-    // Dispatch to the const wchar_t* overload instead.
-    EXPECT_STREQ(reinterpret_cast<const wchar_t*>(src16),
-                 reinterpret_cast<const wchar_t*>(out16.c_str()));
+    EXPECT_EQ(srcw, StringPrintf(L"%ls", srcw));
 #endif
   }
 }
@@ -134,9 +110,6 @@
 
   const char fmt[] = "%sB%sB%sB%sB%sB%sB%s";
 
-  std::string out;
-  SStringPrintf(&out, fmt, src, src, src, src, src, src, src);
-
   const int kRefSize = 320000;
   char* ref = new char[kRefSize];
 #if BUILDFLAG(IS_WIN)
@@ -145,7 +118,7 @@
   snprintf(ref, kRefSize, fmt, src, src, src, src, src, src, src);
 #endif
 
-  EXPECT_STREQ(ref, out.c_str());
+  EXPECT_EQ(ref, StringPrintf(fmt, src, src, src, src, src, src, src));
   delete[] ref;
 }
 
@@ -158,10 +131,6 @@
   std::wstring outw;
   StringAppendVTestHelper(&outw, L"%d foo %ls", 1, L"bar");
   EXPECT_EQ(L"1 foo bar", outw);
-
-  std::u16string out16;
-  StringAppendVTestHelper(&out16, u"%d foo %ls", 1, u"bar");
-  EXPECT_EQ(u"1 foo bar", out16);
 #endif
 }
 
@@ -178,10 +147,7 @@
     src[i] = 'a';
   src[kBufLen - 1] = 0;
 
-  std::string out;
-  SStringPrintf(&out, "%s", src);
-
-  EXPECT_STREQ(src, out.c_str());
+  EXPECT_EQ(src, StringPrintf("%s", src));
 }
 
 #if BUILDFLAG(IS_WIN)
@@ -190,9 +156,7 @@
   invalid[0] = 0xffff;
   invalid[1] = 0;
 
-  std::wstring out;
-  SStringPrintf(&out, L"%ls", invalid);
-  EXPECT_STREQ(invalid, out.c_str());
+  EXPECT_EQ(invalid, StringPrintf(L"%ls", invalid));
 }
 #endif
 
diff --git a/base/strings/sys_string_conversions.h b/base/strings/sys_string_conversions.h
index 37f5455..38f89f8 100644
--- a/base/strings/sys_string_conversions.h
+++ b/base/strings/sys_string_conversions.h
@@ -20,7 +20,7 @@
 #if BUILDFLAG(IS_APPLE)
 #include <CoreFoundation/CoreFoundation.h>
 
-#include "base/mac/scoped_cftyperef.h"
+#include "base/apple/scoped_cftyperef.h"
 
 #ifdef __OBJC__
 @class NSString;
@@ -63,10 +63,10 @@
 // Converts between strings and CFStringRefs/NSStrings.
 
 // Converts a string to a CFStringRef. Returns null on failure.
-[[nodiscard]] BASE_EXPORT ScopedCFTypeRef<CFStringRef> SysUTF8ToCFStringRef(
-    StringPiece utf8);
-[[nodiscard]] BASE_EXPORT ScopedCFTypeRef<CFStringRef> SysUTF16ToCFStringRef(
-    StringPiece16 utf16);
+[[nodiscard]] BASE_EXPORT apple::ScopedCFTypeRef<CFStringRef>
+SysUTF8ToCFStringRef(StringPiece utf8);
+[[nodiscard]] BASE_EXPORT apple::ScopedCFTypeRef<CFStringRef>
+SysUTF16ToCFStringRef(StringPiece16 utf16);
 
 // Converts a CFStringRef to a string. Returns an empty string on failure. It is
 // not valid to call these with a null `ref`.
diff --git a/base/strings/to_string.h b/base/strings/to_string.h
index 79c6b7d..26ff960 100644
--- a/base/strings/to_string.h
+++ b/base/strings/to_string.h
@@ -9,13 +9,18 @@
 #include <memory>
 #include <sstream>
 #include <string>
+#include <tuple>
 #include <type_traits>
+#include <utility>
 
 #include "base/template_util.h"
 #include "base/types/supports_ostream_operator.h"
 
 namespace gurl_base {
 
+template <typename... Ts>
+std::string ToString(const Ts&... values);
+
 namespace internal {
 
 template <typename T>
@@ -91,6 +96,23 @@
   }
 };
 
+// Tuples. Will recursively apply `ToString()` to each value in the tuple.
+template <typename... T>
+struct ToStringHelper<std::tuple<T...>> {
+  template <size_t... I>
+  static void StringifyHelper(const std::tuple<T...>& values,
+                              std::index_sequence<I...>,
+                              std::ostringstream& ss) {
+    ss << "<";
+    (..., (ss << (I == 0 ? "" : ", "), ss << ToString(std::get<I>(values))));
+    ss << ">";
+  }
+
+  static void Stringify(const std::tuple<T...>& v, std::ostringstream& ss) {
+    StringifyHelper(v, std::make_index_sequence<sizeof...(T)>(), ss);
+  }
+};
+
 }  // namespace internal
 
 // Converts any type to a string, preferring defined operator<<() or ToString()
@@ -98,9 +120,8 @@
 template <typename... Ts>
 std::string ToString(const Ts&... values) {
   std::ostringstream ss;
-  (internal::ToStringHelper<remove_cvref_t<decltype(values)>>::Stringify(values,
-                                                                         ss),
-   ...);
+  (..., internal::ToStringHelper<remove_cvref_t<decltype(values)>>::Stringify(
+            values, ss));
   return ss.str();
 }
 
diff --git a/base/strings/to_string_test.cc b/base/strings/to_string_unittest.cc
similarity index 93%
rename from base/strings/to_string_test.cc
rename to base/strings/to_string_unittest.cc
index f0c32b2..840b301 100644
--- a/base/strings/to_string_test.cc
+++ b/base/strings/to_string_unittest.cc
@@ -91,6 +91,13 @@
   EXPECT_EQ(ToString("42 in hex is ", std::hex, 42), "42 in hex is 2a");
 }
 
+TEST(ToStringTest, Tuple) {
+  // Tuples should correctly format the contained types.
+  EXPECT_EQ(ToString(std::make_tuple(StreamableTestEnum::kGreeting,
+                                     HasToString(), "a string")),
+            "<hello, yay!, a string>");
+}
+
 void Func() {}
 
 TEST(ToStringTest, FunctionPointer) {
diff --git a/base/third_party/icu/README.chromium b/base/third_party/icu/README.chromium
index b738af6..c514fc5 100644
--- a/base/third_party/icu/README.chromium
+++ b/base/third_party/icu/README.chromium
@@ -14,5 +14,5 @@
 ICU macros should ICU be in use on the system. For the same reason, the
 functions and types have been put in the "base_icu" namespace.
 
-Note that this license file is marked as NOT_SHIPPED, since a more complete
+Note that this license file is marked as not shipped, since a more complete
 ICU license is included from //third_party/icu/README.chromium
diff --git a/copy.bara.sky b/copy.bara.sky
index fd4034f..72fde7e 100644
--- a/copy.bara.sky
+++ b/copy.bara.sky
@@ -108,7 +108,6 @@
     # iOS version of url_idna is ASCII-only, but it uses .mm extension; rename
     # it to a .cc file.
     core.move("url/url_idna_icu_alternatives_ios.mm", "url/url_idna_ascii_only.cc"),
-    core.replace("!defined(__has_feature) || !__has_feature(objc_arc)", "false"),
 
     # Fix some Perfetto includes.
     core.replace("base/trace_event/base_tracing.h", "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"),
diff --git a/url/origin.cc b/url/origin.cc
index 06119ba..0274f34 100644
--- a/url/origin.cc
+++ b/url/origin.cc
@@ -22,6 +22,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
 #include "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"
+#include "polyfills/base/trace_event/memory_usage_estimator.h"
 #include "base/unguessable_token.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
@@ -393,6 +394,10 @@
   std::move(context).WriteString(GetDebugString());
 }
 
+size_t Origin::EstimateMemoryUsage() const {
+  return gurl_base::trace_event::EstimateMemoryUsage(tuple_);
+}
+
 std::ostream& operator<<(std::ostream& out, const url::Origin& origin) {
   out << origin.GetDebugString();
   return out;
diff --git a/url/origin.h b/url/origin.h
index d08229d..a49cbca 100644
--- a/url/origin.h
+++ b/url/origin.h
@@ -329,6 +329,10 @@
 
   void WriteIntoTrace(perfetto::TracedValue context) const;
 
+  // Estimates dynamic memory usage.
+  // See base/trace_event/memory_usage_estimator.h for more info.
+  size_t EstimateMemoryUsage() const;
+
  private:
   friend class blink::SecurityOrigin;
   friend class blink::SecurityOriginTest;
diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc
index db23d39..2db80a8 100644
--- a/url/scheme_host_port.cc
+++ b/url/scheme_host_port.cc
@@ -16,6 +16,7 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
+#include "polyfills/base/trace_event/memory_usage_estimator.h"
 #include "url/gurl.h"
 #include "url/third_party/mozilla/url_parse.h"
 #include "url/url_canon.h"
@@ -229,6 +230,11 @@
   return GURL(std::move(serialized), parsed, true);
 }
 
+size_t SchemeHostPort::EstimateMemoryUsage() const {
+  return gurl_base::trace_event::EstimateMemoryUsage(scheme_) +
+         gurl_base::trace_event::EstimateMemoryUsage(host_);
+}
+
 bool SchemeHostPort::operator<(const SchemeHostPort& other) const {
   return std::tie(port_, scheme_, host_) <
          std::tie(other.port_, other.scheme_, other.host_);
diff --git a/url/scheme_host_port.h b/url/scheme_host_port.h
index 88013dd..0798fec 100644
--- a/url/scheme_host_port.h
+++ b/url/scheme_host_port.h
@@ -139,6 +139,10 @@
   // For example, see crrev.com/c/3637099/comments/782360d0_e14757be.
   GURL GetURL() const;
 
+  // Estimates dynamic memory usage.
+  // See base/trace_event/memory_usage_estimator.h for more info.
+  size_t EstimateMemoryUsage() const;
+
   // Two SchemeHostPort objects are "equal" iff their schemes, hosts, and ports
   // are exact matches.
   //
diff --git a/url/url_canon_path.cc b/url/url_canon_path.cc
index ce28682..7f917db 100644
--- a/url/url_canon_path.cc
+++ b/url/url_canon_path.cc
@@ -6,10 +6,12 @@
 
 #include "polyfills/base/check.h"
 #include "polyfills/base/check_op.h"
+#include "polyfills/base/feature_list.h"
 #include "polyfills/base/metrics/histogram_functions.h"
 #include "absl/types/optional.h"
 #include "url/url_canon.h"
 #include "url/url_canon_internal.h"
+#include "url/url_features.h"
 #include "url/url_parse_internal.h"
 
 namespace url {
@@ -37,6 +39,7 @@
   // This character must be unescaped in canonical output. Not valid with
   // ESCAPE or PASS. We DON'T set the SPECIAL flag since if we encounter these
   // characters unescaped, they should just be copied.
+  // TODO(https://crbug.com/1252531): This is guarded by a feature flag.
   UNESCAPE = 4,
 };
 
@@ -333,7 +336,9 @@
             // the last character of the escape sequence.
             char unescaped_flags = kPathCharLookup[unescaped_value];
 
-            if (unescaped_flags & UNESCAPE) {
+            if (!gurl_base::FeatureList::IsEnabled(
+                    url::kDontDecodeAsciiPercentEncodedURLPath) &&
+                (unescaped_flags & UNESCAPE)) {
               // This escaped value shouldn't be escaped.  Try to copy it.
               unescape_escaped_char = true;
 
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc
index d4bfbdb..c1b19d2 100644
--- a/url/url_canon_unittest.cc
+++ b/url/url_canon_unittest.cc
@@ -1275,13 +1275,13 @@
     {"/foo%2\xc2\xa9zbar", nullptr, "/foo%2%C2%A9zbar", Component(0, 16), true},
     {nullptr, L"/foo%2\xc2\xa9zbar", "/foo%2%C3%82%C2%A9zbar", Component(0, 22),
      true},
-    // Regular characters that are escaped should be unescaped
-    {"/foo%41%7a", L"/foo%41%7a", "/fooAz", Component(0, 6), true},
+    // Regular characters that are escaped should remain escaped
+    {"/foo%41%7a", L"/foo%41%7a", "/foo%41%7a", Component(0, 10), true},
     // Funny characters that are unescaped should be escaped
     {"/foo\x09\x91%91", nullptr, "/foo%09%91%91", Component(0, 13), true},
     {nullptr, L"/foo\x09\x91%91", "/foo%09%C2%91%91", Component(0, 16), true},
     // %00 should not cause failures.
-    {"/foo%00%51", L"/foo%00%51", "/foo%00Q", Component(0, 8), true},
+    {"/foo%00%51", L"/foo%00%51", "/foo%00%51", Component(0, 10), true},
     // Some characters should be passed through unchanged regardless of esc.
     {"/(%28:%3A%29)", L"/(%28:%3A%29)", "/(%28:%3A%29)", Component(0, 13),
      true},
@@ -1302,21 +1302,20 @@
      "/%7Ffp3%3Eju%3Dduvgw%3Dd", Component(0, 24), true},
     // @ should be passed through unchanged (escaped or unescaped).
     {"/@asdf%40", L"/@asdf%40", "/@asdf%40", Component(0, 9), true},
-    // Nested escape sequences should result in escaping the leading '%' if
-    // unescaping would result in a new escape sequence.
-    {"/%A%42", L"/%A%42", "/%25AB", Component(0, 6), true},
-    {"/%%41B", L"/%%41B", "/%25AB", Component(0, 6), true},
-    {"/%%41%42", L"/%%41%42", "/%25AB", Component(0, 6), true},
+    // Nested escape sequences no longer happen. See https://crbug.com/1252531.
+    {"/%A%42", L"/%A%42", "/%A%42", Component(0, 6), true},
+    {"/%%41B", L"/%%41B", "/%%41B", Component(0, 6), true},
+    {"/%%41%42", L"/%%41%42", "/%%41%42", Component(0, 8), true},
     // Make sure truncated "nested" escapes don't result in reading off the
     // string end.
-    {"/%%41", L"/%%41", "/%A", Component(0, 3), true},
+    {"/%%41", L"/%%41", "/%%41", Component(0, 5), true},
     // Don't unescape the leading '%' if unescaping doesn't result in a valid
     // new escape sequence.
-    {"/%%470", L"/%%470", "/%G0", Component(0, 4), true},
-    {"/%%2D%41", L"/%%2D%41", "/%-A", Component(0, 4), true},
+    {"/%%470", L"/%%470", "/%%470", Component(0, 6), true},
+    {"/%%2D%41", L"/%%2D%41", "/%%2D%41", Component(0, 8), true},
     // Don't erroneously downcast a UTF-16 character in a way that makes it
     // look like part of an escape sequence.
-    {nullptr, L"/%%41\x0130", "/%A%C4%B0", Component(0, 9), true},
+    {nullptr, L"/%%41\x0130", "/%%41%C4%B0", Component(0, 11), true},
 
     // ----- encoding tests -----
     // Basic conversions
@@ -1622,7 +1621,7 @@
        "ws://%29w%1ew%81/", false},
       // Regression test for the last_invalid_percent_index bug described in
       // https://crbug.com/1080890#c10.
-      {R"(HTTP:S/5%\../>%41)", "http://s/%3EA", true},
+      {R"(HTTP:S/5%\../>%41)", "http://s/%3E%41", true},
   };
 
   for (size_t i = 0; i < std::size(cases); i++) {
@@ -2742,7 +2741,29 @@
   output.set_length(0);
 }
 
-TEST(URLCanonTest, UnescapePathCharHistogram) {
+class URLCanonAsciiPercentEncodePathTest
+    : public ::testing::Test,
+      public ::testing::WithParamInterface<bool> {
+ public:
+  URLCanonAsciiPercentEncodePathTest() {
+    if (GetParam()) {
+      scoped_feature_list_.InitAndEnableFeature(
+          url::kDontDecodeAsciiPercentEncodedURLPath);
+    } else {
+      scoped_feature_list_.InitAndDisableFeature(
+          url::kDontDecodeAsciiPercentEncodedURLPath);
+    }
+  }
+
+ private:
+  gurl_base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         URLCanonAsciiPercentEncodePathTest,
+                         ::testing::Bool());
+
+TEST_P(URLCanonAsciiPercentEncodePathTest, UnescapePathCharHistogram) {
   struct TestCase {
     gurl_base::StringPiece path;
     gurl_base::HistogramBase::Count cnt;
@@ -2760,8 +2781,13 @@
     StdStringCanonOutput output(&out_str);
     bool success = CanonicalizePath(c.path.data(), in_comp, &output, &out_comp);
     ASSERT_TRUE(success);
-    histogram_tester.ExpectBucketCount("URL.Path.UnescapeEscapedChar", 1,
-                                       c.cnt);
+    if (gurl_base::FeatureList::IsEnabled(
+            url::kDontDecodeAsciiPercentEncodedURLPath)) {
+      histogram_tester.ExpectBucketCount("URL.Path.UnescapeEscapedChar", 1, 0);
+    } else {
+      histogram_tester.ExpectBucketCount("URL.Path.UnescapeEscapedChar", 1,
+                                         c.cnt);
+    }
   }
 }
 
diff --git a/url/url_features.cc b/url/url_features.cc
index d033755..e046f60 100644
--- a/url/url_features.cc
+++ b/url/url_features.cc
@@ -25,6 +25,11 @@
              "ResolveBareFragmentWithColonOnNonHierarchical",
              gurl_base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Kill switch for crbug.com/1252531.
+BASE_FEATURE(kDontDecodeAsciiPercentEncodedURLPath,
+             "DontDecodeAsciiPercentEncodedURLPath",
+             gurl_base::FEATURE_ENABLED_BY_DEFAULT);
+
 bool IsUsingIDNA2008NonTransitional() {
   // If the FeatureList isn't available yet, fall back to the feature's default
   // state. This may happen during early startup, see crbug.com/1441956.
diff --git a/url/url_features.h b/url/url_features.h
index 41f689b..3dfb383 100644
--- a/url/url_features.h
+++ b/url/url_features.h
@@ -28,6 +28,11 @@
 COMPONENT_EXPORT(URL)
 BASE_DECLARE_FEATURE(kResolveBareFragmentWithColonOnNonHierarchical);
 
+// When enabled, percent-encoded ASCII characters in URL path are not decoded
+// automatically. See https://crbug.com/125231.
+COMPONENT_EXPORT(URL)
+BASE_DECLARE_FEATURE(kDontDecodeAsciiPercentEncodedURLPath);
+
 }  // namespace url
 
 #endif  // URL_URL_FEATURES_H_
diff --git a/url/url_idna_ascii_only.cc b/url/url_idna_ascii_only.cc
index 921858a..2a4f0d3 100644
--- a/url/url_idna_ascii_only.cc
+++ b/url/url_idna_ascii_only.cc
@@ -12,10 +12,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "url/url_canon_internal.h"
 
-#if false
-#error "This file requires ARC support."
-#endif
-
 namespace url {
 
 // Only allow ASCII to avoid ICU dependency. Use NSString+IDN