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,