Update googleurl to the latest version from Chromium

Updates to the revision 2c56a1e7c31195a6942f0f998f0b7fbb3099e1d5 from
Wed Aug 2 00:55:29 2023 +0000

Change-Id: Ie449129673f41f0dfa85101139622881734896d8
diff --git a/AUTHORS b/AUTHORS
index 365f616..a0f5060 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -12,6 +12,7 @@
 
 # BEGIN individuals section.
 Aaron Boushley <boushley@gmail.com>
+Aaron Dewes <aarondewes@gmail.com>
 Aaron Jacobs <samusaaron3@gmail.com>
 Aaron Leventhal <aaronlevbugs@gmail.com>
 Aaron Randolph <aaron.randolph@gmail.com>
@@ -122,6 +123,7 @@
 Ankur Verma <ankur1.verma@samsung.com>
 Anna Henningsen <anna@addaleax.net>
 Anne Kao <annekao94@gmail.com>
+Ansh Mishra <mishra.ansh6@gmail.com>
 Anshul Jain <anshul.jain@samsung.com>
 Anssi Hannula <anssi.hannula@iki.fi>
 Anthony Halliday <anth.halliday12@gmail.com>
@@ -160,6 +162,7 @@
 Asish Singh <asish.singh@samsung.com>
 Attila Dusnoki <dati91@gmail.com>
 Avinaash Doreswamy <avi.nitk@samsung.com>
+Axel Chong <haxatron1@gmail.com>
 Ayush Dubey <dubeyaayush07@gmail.com>
 Ayush Khandelwal <k.ayush@samsung.com>
 Azhar Shaikh <azhar.shaikh@intel.com>
@@ -323,6 +326,7 @@
 Deepak Singla <deepak.s@samsung.com>
 Deniz Eren Evrendilek <devrendilek@gmail.com>
 Deokjin Kim <deokjin81.kim@samsung.com>
+Deomid rojer Ryabkov <rojer9@gmail.com>
 Derek Halman <d.halman@gmail.com>
 Devlin Cronin <rdevlin.cronin@gmail.com>
 Dhi Aurrahman <dio@rockybars.com>
@@ -435,6 +439,7 @@
 Gnanasekar Somanathan <gnanasekar.s@samsung.com>
 Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
 Goutham Jagannatha <wrm364@motorola.com>
+Graham Sturmy <gsturmychromium@gmail.com>
 Graham Yoakum <gyoakum@skobalt.com>
 Greg Visser <gregvis@gmail.com>
 Gregory Davis <gpdavis.chromium@gmail.com>
@@ -794,6 +799,7 @@
 Lukasz Krakowiak <lukasz.krakowiak@mobica.com>
 Luke Inman-Semerau <luke.semerau@gmail.com>
 Luke Gu <gulukesh@gmail.com>
+Luke Warlow <lukewarlow156@gmail.com>
 Luke Warlow <luke@warlow.dev>
 Luke Zarko <lukezarko@gmail.com>
 Luoxi Pan <l.panpax@gmail.com>
@@ -831,6 +837,7 @@
 Mark Hahnenberg <mhahnenb@andrew.cmu.edu>
 Mark Seaborn <mrs@mythic-beasts.com>
 Mark Winter <wintermarkedward@gmail.com>
+Marten Richter <marten.richter@tu-berlin.de>
 Martijn Croonen <martijn@martijnc.be>
 Martin Aberer <mail@martin-aberer.at>
 Martin Bednorz <m.s.bednorz@gmail.com>
@@ -848,6 +855,7 @@
 Matt Fysh <mattfysh@gmail.com>
 Matt Strum <mstrum@amazon.com>
 Matt Zeunert <matt@mostlystatic.com>
+Matthew "strager" Glazar <strager.nds@gmail.com>
 Matthew Bauer <mjbauer95@gmail.com>
 Matthew Demarest <demarem@amazon.com>
 Matthew Robertson <matthewrobertson03@gmail.com>
@@ -927,6 +935,7 @@
 Nagarajan Narayanan <nagarajan.n@samsung.com>
 Nagarjuna Atluri <nagarjuna.a@samsung.com>
 Naiem Shaik <naiem.shaik@gmail.com>
+Naman Kumar Narula <namankumarnarula@gmail.com>
 Naoki Takano <takano.naoki@gmail.com>
 Naoto Ono <onoto1998@gmail.com>
 Nathan Mitchell <nathaniel.v.mitchell@gmail.com>
@@ -940,6 +949,7 @@
 Neal Gompa <ngompa13@gmail.com>
 Ned Williamson <nedwilliamson@gmail.com>
 Nedeljko Babic <nedeljko.babic@imgtec.com>
+Neehit Goyal <neehit.goyal@samsung.com>
 Nidhi Jaju <nidhijaju127@gmail.com>
 Niek van der Maas <mail@niekvandermaas.nl>
 Nikhil Bansal <n.bansal@samsung.com>
@@ -952,6 +962,7 @@
 Nils Schneider <nils@nilsschneider.net>
 Ningxin Hu <ningxin.hu@intel.com>
 Nitish Mehrotra <nitish.m@samsung.com>
+Nivedan Sharma <ni.sharma@samsung.com>
 Noam Rosenthal <noam.j.rosenthal@gmail.com>
 Noj Vek <nojvek@gmail.com>
 Nolan Cao <nolan.robin.cao@gmail.com>
@@ -960,6 +971,7 @@
 Olivier Tilloy <olivier+chromium@tilloy.net>
 Olli Raula (Old name Olli Syrjälä) <olli.raula@intel.com>
 Omar Sandoval <osandov@osandov.com>
+Owen Shaw <owenpshaw@gmail.com>
 Owen Yuwono <owenyuwono@gmail.com>
 Palash Verma <palashverma47@gmail.com>
 Pan Deng <pan.deng@intel.com>
@@ -1080,6 +1092,8 @@
 Robert Nagy <robert.nagy@gmail.com>
 Robert Sesek <rsesek@bluestatic.org>
 Roee Kasher <roee91@gmail.com>
+Roger Sanders <sanders_roger@hotmail.com>
+Roger Sanders <sanders.rogerj@gmail.com>
 Roger Zanoni <rogerzanoni@gmail.com>
 Roland Takacs <rtakacs.u-szeged@partner.samsung.com>
 Romain Pokrzywka <romain.pokrzywka@gmail.com>
@@ -1266,6 +1280,7 @@
 Takashi Fujita <tgfjt.mail@gmail.com>
 Takashi Mima <tks.m1205@gmail.com>
 Takeshi Kurosawa <taken.spc@gmail.com>
+Takuya Kurimoto <takuya004869@gmail.com>
 Tanay Chowdhury <tanay.c@samsung.com>
 Tanvir Rizvi <tanvir.rizvi@samsung.com>
 Tao Wang <tao.wang.2261@gmail.com>
@@ -1414,6 +1429,7 @@
 Yongsheng Zhu <yongsheng.zhu@intel.com>
 Yoonjae Cho <yoonjae.cho92@gmail.com>
 Yoshinori Sano <yoshinori.sano@gmail.com>
+Yoshiya Hinosawa <stibium121@gmail.com>
 Young Min Kim <y@ylem.kim>
 Youngho Seo <hazivoo@gmail.com>
 Youngjin Choi <cyjin9.yc@gmail.com>
diff --git a/base/debug/crash_logging.h b/base/debug/crash_logging.h
index ec1df77..381a13d 100644
--- a/base/debug/crash_logging.h
+++ b/base/debug/crash_logging.h
@@ -120,13 +120,20 @@
 
 // Internal helpers for the SCOPED_CRASH_KEY_... helper macros defined below.
 //
-// The static_assert that checks the length of |key_name| is a compile-time
-// equivalent of the GURL_DCHECK in crash_reporter::internal::CrashKeyStringImpl::Set
-// that restricts the name of a crash key to 40 characters.
+// The first static_assert that checks the length of |key_name| is a
+// compile-time equivalent of the GURL_DCHECK in
+// crash_reporter::internal::CrashKeyStringImpl::Set that restricts the name of
+// a crash key to 40 characters.
+//
+// The second static_assert that checks for reserved characters is a compile
+// time equivalent of the GURL_DCHECK in gurl_base::debug::AllocateCrashKeyString.
 #define SCOPED_CRASH_KEY_STRING_INTERNAL2(category, name, nonce, data,  \
                                           key_size)                     \
   static_assert(::std::size(category "-" name) < 40,                    \
                 "Crash key names must be shorter than 40 characters."); \
+  static_assert(::gurl_base::StringPiece(category "-" name).find(':') ==     \
+                    ::gurl_base::StringPiece::npos,                          \
+                "Crash key names must not contain the ':' character."); \
   ::gurl_base::debug::ScopedCrashKeyString scoped_crash_key_helper##nonce(   \
       [] {                                                              \
         static auto* const key = ::gurl_base::debug::AllocateCrashKeyString( \
diff --git a/base/stl_util.h b/base/stl_util.h
index 2511412..3e75842 100644
--- a/base/stl_util.h
+++ b/base/stl_util.h
@@ -48,47 +48,6 @@
   obj->reserve(0);
 }
 
-// O(1) implementation of const casting an iterator for any sequence,
-// associative or unordered associative container in the STL.
-//
-// Reference: https://stackoverflow.com/a/10669041
-template <typename Container,
-          typename ConstIter,
-          std::enable_if_t<!internal::IsRandomAccessIter<ConstIter>>* = nullptr>
-constexpr auto ConstCastIterator(Container& c, ConstIter it) {
-  return c.erase(it, it);
-}
-
-// Explicit overload for std::forward_list where erase() is named erase_after().
-template <typename T, typename Allocator>
-constexpr auto ConstCastIterator(
-    std::forward_list<T, Allocator>& c,
-    typename std::forward_list<T, Allocator>::const_iterator it) {
-// The erase_after(it, it) trick used below does not work for libstdc++ [1],
-// thus we need a different way.
-// TODO(crbug.com/972541): Remove this workaround once libstdc++ is fixed on all
-// platforms.
-//
-// [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90857
-#if defined(__GLIBCXX__)
-  return c.insert_after(it, {});
-#else
-  return c.erase_after(it, it);
-#endif
-}
-
-// Specialized O(1) const casting for random access iterators. This is
-// necessary, because erase() is either not available (e.g. array-like
-// containers), or has O(n) complexity (e.g. std::deque or std::vector).
-template <typename Container,
-          typename ConstIter,
-          std::enable_if_t<internal::IsRandomAccessIter<ConstIter>>* = nullptr>
-constexpr auto ConstCastIterator(Container& c, ConstIter it) {
-  using std::begin;
-  using std::cbegin;
-  return begin(c) + (it - cbegin(c));
-}
-
 // Returns a new ResultType containing the difference of two sorted containers.
 template <typename ResultType, typename Arg1, typename Arg2>
 ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) {
diff --git a/base/strings/escape.cc b/base/strings/escape.cc
index 7a3d701..d7d055c 100644
--- a/base/strings/escape.cc
+++ b/base/strings/escape.cc
@@ -443,8 +443,7 @@
     if (!ShouldUnescapeCodePoint(rules, code_point)) {
       // If it's a valid UTF-8 character, but not safe to unescape, copy all
       // bytes directly.
-      result.append(escaped_text.begin() + i,
-                    escaped_text.begin() + i + 3 * unescaped.length());
+      result.append(escaped_text.substr(i, 3 * unescaped.length()));
       i += unescaped.length() * 3;
       continue;
     }
diff --git a/base/strings/string_piece_rust.h b/base/strings/string_piece_rust.h
index 135b3df..39fb51b 100644
--- a/base/strings/string_piece_rust.h
+++ b/base/strings/string_piece_rust.h
@@ -5,14 +5,15 @@
 #ifndef BASE_STRINGS_STRING_PIECE_RUST_H_
 #define BASE_STRINGS_STRING_PIECE_RUST_H_
 
-#include "base/rust_buildflags.h"
-
-#if BUILDFLAG(BUILD_RUST_BASE_CONVERSIONS)
-
 #include <stdint.h>
 
-#include "base/strings/string_piece.h"
-#include "third_party/rust/cxx/v1/crate/include/cxx.h"  // nogncheck
+#include "base/rust_buildflags.h"
+#include "base/strings/string_piece_forward.h"
+#include "third_party/rust/cxx/v1/crate/include/cxx.h"
+
+#if !BUILDFLAG(BUILD_RUST_BASE_CONVERSIONS)
+#error "string_piece_rust.h included without BUILD_RUST_BASE_CONVERSIONS"
+#endif
 
 namespace gurl_base {
 
@@ -39,6 +40,4 @@
 
 }  // namespace base
 
-#endif  // BUILDFLAG(BUILD_RUST_BASE_CONVERSIONS)
-
 #endif  // BASE_STRINGS_STRING_PIECE_RUST_H_
diff --git a/base/strings/string_piece_rust_unittest.cc b/base/strings/string_piece_rust_unittest.cc
index a5edcbd..38d50d4 100644
--- a/base/strings/string_piece_rust_unittest.cc
+++ b/base/strings/string_piece_rust_unittest.cc
@@ -3,12 +3,9 @@
 // found in the LICENSE file.
 
 #include "base/strings/string_piece_rust.h"
-#include "base/rust_buildflags.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if BUILDFLAG(BUILD_RUST_BASE_CONVERSIONS)
-
 namespace gurl_base {
 namespace {
 
@@ -31,5 +28,3 @@
 
 }  // namespace
 }  // namespace base
-
-#endif  // BUILDFLAG(BUILD_RUST_BASE_CONVERSIONS)
diff --git a/base/strings/to_string.h b/base/strings/to_string.h
index 78691a0..79c6b7d 100644
--- a/base/strings/to_string.h
+++ b/base/strings/to_string.h
@@ -10,7 +10,6 @@
 #include <sstream>
 #include <string>
 #include <type_traits>
-#include <utility>
 
 #include "base/template_util.h"
 #include "base/types/supports_ostream_operator.h"
@@ -19,11 +18,8 @@
 
 namespace internal {
 
-template <typename T, typename = void>
-struct SupportsToString : std::false_type {};
 template <typename T>
-struct SupportsToString<T, decltype(void(std::declval<T>().ToString()))>
-    : std::true_type {};
+concept SupportsToString = requires(const T& t) { t.ToString(); };
 
 // I/O manipulators are function pointers, but should be sent directly to the
 // `ostream` instead of being cast to `const void*` like other function
@@ -55,19 +51,17 @@
 
 // Most streamables.
 template <typename T>
-struct ToStringHelper<
-    T,
-    std::enable_if_t<SupportsOstreamOperator<const T&>::value &&
-                     !WillBeIncorrectlyStreamedAsBool<T>>> {
+struct ToStringHelper<T,
+                      std::enable_if_t<SupportsOstreamOperator<const T&> &&
+                                       !WillBeIncorrectlyStreamedAsBool<T>>> {
   static void Stringify(const T& v, std::ostringstream& ss) { ss << v; }
 };
 
 // Functions and function pointers.
 template <typename T>
-struct ToStringHelper<
-    T,
-    std::enable_if_t<SupportsOstreamOperator<const T&>::value &&
-                     WillBeIncorrectlyStreamedAsBool<T>>> {
+struct ToStringHelper<T,
+                      std::enable_if_t<SupportsOstreamOperator<const T&> &&
+                                       WillBeIncorrectlyStreamedAsBool<T>>> {
   static void Stringify(const T& v, std::ostringstream& ss) {
     ToStringHelper<const void*>::Stringify(reinterpret_cast<const void*>(v),
                                            ss);
@@ -76,10 +70,9 @@
 
 // Non-streamables that have a `ToString` member.
 template <typename T>
-struct ToStringHelper<
-    T,
-    std::enable_if_t<!SupportsOstreamOperator<const T&>::value &&
-                     SupportsToString<const T&>::value>> {
+struct ToStringHelper<T,
+                      std::enable_if_t<!SupportsOstreamOperator<const T&> &&
+                                       SupportsToString<const T&>>> {
   static void Stringify(const T& v, std::ostringstream& ss) {
     // .ToString() may not return a std::string, e.g. blink::WTF::String.
     ToStringHelper<decltype(v.ToString())>::Stringify(v.ToString(), ss);
@@ -91,8 +84,7 @@
 template <typename T>
 struct ToStringHelper<
     T,
-    std::enable_if_t<!SupportsOstreamOperator<const T&>::value &&
-                     std::is_enum_v<T>>> {
+    std::enable_if_t<!SupportsOstreamOperator<const T&> && std::is_enum_v<T>>> {
   static void Stringify(const T& v, std::ostringstream& ss) {
     using UT = typename std::underlying_type_t<T>;
     ToStringHelper<UT>::Stringify(static_cast<UT>(v), ss);
diff --git a/base/strings/to_string_test.cc b/base/strings/to_string_test.cc
index 87d021f..f0c32b2 100644
--- a/base/strings/to_string_test.cc
+++ b/base/strings/to_string_test.cc
@@ -20,14 +20,22 @@
 };
 
 // .ToString() support on structs.
-static_assert(!internal::SupportsToString<NotStringifiable>::value,
+static_assert(!internal::SupportsToString<NotStringifiable>,
               "value without ToString() shouldn't be marked SupportsToString");
-static_assert(!internal::SupportsToString<const NotStringifiable&>::value,
+static_assert(!internal::SupportsToString<NotStringifiable&>,
+              "& without ToString() shouldn't be marked SupportsToString");
+static_assert(!internal::SupportsToString<const NotStringifiable&>,
               "const& without ToString() shouldn't be marked SupportsToString");
-static_assert(internal::SupportsToString<HasToString>::value,
+static_assert(!internal::SupportsToString<NotStringifiable&&>,
+              "&& without ToString() shouldn't be marked SupportsToString");
+static_assert(internal::SupportsToString<HasToString>,
               "value with ToString() should be marked SupportsToString");
-static_assert(internal::SupportsToString<const HasToString&>::value,
+static_assert(internal::SupportsToString<HasToString&>,
+              "& with ToString() should be marked SupportsToString");
+static_assert(internal::SupportsToString<const HasToString&>,
               "const& with ToString() should be marked SupportsToString");
+static_assert(internal::SupportsToString<HasToString&&>,
+              "&& with ToString() should be marked SupportsToString");
 
 TEST(ToStringTest, Streamable) {
   // Types with built-in <<.
diff --git a/base/strings/utf_ostream_operators.h b/base/strings/utf_ostream_operators.h
index 6fca090..58558a5 100644
--- a/base/strings/utf_ostream_operators.h
+++ b/base/strings/utf_ostream_operators.h
@@ -6,6 +6,7 @@
 #define BASE_STRINGS_UTF_OSTREAM_OPERATORS_H_
 
 #include <iosfwd>
+#include <string>
 #include <string_view>
 
 #include "polyfills/base/base_export.h"
diff --git a/base/third_party/icu/README.chromium b/base/third_party/icu/README.chromium
index 4f398d9..b738af6 100644
--- a/base/third_party/icu/README.chromium
+++ b/base/third_party/icu/README.chromium
@@ -2,7 +2,8 @@
 URL: http://site.icu-project.org/
 Version: 60
 License: Unicode
-License File: NOT_SHIPPED
+License File: LICENSE
+Shipped: no
 
 This file has the relevant components from ICU copied to handle basic UTF8/16/32
 conversions. Components are copied from umachine.h, utf.h, utf8.h, and utf16.h
diff --git a/copy.bara.sky b/copy.bara.sky
index 9020cbf..fd4034f 100644
--- a/copy.bara.sky
+++ b/copy.bara.sky
@@ -83,6 +83,7 @@
     "base/logging.h",
     "base/memory/raw_ptr.h",
     "base/memory/raw_ptr_exclusion.h",
+    "base/metrics/histogram_functions.h",
     "base/notreached.h",
     "base/trace_event/memory_usage_estimator.h",
 ]
diff --git a/polyfills/BUILD b/polyfills/BUILD
index 6bd0565..86cecc1 100644
--- a/polyfills/BUILD
+++ b/polyfills/BUILD
@@ -19,6 +19,7 @@
         "base/logging.h",
         "base/memory/raw_ptr.h",
         "base/memory/raw_ptr_exclusion.h",
+        "base/metrics/histogram_functions.h",
         "base/metrics/histogram_macros.h",
         "base/notreached.h",
         "base/trace_event/memory_usage_estimator.h",
diff --git a/polyfills/base/metrics/histogram_functions.h b/polyfills/base/metrics/histogram_functions.h
new file mode 100644
index 0000000..a6f35f8
--- /dev/null
+++ b/polyfills/base/metrics/histogram_functions.h
@@ -0,0 +1,9 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+namespace gurl_base {
+
+inline void UmaHistogramBoolean(const char* /*name*/, bool /*sample*/) {}
+
+}  // namespace gurl_base
diff --git a/url/third_party/mozilla/README.chromium b/url/third_party/mozilla/README.chromium
index ef396d3..9df1992 100644
--- a/url/third_party/mozilla/README.chromium
+++ b/url/third_party/mozilla/README.chromium
@@ -1,7 +1,11 @@
 Name: url_parse
-URL: http://mxr.mozilla.org/comm-central/source/mozilla/netwerk/base/src/nsURLParsers.cpp
+Version: unknown
+URL: https://hg.mozilla.org/mozilla-central/file/tip/netwerk/base/nsURLParsers.cpp
 License: BSD and MPL 1.1/GPL 2.0/LGPL 2.1
 License File: LICENSE.txt
+Shipped: yes
+Security Critical: yes
+CPEPrefix: unknown
 
 Description:
 
diff --git a/url/url_canon_path.cc b/url/url_canon_path.cc
index 9a03fb4..ce28682 100644
--- a/url/url_canon_path.cc
+++ b/url/url_canon_path.cc
@@ -6,6 +6,7 @@
 
 #include "polyfills/base/check.h"
 #include "polyfills/base/check_op.h"
+#include "polyfills/base/metrics/histogram_functions.h"
 #include "absl/types/optional.h"
 #include "url/url_canon.h"
 #include "url/url_canon_internal.h"
@@ -37,25 +38,24 @@
   // ESCAPE or PASS. We DON'T set the SPECIAL flag since if we encounter these
   // characters unescaped, they should just be copied.
   UNESCAPE = 4,
-
-  // This character is disallowed in URLs. Note that the "special" bit is also
-  // set to trigger handling.
-  INVALID_BIT = 8,
-  INVALID = INVALID_BIT | SPECIAL,
 };
 
 // This table contains one of the above flag values. Note some flags are more
 // than one bits because they also turn on the "special" flag. Special is the
 // only flag that may be combined with others.
 //
-// This table is designed to match exactly what IE does with the characters.
+// This table was used to be designed to match exactly what IE did with the
+// characters, however, which doesn't comply with the URL Standard as of Jun
+// 2023. See http://crbug.com/1400251 and http://crbug.com/1252531 for efforts
+// to comply with the URL Standard.
 //
 // Dot is even more special, and the escaped version is handled specially by
 // IsDot. Therefore, we don't need the "escape" flag, and even the "unescape"
 // bit is never handled (we just need the "special") bit.
+// clang-format off
 const unsigned char kPathCharLookup[0x100] = {
 //   NULL     control chars...
-     INVALID, ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
+     ESCAPE , ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
 //   control chars...
      ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
 //   ' '      !        "        #        $        %        &        '        (        )        *        +        ,        -        .        /
@@ -79,6 +79,7 @@
      ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
      ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
      ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE};
+// clang-format on
 
 enum DotDisposition {
   // The given dot is just part of a filename and is not special.
@@ -266,6 +267,7 @@
   absl::optional<size_t> last_invalid_percent_index;
 
   bool success = true;
+  bool unescape_escaped_char = false;
   for (size_t i = static_cast<size_t>(path.begin); i < end; i++) {
     UCHAR uch = static_cast<UCHAR>(spec[i]);
     if (sizeof(CHAR) > 1 && uch >= 0x80) {
@@ -333,6 +335,8 @@
 
             if (unescaped_flags & UNESCAPE) {
               // This escaped value shouldn't be escaped.  Try to copy it.
+              unescape_escaped_char = true;
+
               output->push_back(unescaped_value);
               // If we just unescaped a value within 2 output characters of the
               // '%' from a previously-detected invalid escape sequence, we
@@ -354,8 +358,6 @@
               output->push_back('%');
               output->push_back(static_cast<char>(spec[i - 1]));
               output->push_back(static_cast<char>(spec[i]));
-              if (unescaped_flags & INVALID_BIT)
-                success = false;
             }
           } else {
             // Invalid escape sequence. IE7+ rejects any URLs with such
@@ -366,12 +368,6 @@
             last_invalid_percent_index = output->length();
             output->push_back('%');
           }
-
-        } else if (flags & INVALID_BIT) {
-          // For NULLs, etc. fail.
-          AppendEscapedChar(out_ch, output);
-          success = false;
-
         } else if (flags & ESCAPE_BIT) {
           // This character should be escaped.
           AppendEscapedChar(out_ch, output);
@@ -382,6 +378,8 @@
       }
     }
   }
+  gurl_base::UmaHistogramBoolean("URL.Path.UnescapeEscapedChar",
+                            unescape_escaped_char);
   return success;
 }
 
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc
index e927f74..d4bfbdb 100644
--- a/url/url_canon_unittest.cc
+++ b/url/url_canon_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/gtest_util.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/third_party/mozilla/url_parse.h"
@@ -1279,8 +1280,8 @@
     // 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},
-    // Invalid characters that are escaped should cause a failure.
-    {"/foo%00%51", L"/foo%00%51", "/foo%00Q", Component(0, 8), false},
+    // %00 should not cause failures.
+    {"/foo%00%51", L"/foo%00%51", "/foo%00Q", Component(0, 8), 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},
@@ -1386,7 +1387,7 @@
              CanonicalizePath);
 
   // Manual test: embedded NULLs should be escaped and the URL should be marked
-  // as invalid.
+  // as valid.
   const char path_with_null[] = "/ab\0c";
   Component in_comp(0, 5);
   Component out_comp;
@@ -1395,7 +1396,7 @@
   StdStringCanonOutput output(&out_str);
   bool success = CanonicalizePath(path_with_null, in_comp, &output, &out_comp);
   output.Complete();
-  EXPECT_FALSE(success);
+  EXPECT_TRUE(success);
   EXPECT_EQ("/ab%00c", out_str);
 }
 
@@ -2741,4 +2742,27 @@
   output.set_length(0);
 }
 
+TEST(URLCanonTest, UnescapePathCharHistogram) {
+  struct TestCase {
+    gurl_base::StringPiece path;
+    gurl_base::HistogramBase::Count cnt;
+  } cases[] = {
+      {"/a", 0},
+      {"/%61", 1},
+      {"/%61%61", 1},
+  };
+
+  for (const auto& c : cases) {
+    gurl_base::HistogramTester histogram_tester;
+    Component in_comp(0, c.path.size());
+    Component out_comp;
+    std::string out_str;
+    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);
+  }
+}
+
 }  // namespace url
diff --git a/url/url_features.cc b/url/url_features.cc
index 3602bdd..d033755 100644
--- a/url/url_features.cc
+++ b/url/url_features.cc
@@ -18,7 +18,7 @@
 
 BASE_FEATURE(kStrictIPv4EmbeddedIPv6AddressParsing,
              "StrictIPv4EmbeddedIPv6AddressParsing",
-             gurl_base::FEATURE_DISABLED_BY_DEFAULT);
+             gurl_base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Kill switch for crbug.com/1220361.
 BASE_FEATURE(kResolveBareFragmentWithColonOnNonHierarchical,