Update googleurl
Roll up to the Chromium revision 678f1196b00e9e6a384e59a98b94509f71be3cd6
from Tue May 2 15:12:32 2023 +0000.
Change-Id: Ia24c2ac8e8817a739d06b282d2dc4fd8c5aa9b4a
diff --git a/AUTHORS b/AUTHORS
index ac46f9f..d4f7c9d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -39,6 +39,7 @@
Adrian Belgun <adrian.belgun@intel.com>
Adrian Ratiu <adrian.ratiu@collabora.corp-partner.google.com>
Adrià Vilanova Martínez <me@avm99963.com>
+Ahmed Elwasefi <a.m.elwasefi@gmail.com>
Ahmet Emir Ercin <ahmetemiremir@gmail.com>
Ajay Berwal <a.berwal@samsung.com>
Ajay Berwal <ajay.berwal@samsung.com>
@@ -81,6 +82,7 @@
Allan Sandfeld Jensen <allan.jensen@qt.io>
Alper Çakan <alpercakan98@gmail.com>
Alvaro Silva <alvaro.fagner@gmail.com>
+Ambareesh Balaji <ambareeshbalaji@gmail.com>
Ambarish Rapte <ambarish.r@samsung.com>
Amey Jahagirdar <jahagird@amazon.com>
Amit Paul <a.paul@samsung.com>
@@ -126,6 +128,8 @@
Antonin Hildebrand <antonin.hildebrand@gmail.com>
Antonio Gomes <a1.gomes@sisa.samsung.com>
Anuj Kumar Sharma <anujk.sharma@samsung.com>
+Anže Lešnik <anze@lesnik.cc>
+Ao Hui <aohui.wan@gmail.com>
Ao Sun <ntusunao@gmail.com>
Ao Wang <wangao.james@bytedance.com>
Aquibuzzaman Md. Sayem <md.sayem@samsung.com>
@@ -137,6 +141,7 @@
Arnaud Renevier <a.renevier@samsung.com>
Arpita Bahuguna <a.bah@samsung.com>
Arthur Lussos <developer0420@gmail.com>
+Artin Lindqvist <artin.lindqvist.chromium@gmail.com>
Artur Akerberg <artur.aker@gmail.com>
Arun Kulkarni <kulkarni.a@samsung.com>
Arun Kumar <arun87.kumar@samsung.com>
@@ -177,6 +182,7 @@
Bin Miao <bin.miao@intel.com>
Boaz Sender <boaz@bocoup.com>
Bobby Powers <bobbypowers@gmail.com>
+Bradley Needham <bradley.needham@sony.com>
Branden Archer <bma4@zips.uakron.edu>
Brendan Kirby <brendan.kirby@imgtec.com>
Brendan Long <self@brendanlong.com>
@@ -221,6 +227,7 @@
Changbin Shao <changbin.shao@intel.com>
Changjun Yang <changjun.yang@intel.com>
ChangSeok Lee <charlie.lee921@gmail.com>
+ChangSeok Oh <changseok.oh@bytedance.com>
ChangSeok Oh <shivamidow@gmail.com>
Changwan Hong <changwan.hong@navercorp.com>
Changyeon Kim <cyzero.kim@samsung.com>
@@ -234,6 +241,7 @@
Cheng Yu <yuzichengcode@gmail.com>
Choongwoo Han <cwhan.tunz@gmail.com>
Choudhury M. Shamsujjoha <choudhury.s@samsung.com>
+Chris Dalton <chris@rive.app>
Chris Greene <cwgreene@amazon.com>
Chris Harrelson <chrishtr@gmail.com>
Chris Nardi <hichris123@gmail.com>
@@ -278,6 +286,7 @@
Dániel Vince <vinced@inf.u-szeged.hu>
Daniil Suvorov <severecloud@gmail.com>
Danny Weiss <danny.weiss.fr@gmail.com>
+Danylo Boiko <danielboyko02@gmail.com>
Daoming Qiu <daoming.qiu@intel.com>
Darik Harter <darik.harter@gmail.com>
Darshan Sen <raisinten@gmail.com>
@@ -299,6 +308,7 @@
David Spellman <dspell@amazon.com>
David Valachovic <adenflorian@gmail.com>
Dax Kelson <dkelson@gurulabs.com>
+Debadree Chatterjee <debadree333@gmail.com>
Debashish Samantaray <d.samantaray@samsung.com>
Debug Wang <debugwang@tencent.com>
Deepak Dilip Borade <deepak.db@samsung.com>
@@ -351,6 +361,7 @@
Ehsan Akhgari <ehsan.akhgari@gmail.com>
Ehsan Akhgari <ehsan@mightyapp.com>
Elan Ruusamäe <elan.ruusamae@gmail.com>
+Ely Ronnen <elyronnen@gmail.com>
Emil Suleymanov <emil@esnx.xyz>
Ergun Erdogmus <erdogmusergun@gmail.com>
Eric Ahn <byungwook.ahn@gmail.com>
@@ -373,6 +384,7 @@
Evgeny Agafonchikov <evgeny.agafonchikov@akvelon.com>
Fabian Henneke <fabian.henneke@gmail.com>
Fabien Tassin <fta@sofaraway.org>
+Fan Wen <fan.wen.dev@gmail.com>
Feifei Wang <alexswang@tencent.com>
Felipe Erias Morandeira <felipeerias@gmail.com>
Felix H. Dahlke <fhd@ubercode.de>
@@ -449,6 +461,7 @@
Heeyoun Lee <heeyoun.lee@samsung.com>
Henrique de Carvalho <decarv.henrique@gmail.com>
Henrique Limas <henrique.ramos.limas@gmail.com>
+Hikari Fujimoto <hikari.p.fujimoto@gmail.com>
Himanshu Joshi <h.joshi@samsung.com>
Himanshu Nayak <himanshu.nayak@amd.corp-partner.google.com>
Hiroki Oshima <hiroki.oshima@gmail.com>
@@ -463,6 +476,7 @@
Hosung You <hosung.you@samsung.com>
Huapeng Li <huapengl@amazon.com>
Huayong Xu <huayong.xu@samsung.com>
+Hung Ngo <ngotienhung195@gmail.com>
Hugo Holgersson <hugo.holgersson@sonymobile.com>
Hui Wang <wanghui07050707@gmail.com>
Hui Wang <wanghui210@huawei.com>
@@ -502,6 +516,7 @@
Ivan Pavlotskiy <ivan.pavlotskiy@lgepartner.com>
Ivan Sham <ivansham@amazon.com>
Jack Bates <jack@nottheoilrig.com>
+Jackson Loeffler <j@jloeffler.com>
Jacky Hu <flameddd@gmail.com>
Jacob Clark <jacob.jh.clark@googlemail.com>
Jacob Mandelson <jacob@mandelson.org>
@@ -569,6 +584,7 @@
Jianjun Zhu <jianjun.zhu@intel.com>
Jianneng Zhong <muzuiget@gmail.com>
Jiawei Shao <jiawei.shao@intel.com>
+Jiawei Chen <jiawei.chen@dolby.com>
Jiaxun Wei <leuisken@gmail.com>
Jiaxun Yang <jiaxun.yang@flygoat.com>
Jidong Qin <qinjidong@qianxin.com>
@@ -601,6 +617,7 @@
Joel Stanley <joel@jms.id.au>
Joey Jiao <joeyjiao0810@gmail.com>
Joey Mou <joeymou@amazon.com>
+Johann <johann@duck.com>
Johannes Rudolph <johannes.rudolph@googlemail.com>
John Ingve Olsen <johningveolsen@gmail.com>
John Kleinschmidt <kleinschmidtorama@gmail.com>
@@ -643,6 +660,7 @@
Julien Racle <jracle@logitech.com>
Jun Fang <jun_fang@foxitsoftware.com>
Jun Jiang <jun.a.jiang@intel.com>
+Junbong Eom <jb.eom@samsung.com>
Jungchang Park <valley84265@gmail.com>
Junchao Han <junchao.han@intel.com>
Junghoon Lee <sjh836@gmail.com>
@@ -741,8 +759,12 @@
Leung Wing Chung <lwchkg@gmail.com>
Li Yanbo <liyanbo.monster@bytedance.com>
Li Yin <li.yin@intel.com>
+Lian Ruilong <lianrl@dingdao.com>
+Lian Ruilong <lianruilong1108@gmail.com>
Lidwine Genevet <lgenevet@cisco.com>
+Lin Guo <sinyu890807@gmail.com>
Lin Sun <lin.sun@intel.com>
+Lin Peng <penglin220@gmail.com>
Lin Peng <penglin22@huawei.com>
Lingqi Chi <someway.bit@gmail.com>
Lingyun Cai <lingyun.cai@intel.com>
@@ -761,7 +783,8 @@
Lukas Lihotzki <lukas@lihotzki.de>
Lukasz Krakowiak <lukasz.krakowiak@mobica.com>
Luke Inman-Semerau <luke.semerau@gmail.com>
-Luke Seunghoe Gu <gulukesh@gmail.com>
+Luke Gu <gulukesh@gmail.com>
+Luke Warlow <luke@warlow.dev>
Luke Zarko <lukezarko@gmail.com>
Luoxi Pan <l.panpax@gmail.com>
Lu Yahan <yahan@iscas.ac.cn>
@@ -771,6 +794,7 @@
Magnus Danielsson <fuzzac@gmail.com>
Mahesh Kulkarni <mahesh.kk@samsung.com>
Mahesh Machavolu <mahesh.ma@samsung.com>
+Mahmoud Ahmed <mahmoudaahmedd@gmail.com>
Maksim Kolesin <mkolesin@gmail.com>
Maksim Sisov <maksim.sisov@intel.com>
Malcolm Wang <malcolm.2.wang@gmail.com>
@@ -780,10 +804,13 @@
Manojkumar Bhosale <manojkumar.bhosale@imgtec.com>
Manuel Braun <thembrown@gmail.com>
Manuel Lagana <manuel.lagana.dev@gmail.com>
+Manuel Palenzuela Merino <manuelpalenzuelamerino@gmail.com>
Mao Yujie <maojie0924@gmail.com>
Mao Yujie <yujie.mao@intel.com>
Marc des Garets <marc.desgarets@googlemail.com>
+Marcio Caroso <msscaroso@gmail.com>
Marcin Wiacek <marcin@mwiacek.com>
+Marco Monaco <marco.monaco@ocado.com>
Marco Rodrigues <gothicx@gmail.com>
Marcos Caceres <marcos@marcosc.com>
Marek Behún <kabel@kernel.org>
@@ -918,6 +945,7 @@
Nolan Cao <nolan.robin.cao@gmail.com>
Oleksii Kadurin <ovkadurin@gmail.com>
Oliver Dunk <oliver@oliverdunk.com>
+Olivier Tilloy <olivier+chromium@tilloy.net>
Olli Raula (Old name Olli Syrjälä) <olli.raula@intel.com>
Omar Sandoval <osandov@osandov.com>
Owen Yuwono <owenyuwono@gmail.com>
@@ -1065,6 +1093,7 @@
Sajal Khandelwal <skhandelwa22@bloomberg.net>
Saksham Mittal <gotlouemail@gmail.com>
Salvatore Iovene <salvatore.iovene@intel.com>
+Sam James <sam@gentoo.org>
Sam Larison <qufighter@gmail.com>
Sam McDonald <sam@sammcd.com>
Samuel Attard <samuel.r.attard@gmail.com>
@@ -1286,6 +1315,7 @@
Vipul Bhasin <vipul.bhasin@gmail.com>
Visa Putkinen <v.putkinen@partner.samsung.com>
Vishal Bhatnagar <vishal.b@samsung.com>
+Vishal Lingam <vishal.reddy@samsung.com>
Vitaliy Kharin <kvserr@gmail.com>
Vivek Galatage <vivek.vg@samsung.com>
Volker Sorge <volker.sorge@gmail.com>
@@ -1293,6 +1323,7 @@
wafuwafu13 <mariobaske@i.softbank.jp>
Wojciech Bielawski <wojciech.bielawski@gmail.com>
Wang Weiwei <wangww@dingdao.com>
+Wangyang Dai <jludwy@gmail.com>
Wanming Lin <wanming.lin@intel.com>
Wei Li <wei.c.li@intel.com>
Wen Fan <fanwen1@huawei.com>
@@ -1300,6 +1331,7 @@
WenSheng He <wensheng.he@samsung.com>
Wesley Lancel <wesleylancel@gmail.com>
Wei Wang <wei4.wang@intel.com>
+Wei Wen <wenwei.wenwei@bytedance.com>
Wesley Wigham <wwigham@gmail.com>
Will Cohen <wwcohen@gmail.com>
Will Hirsch <chromium@willhirsch.co.uk>
diff --git a/base/compiler_specific.h b/base/compiler_specific.h
index 8085338..b2d4024 100644
--- a/base/compiler_specific.h
+++ b/base/compiler_specific.h
@@ -41,7 +41,9 @@
// Annotate a function indicating it should not be inlined.
// Use like:
// NOINLINE void DoStuff() { ... }
-#if defined(COMPILER_GCC) || defined(__clang__)
+#if defined(__clang__) && HAS_ATTRIBUTE(noinline)
+#define NOINLINE [[clang::noinline]]
+#elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(noinline)
#define NOINLINE __attribute__((noinline))
#elif defined(COMPILER_MSVC)
#define NOINLINE __declspec(noinline)
@@ -49,7 +51,9 @@
#define NOINLINE
#endif
-#if defined(COMPILER_GCC) && defined(NDEBUG)
+#if defined(__clang__) && defined(NDEBUG) && HAS_ATTRIBUTE(always_inline)
+#define ALWAYS_INLINE [[clang::always_inline]] inline
+#elif defined(COMPILER_GCC) && defined(NDEBUG) && HAS_ATTRIBUTE(always_inline)
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
#elif defined(COMPILER_MSVC) && defined(NDEBUG)
#define ALWAYS_INLINE __forceinline
@@ -66,7 +70,7 @@
// Use like:
// NOT_TAIL_CALLED void FooBar();
#if defined(__clang__) && HAS_ATTRIBUTE(not_tail_called)
-#define NOT_TAIL_CALLED __attribute__((not_tail_called))
+#define NOT_TAIL_CALLED [[clang::not_tail_called]]
#else
#define NOT_TAIL_CALLED
#endif
@@ -78,23 +82,14 @@
//
// In most places you can use the C++11 keyword "alignas", which is preferred.
//
-// But compilers have trouble mixing __attribute__((...)) syntax with
-// alignas(...) syntax.
-//
-// Doesn't work in clang or gcc:
-// struct alignas(16) __attribute__((packed)) S { char c; };
-// Works in clang but not gcc:
-// struct __attribute__((packed)) alignas(16) S2 { char c; };
-// Works in clang and gcc:
-// struct alignas(16) S3 { char c; } __attribute__((packed));
-//
-// There are also some attributes that must be specified *before* a class
-// definition: visibility (used for exporting functions/classes) is one of
-// these attributes. This means that it is not possible to use alignas() with a
-// class that is marked as exported.
-#if defined(COMPILER_MSVC)
+// Historically, compilers had trouble mixing __attribute__((...)) syntax with
+// alignas(...) syntax. However, at least Clang is very accepting nowadays. It
+// may be that this macro can be removed entirely.
+#if defined(__clang__)
+#define ALIGNAS(byte_alignment) alignas(byte_alignment)
+#elif defined(COMPILER_MSVC)
#define ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
-#elif defined(COMPILER_GCC)
+#elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(aligned)
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#endif
@@ -112,13 +107,13 @@
#define NO_UNIQUE_ADDRESS
#endif
-// Tell the compiler a function is using a printf-style format string.
+// Tells the compiler a function is using a printf-style format string.
// |format_param| is the one-based index of the format string parameter;
// |dots_param| is the one-based index of the "..." parameter.
// For v*printf functions (which take a va_list), pass 0 for dots_param.
// (This is undocumented but matches what the system C headers do.)
// For member functions, the implicit this parameter counts as index 1.
-#if defined(COMPILER_GCC) || defined(__clang__)
+#if (defined(COMPILER_GCC) || defined(__clang__)) && HAS_ATTRIBUTE(format)
#define PRINTF_FORMAT(format_param, dots_param) \
__attribute__((format(printf, format_param, dots_param)))
#else
@@ -163,7 +158,7 @@
// DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons.
#if !defined(DISABLE_CFI_PERF)
#if defined(__clang__) && defined(OFFICIAL_BUILD)
-#define DISABLE_CFI_PERF __attribute__((no_sanitize("cfi")))
+#define DISABLE_CFI_PERF NO_SANITIZE("cfi")
#else
#define DISABLE_CFI_PERF
#endif
@@ -290,7 +285,7 @@
// please document the problem for someone who is going to cleanup it later.
// E.g. platform, bot, benchmark or test name in patch description or next to
// the attribute.
-#define STACK_UNINITIALIZED __attribute__((uninitialized))
+#define STACK_UNINITIALIZED [[clang::uninitialized]]
#else
#define STACK_UNINITIALIZED
#endif
diff --git a/base/containers/span.h b/base/containers/span.h
index 1496611..578f3b6 100644
--- a/base/containers/span.h
+++ b/base/containers/span.h
@@ -6,6 +6,7 @@
#define BASE_CONTAINERS_SPAN_H_
#include <stddef.h>
+#include <stdint.h>
#include <array>
#include <iterator>
@@ -242,7 +243,9 @@
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = T*;
+ using const_pointer = const T*;
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.
diff --git a/base/strings/abseil_string_conversions.cc b/base/strings/abseil_string_conversions.cc
deleted file mode 100644
index 6a12c0c..0000000
--- a/base/strings/abseil_string_conversions.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/strings/abseil_string_conversions.h"
-
-#include <vector>
-
-#include "base/containers/span.h"
-#include "base/ranges/algorithm.h"
-#include "base/strings/string_piece.h"
-#include "absl/strings/string_view.h"
-
-namespace gurl_base {
-
-std::vector<absl::string_view> StringPiecesToStringViews(
- span<const StringPiece> pieces) {
- std::vector<absl::string_view> views(pieces.size());
- ranges::transform(pieces, views.begin(), &StringPieceToStringView);
- return views;
-}
-
-std::vector<StringPiece> StringViewsToStringPieces(
- span<const absl::string_view> views) {
- std::vector<StringPiece> pieces(views.size());
- ranges::transform(views, pieces.begin(), &StringViewToStringPiece);
- return pieces;
-}
-
-} // namespace base
diff --git a/base/strings/abseil_string_conversions.h b/base/strings/abseil_string_conversions.h
deleted file mode 100644
index ffb0688..0000000
--- a/base/strings/abseil_string_conversions.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_STRINGS_ABSEIL_STRING_CONVERSIONS_H_
-#define BASE_STRINGS_ABSEIL_STRING_CONVERSIONS_H_
-
-#include <vector>
-
-#include "polyfills/base/base_export.h"
-#include "base/containers/span.h"
-#include "base/strings/string_piece.h"
-#include "absl/strings/string_view.h"
-
-namespace gurl_base {
-
-// Converts `piece` to a string view, pointing to the same piece of memory.
-constexpr absl::string_view StringPieceToStringView(StringPiece piece) {
- return {piece.data(), piece.size()};
-}
-
-// Converts `view` to a string piece, pointing to the same piece of memory.
-constexpr StringPiece StringViewToStringPiece(absl::string_view view) {
- return {view.data(), view.size()};
-}
-
-// Converts `pieces` to string views, pointing to the same piece of memory.
-BASE_EXPORT std::vector<absl::string_view> StringPiecesToStringViews(
- span<const StringPiece> pieces);
-
-// Converts `views` to string pieces, pointing to the same piece of memory.
-BASE_EXPORT std::vector<StringPiece> StringViewsToStringPieces(
- span<const absl::string_view> views);
-
-} // namespace base
-
-#endif // BASE_STRINGS_ABSEIL_STRING_CONVERSIONS_H_
diff --git a/base/strings/abseil_string_conversions_unittest.cc b/base/strings/abseil_string_conversions_unittest.cc
deleted file mode 100644
index 3744035..0000000
--- a/base/strings/abseil_string_conversions_unittest.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/strings/abseil_string_conversions.h"
-
-#include <vector>
-
-#include "base/containers/span.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_piece_forward.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "absl/strings/string_view.h"
-
-namespace gurl_base {
-
-namespace {
-using string_view = absl::string_view;
-} // namespace
-
-TEST(AbseilStringConversionsTest, StringPieceToStringView) {
- static constexpr StringPiece kPiece = "foo";
- static constexpr string_view kView = StringPieceToStringView(kPiece);
- static_assert(kPiece.data() == kView.data(), "");
- static_assert(kPiece.size() == kView.size(), "");
-}
-
-TEST(AbseilStringConversionsTest, StringViewToStringPiece) {
- static constexpr string_view kView = "bar";
- static constexpr StringPiece kPiece = StringViewToStringPiece(kView);
- static_assert(kView.data() == kPiece.data(), "");
- static_assert(kView.size() == kPiece.size(), "");
-}
-
-TEST(AbseilStringConversionsTest, StringPiecesToStringViews) {
- static constexpr StringPiece kFoo = "foo";
- static constexpr StringPiece kBar = "bar";
- static constexpr StringPiece kBaz = "baz";
-
- const std::vector<StringPiece> kPieces = {kFoo, kBar, kBaz};
- const std::vector<string_view> kViews = StringPiecesToStringViews(kPieces);
-
- ASSERT_EQ(kViews.size(), 3u);
- EXPECT_EQ(kViews[0].data(), kFoo);
- EXPECT_EQ(kViews[0].size(), 3u);
- EXPECT_EQ(kViews[1].data(), kBar);
- EXPECT_EQ(kViews[1].size(), 3u);
- EXPECT_EQ(kViews[2].data(), kBaz);
- EXPECT_EQ(kViews[2].size(), 3u);
-}
-
-TEST(AbseilStringConversionsTest, StringViewsToStringPieces) {
- static constexpr string_view kFoo = "foo";
- static constexpr string_view kBar = "bar";
- static constexpr string_view kBaz = "baz";
-
- const std::vector<string_view> kViews = {kFoo, kBar, kBaz};
- const std::vector<StringPiece> kPieces = StringViewsToStringPieces(kViews);
-
- ASSERT_EQ(kPieces.size(), 3u);
- EXPECT_EQ(kPieces[0].data(), kFoo);
- EXPECT_EQ(kPieces[0].size(), 3u);
- EXPECT_EQ(kPieces[1].data(), kBar);
- EXPECT_EQ(kPieces[1].size(), 3u);
- EXPECT_EQ(kPieces[2].data(), kBaz);
- EXPECT_EQ(kPieces[2].size(), 3u);
-}
-
-} // namespace base
diff --git a/base/strings/escape.cc b/base/strings/escape.cc
index 867e04b..7a3d701 100644
--- a/base/strings/escape.cc
+++ b/base/strings/escape.cc
@@ -543,9 +543,20 @@
GURL_DCHECK(!(rules &
~(UnescapeRule::NORMAL | UnescapeRule::REPLACE_PLUS_WITH_SPACE)));
+ // It is not possible to read the feature state when this function is invoked
+ // before FeatureList initialization. In that case, fallback to the feature's
+ // default state.
+ //
+ // TODO(crbug.com/1321924): Cleanup this feature.
+ const bool optimize_data_urls_feature_is_enabled =
+ gurl_base::FeatureList::GetInstance()
+ ? gurl_base::FeatureList::IsEnabled(features::kOptimizeDataUrls)
+ : features::kOptimizeDataUrls.default_state ==
+ gurl_base::FEATURE_ENABLED_BY_DEFAULT;
+
// 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) &&
+ if (optimize_data_urls_feature_is_enabled &&
escaped_text.find('%') == StringPiece::npos) {
std::string unescaped_text(escaped_text);
if (rules & UnescapeRule::REPLACE_PLUS_WITH_SPACE)
diff --git a/base/strings/safe_sprintf.cc b/base/strings/safe_sprintf.cc
index f30360b..690abc9 100644
--- a/base/strings/safe_sprintf.cc
+++ b/base/strings/safe_sprintf.cc
@@ -268,7 +268,7 @@
}
// User-provided buffer that will receive the fully formatted output string.
- raw_ptr<char> buffer_;
+ raw_ptr<char, AllowPtrArithmetic> buffer_;
// Number of bytes that are available in the buffer excluding the trailing
// NUL byte that will be added by the destructor.
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index fe524df..d5f51ad 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -22,11 +22,13 @@
#define BASE_STRINGS_STRING_PIECE_H_
#include <stddef.h>
+#include <stdint.h>
#include <algorithm>
#include <iosfwd>
#include <limits>
#include <string>
+#include <string_view>
#include <type_traits>
#include "polyfills/base/base_export.h"
@@ -34,7 +36,6 @@
#include "polyfills/base/check_op.h"
#include "base/compiler_specific.h"
#include "base/cxx20_is_constant_evaluated.h"
-#include "base/numerics/safe_math.h"
#include "base/strings/string_piece_forward.h" // IWYU pragma: export
#include "build/build_config.h"
@@ -118,8 +119,14 @@
constexpr BasicStringPiece(const BasicStringPiece& other) noexcept = default;
constexpr BasicStringPiece& operator=(const BasicStringPiece& view) noexcept =
default;
- constexpr BasicStringPiece(const CharT* s, CheckedNumeric<size_t> count)
- : ptr_(s), length_(count.ValueOrDie()) {}
+ constexpr BasicStringPiece(const CharT* s, size_t count)
+ : ptr_(s), length_(count) {
+ // Intentional STL deviation: Check the string length fits in
+ // `difference_type`. No valid buffer can exceed this type, otherwise
+ // pointer arithmetic would not be defined. This helps avoid bugs where
+ // `count` was computed from an underflow or negative sentinel value.
+ GURL_CHECK(length_ <= size_t{PTRDIFF_MAX});
+ }
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr BasicStringPiece(const CharT* s)
: ptr_(s), length_(s ? traits_type::length(s) : 0) {
@@ -132,6 +139,7 @@
// `BasicStringPiece(nullptr_t) = delete`, but unfortunately the terse form is
// not supported by the PNaCl toolchain.
template <class T, class = std::enable_if_t<std::is_null_pointer<T>::value>>
+ // NOLINTNEXTLINE(google-explicit-constructor)
BasicStringPiece(T) {
static_assert(sizeof(T) == 0, // Always false.
"StringPiece does not support construction from nullptr, use "
@@ -142,12 +150,25 @@
// (an object convertible to) a std::basic_string_view, as well as an explicit
// cast operator to a std::basic_string_view, but (obviously) not from/to a
// BasicStringPiece.
+ // NOLINTNEXTLINE(google-explicit-constructor)
BasicStringPiece(const std::basic_string<CharT>& str)
: ptr_(str.data()), length_(str.size()) {}
explicit operator std::basic_string<CharT>() const {
return std::basic_string<CharT>(data(), size());
}
+ // Provide implicit conversions from/to the STL version, for interoperability
+ // with non-Chromium code.
+ // TODO(crbug.com/691162): These will be moot when BasicStringPiece is
+ // replaced with std::basic_string_view.
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ constexpr BasicStringPiece(std::basic_string_view<CharT> str)
+ : ptr_(str.data()), length_(str.size()) {}
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ constexpr operator std::basic_string_view<CharT>() const {
+ return std::basic_string_view<CharT>(data(), size());
+ }
+
constexpr const_iterator begin() const noexcept { return ptr_; }
constexpr const_iterator cbegin() const noexcept { return ptr_; }
constexpr const_iterator end() const noexcept { return ptr_ + length_; }
@@ -607,6 +628,8 @@
// Stand-ins for the STL's std::hash<> specializations.
template <typename StringPieceType>
struct StringPieceHashImpl {
+ using is_transparent = void; // to allow for heterogenous lookup
+
// 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.
diff --git a/base/strings/string_piece_rust.h b/base/strings/string_piece_rust.h
index ff08c34..135b3df 100644
--- a/base/strings/string_piece_rust.h
+++ b/base/strings/string_piece_rust.h
@@ -5,14 +5,14 @@
#ifndef BASE_STRINGS_STRING_PIECE_RUST_H_
#define BASE_STRINGS_STRING_PIECE_RUST_H_
-#include "build/rust/rust_buildflags.h"
+#include "base/rust_buildflags.h"
-#if BUILDFLAG(TOOLCHAIN_HAS_RUST)
+#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"
+#include "third_party/rust/cxx/v1/crate/include/cxx.h" // nogncheck
namespace gurl_base {
@@ -39,6 +39,6 @@
} // namespace base
-#endif // BUILDFLAG(TOOLCHAIN_HAS_RUST)
+#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 2f8db6c..a5edcbd 100644
--- a/base/strings/string_piece_rust_unittest.cc
+++ b/base/strings/string_piece_rust_unittest.cc
@@ -3,11 +3,11 @@
// found in the LICENSE file.
#include "base/strings/string_piece_rust.h"
-#include "build/rust/rust_buildflags.h"
+#include "base/rust_buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if BUILDFLAG(TOOLCHAIN_HAS_RUST)
+#if BUILDFLAG(BUILD_RUST_BASE_CONVERSIONS)
namespace gurl_base {
namespace {
@@ -32,4 +32,4 @@
} // namespace
} // namespace base
-#endif // BUILDFLAG(TOOLCHAIN_HAS_RUST)
+#endif // BUILDFLAG(BUILD_RUST_BASE_CONVERSIONS)
diff --git a/base/strings/string_piece_unittest.cc b/base/strings/string_piece_unittest.cc
index 9cd9b3f..35ea795 100644
--- a/base/strings/string_piece_unittest.cc
+++ b/base/strings/string_piece_unittest.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <string>
+#include <string_view>
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
@@ -893,4 +894,19 @@
static_assert(foobar.find_last_not_of("ox", 2) == 0, "");
}
+// Test that `gurl_base::StringPiece` and `std::string_view` are interoperable.
+TEST(StringPieceTest, StringPieceToStringView) {
+ constexpr StringPiece kPiece = "foo";
+ constexpr std::string_view kView = kPiece;
+ static_assert(kPiece.data() == kView.data());
+ static_assert(kPiece.size() == kView.size());
+}
+
+TEST(StringPieceTest, StringViewToStringPiece) {
+ constexpr std::string_view kView = "bar";
+ constexpr StringPiece kPiece = kView;
+ static_assert(kView.data() == kPiece.data());
+ static_assert(kView.size() == kPiece.size());
+}
+
} // namespace base
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index f345244..4a7638b 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -433,6 +433,11 @@
size_t strlcpy(char* dst, const char* src, size_t dst_size) {
return internal::lcpyT(dst, src, dst_size);
}
+
+size_t u16cstrlcpy(char16_t* dst, const char16_t* src, size_t dst_size) {
+ return internal::lcpyT(dst, src, dst_size);
+}
+
size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) {
return internal::lcpyT(dst, src, dst_size);
}
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 48d3fac..082e42d 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -13,7 +13,6 @@
#include <stdint.h>
#include <initializer_list>
-#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
@@ -61,6 +60,9 @@
// If the return value is >= dst_size, then the output was truncated.
// NOTE: All sizes are in number of characters, NOT in bytes.
BASE_EXPORT size_t strlcpy(char* dst, const char* src, size_t dst_size);
+BASE_EXPORT size_t u16cstrlcpy(char16_t* dst,
+ const char16_t* src,
+ size_t dst_size);
BASE_EXPORT size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
// Scan a wprintf format string to determine whether it's portable across a
@@ -111,14 +113,6 @@
return MakeBasicStringPiece<wchar_t>(begin, end);
}
-// Convert a type with defined `operator<<` into a string.
-template <typename... Streamable>
-std::string StreamableToString(const Streamable&... values) {
- std::ostringstream ss;
- (ss << ... << values);
- return ss.str();
-}
-
// ASCII-specific tolower. The standard library's tolower is locale sensitive,
// so we don't want to use it here.
template <typename CharT,
diff --git a/base/strings/string_util_unittest.cc b/base/strings/string_util_unittest.cc
index e15358f..988344d 100644
--- a/base/strings/string_util_unittest.cc
+++ b/base/strings/string_util_unittest.cc
@@ -24,43 +24,43 @@
namespace gurl_base {
-static const struct trim_case {
+namespace {
+
+const struct trim_case {
const wchar_t* input;
const TrimPositions positions;
const wchar_t* output;
const TrimPositions return_value;
} trim_cases[] = {
- {L" Google Video ", TRIM_LEADING, L"Google Video ", TRIM_LEADING},
- {L" Google Video ", TRIM_TRAILING, L" Google Video", TRIM_TRAILING},
- {L" Google Video ", TRIM_ALL, L"Google Video", TRIM_ALL},
- {L"Google Video", TRIM_ALL, L"Google Video", TRIM_NONE},
- {L"", TRIM_ALL, L"", TRIM_NONE},
- {L" ", TRIM_LEADING, L"", TRIM_LEADING},
- {L" ", TRIM_TRAILING, L"", TRIM_TRAILING},
- {L" ", TRIM_ALL, L"", TRIM_ALL},
- {L"\t\rTest String\n", TRIM_ALL, L"Test String", TRIM_ALL},
- {L"\x2002Test String\x00A0\x3000", TRIM_ALL, L"Test String", TRIM_ALL},
+ {L" Google Video ", TRIM_LEADING, L"Google Video ", TRIM_LEADING},
+ {L" Google Video ", TRIM_TRAILING, L" Google Video", TRIM_TRAILING},
+ {L" Google Video ", TRIM_ALL, L"Google Video", TRIM_ALL},
+ {L"Google Video", TRIM_ALL, L"Google Video", TRIM_NONE},
+ {L"", TRIM_ALL, L"", TRIM_NONE},
+ {L" ", TRIM_LEADING, L"", TRIM_LEADING},
+ {L" ", TRIM_TRAILING, L"", TRIM_TRAILING},
+ {L" ", TRIM_ALL, L"", TRIM_ALL},
+ {L"\t\rTest String\n", TRIM_ALL, L"Test String", TRIM_ALL},
+ {L"\x2002Test String\x00A0\x3000", TRIM_ALL, L"Test String", TRIM_ALL},
};
-static const struct trim_case_ascii {
+const struct trim_case_ascii {
const char* input;
const TrimPositions positions;
const char* output;
const TrimPositions return_value;
} trim_cases_ascii[] = {
- {" Google Video ", TRIM_LEADING, "Google Video ", TRIM_LEADING},
- {" Google Video ", TRIM_TRAILING, " Google Video", TRIM_TRAILING},
- {" Google Video ", TRIM_ALL, "Google Video", TRIM_ALL},
- {"Google Video", TRIM_ALL, "Google Video", TRIM_NONE},
- {"", TRIM_ALL, "", TRIM_NONE},
- {" ", TRIM_LEADING, "", TRIM_LEADING},
- {" ", TRIM_TRAILING, "", TRIM_TRAILING},
- {" ", TRIM_ALL, "", TRIM_ALL},
- {"\t\rTest String\n", TRIM_ALL, "Test String", TRIM_ALL},
+ {" Google Video ", TRIM_LEADING, "Google Video ", TRIM_LEADING},
+ {" Google Video ", TRIM_TRAILING, " Google Video", TRIM_TRAILING},
+ {" Google Video ", TRIM_ALL, "Google Video", TRIM_ALL},
+ {"Google Video", TRIM_ALL, "Google Video", TRIM_NONE},
+ {"", TRIM_ALL, "", TRIM_NONE},
+ {" ", TRIM_LEADING, "", TRIM_LEADING},
+ {" ", TRIM_TRAILING, "", TRIM_TRAILING},
+ {" ", TRIM_ALL, "", TRIM_ALL},
+ {"\t\rTest String\n", TRIM_ALL, "Test String", TRIM_ALL},
};
-namespace {
-
// Helper used to test TruncateUTF8ToByteSize.
bool Truncated(const std::string& input,
const size_t byte_size,
@@ -72,7 +72,7 @@
using TestFunction = bool (*)(StringPiece str);
-// Helper used to test IsStringUTF8{,AllowingNoncharacters}.
+// Helper used to test IsStringUTF8[AllowingNoncharacters].
void TestStructurallyValidUtf8(TestFunction fn) {
EXPECT_TRUE(fn("abc"));
EXPECT_TRUE(fn("\xC2\x81"));
@@ -92,7 +92,7 @@
EXPECT_TRUE(fn(kEmbeddedNull));
}
-// Helper used to test IsStringUTF8{,AllowingNoncharacters}.
+// Helper used to test IsStringUTF8[AllowingNoncharacters].
void TestStructurallyInvalidUtf8(TestFunction fn) {
// Invalid encoding of U+1FFFE (0x8F instead of 0x9F)
EXPECT_FALSE(fn("\xF0\x8F\xBF\xBE"));
@@ -151,7 +151,7 @@
EXPECT_FALSE(fn(kUtf32LeBom));
}
-// Helper used to test IsStringUTF8{,AllowingNoncharacters}.
+// Helper used to test IsStringUTF8[AllowingNoncharacters].
void TestNoncharacters(TestFunction fn, bool expected_result) {
EXPECT_EQ(fn("\xEF\xB7\x90"), expected_result); // U+FDD0
EXPECT_EQ(fn("\xEF\xB7\x9F"), expected_result); // U+FDDF
@@ -192,8 +192,6 @@
EXPECT_EQ(fn("\xF4\x8F\xBF\xBF"), expected_result); // U+10FFFF
}
-} // namespace
-
TEST(StringUtilTest, TruncateUTF8ToByteSize) {
std::string output;
@@ -1214,21 +1212,28 @@
// Test the normal case where we fit in our buffer.
{
char dst[10];
+ char16_t u16dst[10];
wchar_t wdst[10];
EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
- EXPECT_EQ(0, memcmp(dst, "abcdefg", 8));
+ EXPECT_EQ(0, memcmp(dst, "abcdefg", sizeof(dst[0]) * 8));
+ EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
+ EXPECT_EQ(0, memcmp(u16dst, u"abcdefg", sizeof(u16dst[0]) * 8));
EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
- EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wchar_t) * 8));
+ EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wdst[0]) * 8));
}
// Test dst_size == 0, nothing should be written to |dst| and we should
// have the equivalent of strlen(src).
{
char dst[2] = {1, 2};
+ char16_t u16dst[2] = {1, 2};
wchar_t wdst[2] = {1, 2};
EXPECT_EQ(7U, strlcpy(dst, "abcdefg", 0));
EXPECT_EQ(1, dst[0]);
EXPECT_EQ(2, dst[1]);
+ EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", 0));
+ EXPECT_EQ(char16_t{1}, u16dst[0]);
+ EXPECT_EQ(char16_t{2}, u16dst[1]);
EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", 0));
EXPECT_EQ(static_cast<wchar_t>(1), wdst[0]);
EXPECT_EQ(static_cast<wchar_t>(2), wdst[1]);
@@ -1237,31 +1242,40 @@
// Test the case were we _just_ competely fit including the null.
{
char dst[8];
+ char16_t u16dst[8];
wchar_t wdst[8];
EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
EXPECT_EQ(0, memcmp(dst, "abcdefg", 8));
+ EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
+ EXPECT_EQ(0, memcmp(u16dst, u"abcdefg", sizeof(u16dst)));
EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
- EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wchar_t) * 8));
+ EXPECT_EQ(0, memcmp(wdst, L"abcdefg", sizeof(wdst)));
}
// Test the case were we we are one smaller, so we can't fit the null.
{
char dst[7];
+ char16_t u16dst[7];
wchar_t wdst[7];
EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
- EXPECT_EQ(0, memcmp(dst, "abcdef", 7));
+ EXPECT_EQ(0, memcmp(dst, "abcdef", sizeof(dst[0]) * 7));
+ EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
+ EXPECT_EQ(0, memcmp(u16dst, u"abcdef", sizeof(u16dst[0]) * 7));
EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
- EXPECT_EQ(0, memcmp(wdst, L"abcdef", sizeof(wchar_t) * 7));
+ EXPECT_EQ(0, memcmp(wdst, L"abcdef", sizeof(wdst[0]) * 7));
}
// Test the case were we are just too small.
{
char dst[3];
+ char16_t u16dst[3];
wchar_t wdst[3];
EXPECT_EQ(7U, strlcpy(dst, "abcdefg", std::size(dst)));
- EXPECT_EQ(0, memcmp(dst, "ab", 3));
+ EXPECT_EQ(0, memcmp(dst, "ab", sizeof(dst)));
+ EXPECT_EQ(7U, u16cstrlcpy(u16dst, u"abcdefg", std::size(u16dst)));
+ EXPECT_EQ(0, memcmp(u16dst, u"ab", sizeof(u16dst)));
EXPECT_EQ(7U, wcslcpy(wdst, L"abcdefg", std::size(wdst)));
- EXPECT_EQ(0, memcmp(wdst, L"ab", sizeof(wchar_t) * 3));
+ EXPECT_EQ(0, memcmp(wdst, L"ab", sizeof(wdst)));
}
}
@@ -1337,28 +1351,6 @@
EXPECT_TRUE(MakeWStringPiece(baz.end(), baz.end()).empty());
}
-enum class StreamableTestEnum { kGreeting, kLocation };
-
-std::ostream& operator<<(std::ostream& os, const StreamableTestEnum& value) {
- switch (value) {
- case StreamableTestEnum::kGreeting:
- return os << "hello";
- case StreamableTestEnum::kLocation:
- return os << "world";
- }
-}
-
-TEST(StringUtilTest, StreamableToString) {
- EXPECT_EQ(StreamableToString("foo"), "foo");
- EXPECT_EQ(StreamableToString(123), "123");
- EXPECT_EQ(StreamableToString(StreamableTestEnum::kGreeting), "hello");
- EXPECT_EQ(StreamableToString(StreamableTestEnum::kGreeting, " ",
- StreamableTestEnum::kLocation),
- "hello world");
- EXPECT_EQ(StreamableToString("42 in hex is ", std::hex, 42),
- "42 in hex is 2a");
-}
-
TEST(StringUtilTest, RemoveChars) {
const char kRemoveChars[] = "-/+*";
std::string input = "A-+bc/d!*";
@@ -1617,4 +1609,6 @@
EXPECT_EQ(4u, live.size());
}
+} // namespace
+
} // namespace base
diff --git a/base/template_util.h b/base/template_util.h
index 1179a99..93b7c31 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -18,15 +18,6 @@
namespace internal {
-// Uses expression SFINAE to detect whether using operator<< would work.
-template <typename T, typename = void>
-struct SupportsOstreamOperator : std::false_type {};
-template <typename T>
-struct SupportsOstreamOperator<T,
- decltype(void(std::declval<std::ostream&>()
- << std::declval<T>()))>
- : std::true_type {};
-
template <typename T, typename = void>
struct SupportsToString : std::false_type {};
template <typename T>
diff --git a/copy.bara.sky b/copy.bara.sky
index 6c374ad..7f21a09 100644
--- a/copy.bara.sky
+++ b/copy.bara.sky
@@ -84,7 +84,6 @@
"base/memory/raw_ptr_exclusion.h",
"base/notreached.h",
"base/trace_event/memory_usage_estimator.h",
- "third_party/perfetto/include/perfetto/tracing/traced_value.h",
]
transformations = [
@@ -109,7 +108,8 @@
core.move("url/url_idna_icu_alternatives_ios.mm", "url/url_idna_ascii_only.cc"),
# Fix some Perfetto includes.
- core.replace("perfetto/tracing/traced_value_forward.h", "perfetto/tracing/traced_value.h"),
+ core.replace("base/trace_event/base_tracing.h", "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"),
+ core.replace("base/trace_event/base_tracing_forward.h", "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"),
core.replace("#include \"base/strings/string_number_conversions_win.h\"", ""),
core.replace("#include \"base/allocator/partition_allocator/partition_alloc_config.h\"", ""),
diff --git a/url/gurl.cc b/url/gurl.cc
index 87097a9..73e1070 100644
--- a/url/gurl.cc
+++ b/url/gurl.cc
@@ -15,8 +15,8 @@
#include "base/no_destructor.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
-#include "polyfills/base/trace_event/memory_usage_estimator.h"
#include "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"
+#include "polyfills/base/trace_event/memory_usage_estimator.h"
#include "url/url_canon_stdstring.h"
#include "url/url_util.h"
diff --git a/url/origin.cc b/url/origin.cc
index b16d3df..06119ba 100644
--- a/url/origin.cc
+++ b/url/origin.cc
@@ -21,8 +21,8 @@
#include "base/pickle.h"
#include "base/strings/strcat.h"
#include "base/strings/string_piece.h"
-#include "base/unguessable_token.h"
#include "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"
+#include "base/unguessable_token.h"
#include "url/gurl.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"
diff --git a/url/origin.h b/url/origin.h
index 292d8d4..d08229d 100644
--- a/url/origin.h
+++ b/url/origin.h
@@ -16,11 +16,11 @@
#include "base/gtest_prod_util.h"
#include "base/strings/string_piece_forward.h"
#include "base/strings/string_util.h"
+#include "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "absl/types/optional.h"
-#include "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"
#include "url/scheme_host_port.h"
#if BUILDFLAG(IS_ANDROID)
diff --git a/url/url_canon.h b/url/url_canon.h
index bb90c4a..55fe426 100644
--- a/url/url_canon.h
+++ b/url/url_canon.h
@@ -730,14 +730,30 @@
query(default_value),
ref(default_value) {}
- const CHAR* scheme;
- const CHAR* username;
- const CHAR* password;
- const CHAR* host;
- const CHAR* port;
- const CHAR* path;
- const CHAR* query;
- const CHAR* ref;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* scheme;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* username;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* password;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* host;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* port;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* path;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* query;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const CHAR* ref;
};
// This structure encapsulates information on modifying a URL. Each component
diff --git a/url/url_canon_icu.cc b/url/url_canon_icu.cc
index 088235b..b5ebf9a 100644
--- a/url/url_canon_icu.cc
+++ b/url/url_canon_icu.cc
@@ -10,6 +10,7 @@
#include "polyfills/base/check.h"
#include "polyfills/base/memory/raw_ptr.h"
+#include "polyfills/base/memory/raw_ptr_exclusion.h"
#include <unicode/ucnv.h>
#include <unicode/ucnv_cb.h>
#include <unicode/utypes.h>
@@ -70,7 +71,9 @@
raw_ptr<UConverter> converter_;
UConverterFromUCallback old_callback_;
- const void* old_context_;
+ // This field is not a raw_ptr<> because it was filtered by the rewriter for:
+ // #addr-of
+ RAW_PTR_EXCLUSION const void* old_context_;
};
} // namespace
diff --git a/url/url_canon_ip.cc b/url/url_canon_ip.cc
index ec8617e..88d9bf5 100644
--- a/url/url_canon_ip.cc
+++ b/url/url_canon_ip.cc
@@ -11,6 +11,7 @@
#include "polyfills/base/check.h"
#include "url/url_canon_internal.h"
+#include "url/url_features.h"
namespace url {
@@ -490,13 +491,24 @@
// it to |address|.
if (ipv6_parsed.ipv4_component.is_valid()) {
// Append the 32-bit number to |address|.
- int ignored_num_ipv4_components;
+ int num_ipv4_components = 0;
+ // IPv4AddressToNumber will remove the trailing dot from the component.
+ bool trailing_dot = ipv6_parsed.ipv4_component.is_nonempty() &&
+ spec[ipv6_parsed.ipv4_component.end() - 1] == '.';
+ // The URL standard requires the embedded IPv4 address to be concisely
+ // composed of 4 parts and disallows terminal dots.
+ // See https://url.spec.whatwg.org/#concept-ipv6-parser
if (CanonHostInfo::IPV4 !=
- IPv4AddressToNumber(spec,
- ipv6_parsed.ipv4_component,
- &address[cur_index_in_address],
- &ignored_num_ipv4_components))
+ IPv4AddressToNumber(spec, ipv6_parsed.ipv4_component,
+ &address[cur_index_in_address],
+ &num_ipv4_components)) {
return false;
+ }
+ if ((num_ipv4_components != 4 || trailing_dot) &&
+ gurl_base::FeatureList::IsEnabled(
+ url::kStrictIPv4EmbeddedIPv6AddressParsing)) {
+ return false;
+ }
}
return true;
diff --git a/url/url_canon_relative.cc b/url/url_canon_relative.cc
index 67780b1..b9f7b98 100644
--- a/url/url_canon_relative.cc
+++ b/url/url_canon_relative.cc
@@ -12,6 +12,7 @@
#include "url/url_canon.h"
#include "url/url_canon_internal.h"
#include "url/url_constants.h"
+#include "url/url_features.h"
#include "url/url_file.h"
#include "url/url_parse_internal.h"
#include "url/url_util.h"
@@ -162,7 +163,12 @@
// If the scheme isn't valid, then it's relative.
if (!IsValidScheme(url, scheme)) {
- if (!is_base_hierarchical) {
+ if (url[begin] == '#' &&
+ gurl_base::FeatureList::IsEnabled(
+ kResolveBareFragmentWithColonOnNonHierarchical)) {
+ // |url| is a bare fragment (e.g. "#foo:bar"). This can be resolved
+ // against any base. Fall-through.
+ } else if (!is_base_hierarchical) {
// Don't allow relative URLs if the base scheme doesn't support it.
return false;
}
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc
index 8890639..db875a8 100644
--- a/url/url_canon_unittest.cc
+++ b/url/url_canon_unittest.cc
@@ -290,8 +290,9 @@
// IDNA mode to use in CanonHost tests.
enum class IDNAMode { kTransitional, kNonTransitional };
-class URLCanonHostTest : public ::testing::Test,
- public ::testing::WithParamInterface<IDNAMode> {
+class URLCanonHostTest
+ : public ::testing::Test,
+ public ::testing::WithParamInterface<IDNAMode> {
public:
URLCanonHostTest() {
if (GetParam() == IDNAMode::kNonTransitional) {
@@ -856,7 +857,30 @@
}
}
-TEST(URLCanonTest, IPv6) {
+class URLCanonIPv6Test
+ : public ::testing::Test,
+ public ::testing::WithParamInterface<bool> {
+ public:
+ URLCanonIPv6Test() {
+ if (GetParam()) {
+ scoped_feature_list_.InitAndEnableFeature(kStrictIPv4EmbeddedIPv6AddressParsing);
+ } else {
+ scoped_feature_list_.InitAndDisableFeature(kStrictIPv4EmbeddedIPv6AddressParsing);
+ }
+ }
+
+ private:
+ gurl_base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+ URLCanonIPv6Test,
+ ::testing::Bool());
+
+TEST_P(URLCanonIPv6Test, IPv6) {
+ bool strict_ipv4_embedded_ipv6_parsing =
+ gurl_base::FeatureList::IsEnabled(url::kStrictIPv4EmbeddedIPv6AddressParsing);
+
IPAddressCase cases[] = {
// Empty is not an IP address.
{"", L"", "", Component(), CanonHostInfo::NEUTRAL, -1, ""},
@@ -895,8 +919,24 @@
{"[2001::192.168.0.1]", L"[2001::192.168.0.1]", "[2001::c0a8:1]", Component(0, 14), CanonHostInfo::IPV6, -1, "200100000000000000000000C0A80001"},
{"[1:2:192.168.0.1:5:6]", L"[1:2:192.168.0.1:5:6]", "", Component(), CanonHostInfo::BROKEN, -1, ""},
- // IPv4 with last component missing.
- {"[::ffff:192.1.2]", L"[::ffff:192.1.2]", "[::ffff:c001:2]", Component(0,15), CanonHostInfo::IPV6, -1, "00000000000000000000FFFFC0010002"},
+ // IPv4 embedded IPv6 addresses
+ {"[::ffff:192.1.2]",
+ L"[::ffff:192.1.2]",
+ "[::ffff:c001:2]",
+ strict_ipv4_embedded_ipv6_parsing ? Component() : Component(0,15),
+ strict_ipv4_embedded_ipv6_parsing ? CanonHostInfo::BROKEN : CanonHostInfo::IPV6,
+ -1,
+ (strict_ipv4_embedded_ipv6_parsing ? "" : "00000000000000000000FFFFC0010002")},
+ {"[::ffff:192.1]",
+ L"[::ffff:192.1]",
+ "[::ffff:c000:1]",
+ strict_ipv4_embedded_ipv6_parsing ? Component() : Component(0,15),
+ strict_ipv4_embedded_ipv6_parsing ? CanonHostInfo::BROKEN : CanonHostInfo::IPV6,
+ -1,
+ (strict_ipv4_embedded_ipv6_parsing ? "" : "00000000000000000000FFFFC0000001")},
+ {"[::ffff:192.1.2.3.4]",
+ L"[::ffff:192.1.2.3.4]",
+ "", Component(), CanonHostInfo::BROKEN, -1, ""},
// IPv4 using hex.
// TODO(eroman): Should this format be disallowed?
diff --git a/url/url_constants.cc b/url/url_constants.cc
index aa8978b..850a31c 100644
--- a/url/url_constants.cc
+++ b/url/url_constants.cc
@@ -40,10 +40,6 @@
const char16_t kJavaScriptScheme16[] = u"javascript";
const char kMailToScheme[] = "mailto";
const char16_t kMailToScheme16[] = u"mailto";
-// This is for QuicTransport (https://wicg.github.io/web-transport/).
-// See also: https://www.iana.org/assignments/uri-schemes/prov/quic-transport
-const char kQuicTransportScheme[] = "quic-transport";
-const char16_t kQuicTransportScheme16[] = u"quic-transport";
const char kTelScheme[] = "tel";
const char16_t kTelScheme16[] = u"tel";
const char kUrnScheme[] = "urn";
diff --git a/url/url_constants.h b/url/url_constants.h
index bbcdd40..0d58125 100644
--- a/url/url_constants.h
+++ b/url/url_constants.h
@@ -46,8 +46,6 @@
COMPONENT_EXPORT(URL) extern const char16_t kJavaScriptScheme16[];
COMPONENT_EXPORT(URL) extern const char kMailToScheme[];
COMPONENT_EXPORT(URL) extern const char16_t kMailToScheme16[];
-COMPONENT_EXPORT(URL) extern const char kQuicTransportScheme[];
-COMPONENT_EXPORT(URL) extern const char16_t kQuicTransportScheme16[];
COMPONENT_EXPORT(URL) extern const char kTelScheme[];
COMPONENT_EXPORT(URL) extern const char16_t kTelScheme16[];
COMPONENT_EXPORT(URL) extern const char kUrnScheme[];
diff --git a/url/url_features.cc b/url/url_features.cc
index 877d846..b82afd7 100644
--- a/url/url_features.cc
+++ b/url/url_features.cc
@@ -15,6 +15,15 @@
"RecordIDNA2008Metrics",
gurl_base::FEATURE_ENABLED_BY_DEFAULT);
+BASE_FEATURE(kStrictIPv4EmbeddedIPv6AddressParsing,
+ "StrictIPv4EmbeddedIPv6AddressParsing",
+ gurl_base::FEATURE_DISABLED_BY_DEFAULT);
+
+// Kill switch for crbug.com/1220361.
+BASE_FEATURE(kResolveBareFragmentWithColonOnNonHierarchical,
+ "ResolveBareFragmentWithColonOnNonHierarchical",
+ gurl_base::FEATURE_ENABLED_BY_DEFAULT);
+
bool IsUsingIDNA2008NonTransitional() {
return gurl_base::FeatureList::IsEnabled(kUseIDNA2008NonTransitional);
}
diff --git a/url/url_features.h b/url/url_features.h
index e1b62be..41f689b 100644
--- a/url/url_features.h
+++ b/url/url_features.h
@@ -18,6 +18,16 @@
// Returns true if Chrome is recording IDNA 2008 related metrics.
COMPONENT_EXPORT(URL) bool IsRecordingIDNA2008Metrics();
+// Returns true if Chrome is enforcing the 4 part check for IPv4 embedded IPv6
+// addresses.
+COMPONENT_EXPORT(URL)
+BASE_DECLARE_FEATURE(kStrictIPv4EmbeddedIPv6AddressParsing);
+
+// When enabled, allows resolving of a bare fragment containing a colon against
+// a non-hierarchical URL. (For example '#foo:bar' against 'about:blank'.)
+COMPONENT_EXPORT(URL)
+BASE_DECLARE_FEATURE(kResolveBareFragmentWithColonOnNonHierarchical);
+
} // namespace url
#endif // URL_URL_FEATURES_H_
diff --git a/url/url_util.cc b/url/url_util.cc
index da29651..705ec2e 100644
--- a/url/url_util.cc
+++ b/url/url_util.cc
@@ -57,7 +57,6 @@
SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, // WebSocket secure.
{kWsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, // WebSocket.
{kFileSystemScheme, SCHEME_WITHOUT_AUTHORITY},
- {kQuicTransportScheme, SCHEME_WITH_HOST_AND_PORT},
};
// Schemes that are allowed for referrers.
@@ -74,7 +73,10 @@
// Schemes that do not trigger mixed content warning.
std::vector<std::string> secure_schemes = {
- kHttpsScheme, kAboutScheme, kDataScheme, kQuicTransportScheme, kWssScheme,
+ kHttpsScheme,
+ kWssScheme,
+ kDataScheme,
+ kAboutScheme,
};
// Schemes that normal pages cannot link to or access (i.e., with the same
diff --git a/url/url_util_unittest.cc b/url/url_util_unittest.cc
index 098dc7c..a220af9 100644
--- a/url/url_util_unittest.cc
+++ b/url/url_util_unittest.cc
@@ -144,9 +144,8 @@
TEST_F(URLUtilTest, GetStandardSchemes) {
std::vector<std::string> expected = {
- kHttpsScheme, kHttpScheme, kFileScheme,
- kFtpScheme, kWssScheme, kWsScheme,
- kFileSystemScheme, kQuicTransportScheme, "foo",
+ kHttpsScheme, kHttpScheme, kFileScheme, kFtpScheme,
+ kWssScheme, kWsScheme, kFileSystemScheme, "foo",
};
AddStandardScheme("foo", url::SCHEME_WITHOUT_AUTHORITY);
EXPECT_EQ(expected, GetStandardSchemes());
@@ -395,6 +394,7 @@
{"about:blank", "#id42", true, "about:blank#id42"},
{"about:blank", " #id42", true, "about:blank#id42"},
{"about:blank#oldfrag", "#newfrag", true, "about:blank#newfrag"},
+ {"about:blank", " #id:42", true, "about:blank#id:42"},
// A surprising side effect of allowing fragments to resolve against
// any URL scheme is we might break javascript: URLs by doing so...
{"javascript:alert('foo#bar')", "#badfrag", true,