Update googleurl to the latest version from Chromium
Version used is cabce318aaa096f18dee72eb09b0bddf1565cd2b from
Tue Feb 22 09:08:34 2022 +0000.
Change-Id: Ia8646e29a6780b3d8f3dab275c2513e012b3546f
diff --git a/AUTHORS b/AUTHORS
index 012e246..364df55 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -47,6 +47,7 @@
Alec Petridis <alecthechop@gmail.com>
Aleksandar Stojiljkovic <aleksandar.stojiljkovic@intel.com>
Aleksei Gurianov <gurianov@gmail.com>
+Alesandro Ortiz <alesandro@alesandroortiz.com>
Alex Chronopoulos <achronop@gmail.com>
Alex Gabriel <minilogo@gmail.com>
Alex Gartrell <agartrell@cmu.edu>
@@ -88,10 +89,12 @@
anatoly techtonik <techtonik@gmail.com>
Ancil George <ancilgeorge@samsung.com>
Andra Paraschiv <andra.paraschiv@intel.com>
+Andras Tokodi <a.tokodi@eyeo.com>
Andreas Papacharalampous <andreas@apap04.com>
Andrei Borza <andrei.borza@gmail.com>
Andrei Parvu <andrei.prv@gmail.com>
Andrei Parvu <parvu@adobe.com>
+Andres Salomon <dilinger@queued.net>
Andreu Botella <andreu@andreubotella.com>
Andrew Boyarshin <andrew.boyarshin@gmail.com>
Andrew Brampton <me@bramp.net>
@@ -183,6 +186,7 @@
Caio Marcelo de Oliveira Filho <caio.de.oliveira.filho@intel.com>
Caitlin Potter <caitpotter88@gmail.com>
Calvin Mei <calvimei@amazon.com>
+Calvin Watford <watfordcalvin@gmail.com>
Cameron Gutman <aicommander@gmail.com>
Camille Viot <viot.camille@outlook.com>
Carlos Santa <carlos.santa@intel.com>
@@ -251,8 +255,10 @@
Daniel Waxweiler <daniel.waxweiler@gmail.com>
Dániel Bátyai <dbatyai@inf.u-szeged.hu>
Dániel Vince <vinced@inf.u-szeged.hu>
+Daniil Suvorov <severecloud@gmail.com>
Daoming Qiu <daoming.qiu@intel.com>
Darik Harter <darik.harter@gmail.com>
+Darshan Sen <raisinten@gmail.com>
Darshini KN <kn.darshini@samsung.com>
Dave Vandyke <kzar@kzar.co.uk>
David Benjamin <davidben@mit.edu>
@@ -342,6 +348,7 @@
Fabien Tassin <fta@sofaraway.org>
Felipe Erias Morandeira <felipeerias@gmail.com>
Felix H. Dahlke <fhd@ubercode.de>
+Felix Weilbach <feweilbach@gmail.com>
Fengrong Fang <fr.fang@samsung.com>
Fernando Jiménez Moreno <ferjmoreno@gmail.com>
Finbar Crago <finbar.crago@gmail.com>
@@ -408,6 +415,7 @@
Heeyoun Lee <heeyoun.lee@samsung.com>
Henrique Limas <henrique.ramos.limas@gmail.com>
Himanshu Joshi <h.joshi@samsung.com>
+Hiroyuki Matsuda <gsittyz@gmail.com>
Hodol Han <bab6ting@gmail.com>
Holger Kraus <kraush@amazon.com>
Hong Zheng <hong.zheng@intel.com>
@@ -476,6 +484,7 @@
James Wei <james.wei@intel.com>
James Willcox <jwillcox@litl.com>
Jan Grulich <grulja@gmail.com>
+Jan Keitel <jan.keitel@gmail.com>
Jan Rucka <ruckajan10@gmail.com>
Jan Sauer <jan@jansauer.de>
Janusz Majnert <jmajnert@gmail.com>
@@ -535,6 +544,7 @@
Jinyoung Hur <hur.ims@navercorp.com>
Jinyoung Hur <hurims@gmail.com>
Jitendra Kumar Sahoo <jitendra.ks@samsung.com>
+Jitesh Pareek <j1.pareek@samsung.com>
Joachim Bauch <jbauch@webrtc.org>
Joachim Bauch <mail@joachim-bauch.de>
Joanmarie Diggs <joanmarie.diggs@gmail.com>
@@ -553,6 +563,7 @@
Jonathan Garbee <jonathan@garbee.me>
Jonathan Hacker <jhacker@arcanefour.com>
Jonathan Kingston <kingstonmailbox@gmail.com>
+Jonathan Shimonovich <jonathans@talon-sec.com>
Jongdeok Kim <jongdeok.kim@navercorp.com>
Jongheon Kim <sapzape@gmail.com>
JongKwon Lee <jongkwon.lee@navercorp.com>
@@ -592,6 +603,7 @@
Justin Okamoto <justmoto@amazon.com>
Justin Ribeiro <justin@justinribeiro.com>
Jüri Valdmann <juri.valdmann@qt.io>
+Juyoung Kim <chattank05@gmail.com>
Kai Jiang <jiangkai@gmail.com>
Kai Köhne <kai.koehne@qt.io>
Kai Uwe Broulik <kde@privat.broulik.de>
@@ -610,6 +622,7 @@
Kaustubh Atrawalkar <kaustubh.a@samsung.com>
Kaustubh Atrawalkar <kaustubh.ra@gmail.com>
Ke He <ke.he@intel.com>
+Keeley Hammond <vertedinde@electronjs.org>
Keene Pan <keenepan@linpus.com>
Keiichiro Nagashima <n4ag3a2sh1i@gmail.com>
Keita Suzuki <keitasuzuki.park@gmail.com>
@@ -645,6 +658,7 @@
Kui Tan <tk1061178@gmail.com>
Kunal Thakar <kunalt@gmail.com>
Kushal Pisavadia <kushi.p@gmail.com>
+Kwanghee Lee <ekwange@gmail.com>
Kwangho Shin <k_h.shin@samsung.com>
Kyle Nahrgang <kpn24@drexel.edu>
Kyle Plumadore <kyle.plumadore@amd.com>
@@ -682,6 +696,7 @@
Lorenzo Stoakes <lstoakes@gmail.com>
Lu Guanqun <guanqun.lu@gmail.com>
Luc Shi <lei.a.shi@intel.com>
+Luca Casonato <luccasonato@gmail.com>
Luca Di Domenico <luca94dd@gmail.com>
Lucie Brozkova <lucinka.brozkova@gmail.com>
Luiz Von Dentz <luiz.von.dentz@intel.com>
@@ -790,6 +805,7 @@
Miran Karic <miran.karic@imgtec.com>
Mirela Budaes <mbudaes@adobe.com>
Mirela Budaes <mbudaes@gmail.com>
+Mitchell Cohen <mitchell@agilebits.com>
Miyoung Shin <myid.shin@navercorp.com>
Mohamed I. Hammad <ibraaaa@gmail.com>
Mohamed Mansour <m0.interactive@gmail.com>
@@ -797,6 +813,7 @@
Mohammed Wajahat Ali Siddiqui <wajahat.s@samsung.com>
Mohan Reddy <mohan.reddy@samsung.com>
Mohit Bhalla <bhallam@amazon.com>
+Momoka Yamamoto <momoka.my6@gmail.com>
Momoko Hattori <momohatt10@gmail.com>
Mostafa Sedaghat joo <mostafa.sedaghat@gmail.com>
Mrunal Kapade <mrunal.kapade@intel.com>
@@ -954,6 +971,7 @@
Rosen Dash <rosen.dash@gmail.com>
Ross Kirsling <rkirsling@gmail.com>
Ross Wollman <ross.wollman@gmail.com>
+Roy Le <royle0502@gmail.com>
Ruan Beihong <ruanbeihong@gmail.com>
ruben <chromium@hybridsource.org>
Ruben Bridgewater <ruben@bridgewater.de>
@@ -1013,6 +1031,7 @@
Sergio Carlos Morales Angeles <carloschilazo@gmail.com>
Sergio Garcia Murillo <sergio.garcia.murillo@gmail.com>
Sergiy Belozorov <rryk.ua@gmail.com>
+Serhii Matrunchyk <sergiy.matrunchyk@gmail.com>
Seshadri Mahalingam <seshadri.mahalingam@gmail.com>
Seungkyu Lee <zx6658@gmail.com>
Sevan Janiyan <venture37@geeklan.co.uk>
@@ -1100,6 +1119,7 @@
Sylvestre Ledru <sylvestre.ledru@gmail.com>
Synthia Islam <synthia.is@samsung.com>
Szabolcs David <davidsz@inf.u-szeged.hu>
+Szilard Szaloki <szilardszaloki@gmail.com>
Szymon Piechowicz <szymonpiechowicz@o2.pl>
Taeheon Kim <skyrabbits1@gmail.com>
Taeho Nam <thn7440@gmail.com>
@@ -1108,7 +1128,9 @@
Taeyeon Kim <ssg9732@gmail.com>
Tae Shin <taeshindev@gmail.com>
Takaaki Suzuki <takaakisuzuki.14@gmail.com>
+Takahiro Aoyagi <hogehoge@gachapin.jp>
Takashi Fujita <tgfjt.mail@gmail.com>
+Takashi Mima <tks.m1205@gmail.com>
Takeshi Kurosawa <taken.spc@gmail.com>
Tanay Chowdhury <tanay.c@samsung.com>
Tanvir Rizvi <tanvir.rizvi@samsung.com>
@@ -1133,6 +1155,7 @@
Timo Reimann <ttr314@googlemail.com>
Timo Witte <timo.witte@gmail.com>
Ting Shao <ting.shao@intel.com>
+Tobias Lippert <tobias.lippert@fastmail.com>
Tobias Soppa <tobias@soppa.me>
Tobias Soppa <tobias.soppa@code.berlin>
Tom Callaway <tcallawa@redhat.com>
@@ -1150,6 +1173,7 @@
U. Artie Eoff <ullysses.a.eoff@intel.com>
Umar Hansa <umar.hansa@gmail.com>
Upendra Gowda <upendrag.gowda@gmail.com>
+UwU UwU <uwu7586@gmail.com>
Uzair Jaleel <uzair.jaleel@samsung.com>
Vadim Gorbachev <bmsdave@gmail.com>
Vaibhav Agrawal <vaibhav1.a@samsung.com>
@@ -1174,6 +1198,7 @@
Vivek Galatage <vivek.vg@samsung.com>
Volker Sorge <volker.sorge@gmail.com>
Waihung Fu <fufranci@amazon.com>
+wafuwafu13 <mariobaske@i.softbank.jp>
Wojciech Bielawski <wojciech.bielawski@gmail.com>
Wanming Lin <wanming.lin@intel.com>
Wei Li <wei.c.li@intel.com>
@@ -1186,6 +1211,7 @@
Will Cohen <wwcohen@gmail.com>
Will Hirsch <chromium@willhirsch.co.uk>
Will Shackleton <w.shackleton@gmail.com>
+Will Watts <willwatts.ww@googlemail.com>
William Xie <william.xie@intel.com>
Winston Chen <winston.c1@samsung.com>
Xiang Long <xiang.long@intel.com>
@@ -1239,7 +1265,9 @@
Youngsun Suh <zard17@gmail.com>
Yuan-Pin Yu <yjames@uber.com>
Yuhong Sha <yuhong.sha@samsung.com>
+Yuki Osaki <yuki.osaki7@gmail.com>
Yuki Tsuchiya <Yuki.Tsuchiya@sony.com>
+Yuma Takai <tara20070827@gmail.com>
Yumikiyo Osanai <yumios.art@gmail.com>
Yunchao He <yunchao.he@intel.com>
Yupei Lin <yplam@yplam.com>
@@ -1251,6 +1279,7 @@
Yuta Kasai <kasai.yuta0810@gmail.com>
Yuvanesh Natarajan <yuvanesh.n1@samsung.com>
Zach Bjornson <zbbjornson@gmail.com>
+Zachary Capalbo <zach.geek@gmail.com>
Zeno Albisser <zeno.albisser@digia.com>
Zeqin Chen <talonchen@tencent.com>
Zhang Hao <15686357310a@gmail.com>
@@ -1267,6 +1296,7 @@
Zoltan Czirkos <czirkos.zoltan@gmail.com>
Zoltan Herczeg <zherczeg.u-szeged@partner.samsung.com>
Zoltan Kuscsik <zoltan.kuscsik@linaro.org>
+Zoru Lee <donzoru@gmail.com>
Zsolt Borbely <zsborbely.u-szeged@partner.samsung.com>
方觉 (Fang Jue) <fangjue23303@gmail.com>
迷渡 <justjavac@gmail.com>
@@ -1276,6 +1306,7 @@
# BEGIN organizations section.
Accenture <*@accenture.com>
ACCESS CO., LTD. <*@access-company.com>
+Ada Logics Ltd. <*@adalogics.com>
Akamai Inc. <*@akamai.com>
ARM Holdings <*@arm.com>
BlackBerry Limited <*@blackberry.com>
@@ -1318,11 +1349,13 @@
Mozilla Corporation <*@mozilla.com>
Neverware Inc. <*@neverware.com>
NIKE, Inc. <*@nike.com>
+Nutanix Inc. <*nutanix.com>
NVIDIA Corporation <*@nvidia.com>
OpenFin Inc. <*@openfin.co>
Opera Software ASA <*@opera.com>
Optical Tone Ltd <*@opticaltone.com>
Pengutronix e.K. <*@pengutronix.de>
+Quality First Software GmbH <*@qf-software.com>
Rakuten Kobo Inc. <*@kobo.com>
Rakuten Kobo Inc. <*@rakuten.com>
Red Hat Inc. <*@redhat.com>
@@ -1332,15 +1365,18 @@
Spotify AB <*@spotify.com>
Synaptics <*@synaptics.com>
Tableau Software <*@tableau.com>
+Talon Cyber Security Ltd. <*@talon-sec.com>
TeamSpeak Systems GmbH <*@teamspeak.com>
The Chromium Authors <*@chromium.org>
The MathWorks, Inc. <binod.pant@mathworks.com>
+THEO Technologies <*@theoplayer.com>
Torchmobile Inc.
Upwork <*@cloud.upwork.com>
Venture 3 Systems LLC <*@venture3systems.com>
Vewd Software AS <*@vewd.com>
Vivaldi Technologies AS <*@vivaldi.com>
Wacom <*@wacom.com>
+Xperi Corporation <*@xperi.com>
Yandex LLC <*@yandex-team.ru>
# Please DO NOT APPEND here. See comments at the top of the file.
# END organizations section.
diff --git a/base/BUILD b/base/BUILD
index e2da292..d31df3e 100644
--- a/base/BUILD
+++ b/base/BUILD
@@ -6,6 +6,14 @@
cc_library(
name = "base",
+ srcs = [
+ "debug/crash_logging.cc",
+ "strings/string_piece.cc",
+ "strings/string_util.cc",
+ "strings/string_util_constants.cc",
+ "strings/utf_string_conversion_utils.cc",
+ "strings/utf_string_conversions.cc",
+ ],
hdrs = [
"compiler_specific.h",
"containers/checked_iterators.h",
@@ -15,22 +23,33 @@
"containers/util.h",
"cxx17_backports.h",
"cxx20_to_address.h",
+ "debug/crash_logging.h",
"debug/leak_annotations.h",
"functional/identity.h",
"functional/invoke.h",
"functional/not_fn.h",
- "macros.h",
+ "memory/raw_ptr.h",
"no_destructor.h",
"ranges/algorithm.h",
"ranges/functional.h",
"ranges/ranges.h",
"stl_util.h",
"template_util.h",
- ],
+ "strings/char_traits.h",
+ "strings/string_piece_forward.h",
+ "strings/string_piece.h",
+ "strings/string_util.h",
+ "strings/string_util_internal.h",
+ "strings/string_number_conversions.h",
+ "strings/utf_string_conversions.h",
+ "strings/utf_string_conversion_utils.h",
+ ] + build_config.strings_hdrs,
copts = build_config.default_copts,
visibility = ["//visibility:public"],
deps = [
+ "//base/third_party/icu",
"//build:build_config",
+ "//build:buildflag",
"//polyfills",
"@com_google_absl//absl/types:optional",
],
diff --git a/base/compiler_specific.h b/base/compiler_specific.h
index 58a7d0d..3a85453 100644
--- a/base/compiler_specific.h
+++ b/base/compiler_specific.h
@@ -31,23 +31,6 @@
#define HAS_BUILTIN(x) 0
#endif
-// Annotate a variable indicating it's ok if the variable is not used.
-// (Typically used to silence a compiler warning when the assignment
-// is important for some other reason.)
-// Use like:
-// int x = ...;
-// ALLOW_UNUSED_LOCAL(x);
-#define ALLOW_UNUSED_LOCAL(x) (void)x
-
-// Annotate a typedef or function indicating it's ok if it's not used.
-// Use like:
-// typedef Foo Bar ALLOW_UNUSED_TYPE;
-#if defined(COMPILER_GCC) || defined(__clang__)
-#define ALLOW_UNUSED_TYPE __attribute__((unused))
-#else
-#define ALLOW_UNUSED_TYPE
-#endif
-
// Annotate a function indicating it should not be inlined.
// Use like:
// NOINLINE void DoStuff() { ... }
@@ -108,17 +91,6 @@
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#endif
-// Annotate a function indicating the caller must examine the return value.
-// Use like:
-// int foo() WARN_UNUSED_RESULT;
-// To explicitly ignore a result, see |ignore_result()| in base/macros.h.
-#undef WARN_UNUSED_RESULT
-#if defined(COMPILER_GCC) || defined(__clang__)
-#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
-#else
-#define WARN_UNUSED_RESULT
-#endif
-
// In case the compiler supports it NO_UNIQUE_ADDRESS evaluates to the C++20
// attribute [[no_unique_address]]. This allows annotating data members so that
// they need not have an address distinct from all other non-static data members
@@ -164,7 +136,7 @@
#endif
// MemorySanitizer annotations.
-#if defined(MEMORY_SANITIZER) && !defined(OS_NACL)
+#if defined(MEMORY_SANITIZER) && !BUILDFLAG(IS_NACL)
#include <sanitizer/msan_interface.h>
// Mark a memory region fully initialized.
@@ -194,7 +166,7 @@
// DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks.
#if !defined(DISABLE_CFI_ICALL)
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
// Windows also needs __declspec(guard(nocf)).
#define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") __declspec(guard(nocf))
#else
@@ -207,11 +179,11 @@
// Macro useful for writing cross-platform function pointers.
#if !defined(CDECL)
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
#define CDECL __cdecl
-#else // defined(OS_WIN)
+#else // BUILDFLAG(IS_WIN)
#define CDECL
-#endif // defined(OS_WIN)
+#endif // BUILDFLAG(IS_WIN)
#endif // !defined(CDECL)
// Macro for hinting that an expression is likely to be false.
@@ -239,13 +211,6 @@
#define HAS_FEATURE(FEATURE) 0
#endif
-// Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
-#if defined(__clang__)
-#define FALLTHROUGH [[clang::fallthrough]]
-#else
-#define FALLTHROUGH
-#endif
-
#if defined(COMPILER_GCC)
#define PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif defined(COMPILER_MSVC)
@@ -354,13 +319,11 @@
#define ANALYZER_ASSUME_TRUE(arg) ::AnalyzerAssumeTrue(!!(arg))
#define ANALYZER_SKIP_THIS_PATH() static_cast<void>(::AnalyzerNoReturn())
-#define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
#else // !defined(__clang_analyzer__)
#define ANALYZER_ASSUME_TRUE(arg) (arg)
#define ANALYZER_SKIP_THIS_PATH()
-#define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
#endif // defined(__clang_analyzer__)
@@ -419,4 +382,12 @@
#define CONSTINIT
#endif
+#if defined(__clang__)
+#define GSL_OWNER [[gsl::Owner]]
+#define GSL_POINTER [[gsl::Pointer]]
+#else
+#define GSL_OWNER
+#define GSL_POINTER
+#endif
+
#endif // BASE_COMPILER_SPECIFIC_H_
diff --git a/base/containers/checked_iterators.h b/base/containers/checked_iterators.h
index b5fe925..c4e1e69 100644
--- a/base/containers/checked_iterators.h
+++ b/base/containers/checked_iterators.h
@@ -30,7 +30,7 @@
// Required for certain libc++ algorithm optimizations that are not available
// for NaCl.
-#if defined(_LIBCPP_VERSION) && !defined(OS_NACL)
+#if defined(_LIBCPP_VERSION) && !BUILDFLAG(IS_NACL)
template <typename Ptr>
friend struct std::pointer_traits;
#endif
@@ -185,10 +185,10 @@
return current_[rhs];
}
- static bool IsRangeMoveSafe(const CheckedContiguousIterator& from_begin,
- const CheckedContiguousIterator& from_end,
- const CheckedContiguousIterator& to)
- WARN_UNUSED_RESULT {
+ [[nodiscard]] static bool IsRangeMoveSafe(
+ const CheckedContiguousIterator& from_begin,
+ const CheckedContiguousIterator& from_end,
+ const CheckedContiguousIterator& to) {
if (from_end < from_begin)
return false;
const auto from_begin_uintptr = get_uintptr(from_begin.current_);
@@ -217,7 +217,7 @@
} // namespace base
-#if defined(_LIBCPP_VERSION) && !defined(OS_NACL)
+#if defined(_LIBCPP_VERSION) && !BUILDFLAG(IS_NACL)
// Specialize both std::__is_cpp17_contiguous_iterator and std::pointer_traits
// for CCI in case we compile with libc++ outside of NaCl. The former is
// required to enable certain algorithm optimizations (e.g. std::copy can be a
diff --git a/base/containers/span.h b/base/containers/span.h
index 550eec8..1ba60b1 100644
--- a/base/containers/span.h
+++ b/base/containers/span.h
@@ -15,6 +15,7 @@
#include <utility>
#include "polyfills/base/check_op.h"
+#include "base/compiler_specific.h"
#include "base/containers/checked_iterators.h"
#include "base/containers/contiguous_iterator.h"
#include "base/cxx17_backports.h"
@@ -225,10 +226,6 @@
// sized container (e.g. std::vector) requires an explicit conversion (in the
// C++20 draft this is simply UB)
//
-// Differences from [span.obs]:
-// - empty() is marked with WARN_UNUSED_RESULT instead of [[nodiscard]]
-// ([[nodiscard]] is a C++17 feature)
-//
// Furthermore, all constructors and methods are marked noexcept due to the lack
// of exceptions in Chromium.
//
@@ -237,7 +234,7 @@
// [span], class template span
template <typename T, size_t Extent>
-class span : public internal::ExtentStorage<Extent> {
+class GSL_POINTER span : public internal::ExtentStorage<Extent> {
private:
using ExtentStorage = internal::ExtentStorage<Extent>;
@@ -408,9 +405,7 @@
// [span.obs], span observers
constexpr size_t size() const noexcept { return ExtentStorage::size(); }
constexpr size_t size_bytes() const noexcept { return size() * sizeof(T); }
- constexpr bool empty() const noexcept WARN_UNUSED_RESULT {
- return size() == 0;
- }
+ [[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
// [span.elem], span element access
constexpr T& operator[](size_t idx) const noexcept {
diff --git a/base/debug/crash_logging.cc b/base/debug/crash_logging.cc
new file mode 100644
index 0000000..f6bad4f
--- /dev/null
+++ b/base/debug/crash_logging.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/debug/crash_logging.h"
+
+namespace gurl_base {
+namespace debug {
+
+namespace {
+
+CrashKeyImplementation* g_crash_key_impl = nullptr;
+
+} // namespace
+
+CrashKeyString* AllocateCrashKeyString(const char name[],
+ CrashKeySize value_length) {
+ if (!g_crash_key_impl)
+ return nullptr;
+
+ return g_crash_key_impl->Allocate(name, value_length);
+}
+
+void SetCrashKeyString(CrashKeyString* crash_key, gurl_base::StringPiece value) {
+ if (!g_crash_key_impl || !crash_key)
+ return;
+
+ g_crash_key_impl->Set(crash_key, value);
+}
+
+void ClearCrashKeyString(CrashKeyString* crash_key) {
+ if (!g_crash_key_impl || !crash_key)
+ return;
+
+ g_crash_key_impl->Clear(crash_key);
+}
+
+BASE_EXPORT void OutputCrashKeysToStream(std::ostream& out) {
+ if (!g_crash_key_impl)
+ return;
+
+ g_crash_key_impl->OutputCrashKeysToStream(out);
+}
+
+ScopedCrashKeyString::ScopedCrashKeyString(CrashKeyString* crash_key,
+ gurl_base::StringPiece value)
+ : crash_key_(crash_key) {
+ SetCrashKeyString(crash_key_, value);
+}
+
+ScopedCrashKeyString::ScopedCrashKeyString(ScopedCrashKeyString&& other)
+ : crash_key_(std::exchange(other.crash_key_, nullptr)) {}
+
+ScopedCrashKeyString::~ScopedCrashKeyString() {
+ ClearCrashKeyString(crash_key_);
+}
+
+void SetCrashKeyImplementation(std::unique_ptr<CrashKeyImplementation> impl) {
+ delete g_crash_key_impl;
+ g_crash_key_impl = impl.release();
+}
+
+} // namespace debug
+} // namespace base
diff --git a/base/debug/crash_logging.h b/base/debug/crash_logging.h
new file mode 100644
index 0000000..fdc5343
--- /dev/null
+++ b/base/debug/crash_logging.h
@@ -0,0 +1,204 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_DEBUG_CRASH_LOGGING_H_
+#define BASE_DEBUG_CRASH_LOGGING_H_
+
+#include <stddef.h>
+
+#include <iosfwd>
+#include <memory>
+#include <type_traits>
+
+#include "polyfills/base/base_export.h"
+#include "base/cxx17_backports.h"
+#include "base/memory/raw_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+
+namespace gurl_base {
+namespace debug {
+
+// A crash key is an annotation that is carried along with a crash report, to
+// provide additional debugging information beyond a stack trace. Crash keys
+// have a name and a string value.
+//
+// The preferred API is //components/crash/core/common:crash_key, however not
+// all clients can hold a direct dependency on that target. The API provided
+// in this file indirects the dependency and adds some convenience helpers that
+// make the API a bit less clunky.
+//
+// TODO(dcheng): Some of the nicer APIs should probably be upstreamed into
+// //components/crash.
+//
+// Preferred usage when a crash key value only needs to be set within a scope:
+//
+// SCOPED_CRASH_KEY_STRING32("category", "name", "value");
+// gurl_base::debug::DumpWithoutCrashing();
+//
+// If the crash key is pre-allocated elsewhere, but the value only needs to be
+// set within a scope:
+//
+// gurl_base::debug::ScopedCrashKeyString scoper(
+// GetCrashKeyForComponent(),
+// "value");
+//
+// Otherwise, if the crash key needs to persist (e.g. the actual crash dump is
+// triggered some time later asynchronously):
+//
+// static auto* const crash_key = gurl_base::debug::AllocateCrashKeyString(
+// "name", gurl_base::debug::CrashKeySize::Size32);
+// gurl_base::debug::SetCrashKeyString(crash_key);
+//
+// // Do other work before calling `gurl_base::debug::DumpWithoutCrashing()` later.
+//
+// ***WARNING***
+//
+// Do *not* write this:
+//
+// gurl_base::debug::SetCrashKeyString(
+// gurl_base::debug::AllocateCrashKeyString(
+// "name", gurl_base::debug::CrashKeySize::Size32),
+// "value");
+//
+// As this will leak a heap allocation every time the crash key is set!
+
+// The maximum length for a crash key's value must be one of the following
+// pre-determined values.
+enum class CrashKeySize {
+ Size32 = 32,
+ Size64 = 64,
+ Size256 = 256,
+};
+
+struct CrashKeyString;
+
+// Allocates a new crash key with the specified |name| with storage for a
+// value up to length |size|. This will return null if the crash key system is
+// not initialized.
+//
+// Note: this internally allocates, so the returned pointer should always
+// be cached in a variable with static storage duration, e.g.:
+// static auto* const crash_key = gurl_base::debug::AllocateCrashKeyString(...);
+BASE_EXPORT CrashKeyString* AllocateCrashKeyString(const char name[],
+ CrashKeySize size);
+
+// Stores |value| into the specified |crash_key|. The |crash_key| may be null
+// if AllocateCrashKeyString() returned null. If |value| is longer than the
+// size with which the key was allocated, it will be truncated.
+BASE_EXPORT void SetCrashKeyString(CrashKeyString* crash_key,
+ gurl_base::StringPiece value);
+
+// Clears any value that was stored in |crash_key|. The |crash_key| may be
+// null.
+BASE_EXPORT void ClearCrashKeyString(CrashKeyString* crash_key);
+
+// Outputs current (i.e. allocated and non-empty) crash keys to `out`.
+BASE_EXPORT void OutputCrashKeysToStream(std::ostream& out);
+
+// A scoper that sets the specified key to value for the lifetime of the
+// object, and clears it on destruction.
+class BASE_EXPORT ScopedCrashKeyString {
+ public:
+ ScopedCrashKeyString(CrashKeyString* crash_key, gurl_base::StringPiece value);
+ ScopedCrashKeyString(ScopedCrashKeyString&& other);
+ ~ScopedCrashKeyString();
+
+ // Disallow copy and assign.
+ ScopedCrashKeyString(const ScopedCrashKeyString&) = delete;
+ ScopedCrashKeyString& operator=(const ScopedCrashKeyString&) = delete;
+
+ // Disallow move assign to keep the time at which the crash key is cleared
+ // easy to reason about. Assigning over an existing instance would
+ // automatically clear the key instead of at the destruction of the object.
+ ScopedCrashKeyString& operator=(ScopedCrashKeyString&&) = delete;
+
+ private:
+ raw_ptr<CrashKeyString> crash_key_;
+};
+
+// Internal helpers for the SCOPED_CRASH_KEY_... helper macros defined below.
+//
+// The static_assert that checks the length of |key_name| is a compile-time
+// equivalent of the GURL_DCHECK in crash_reporter::internal::CrashKeyStringImpl::Set
+// that restricts the name of a crash key to 40 characters.
+#define SCOPED_CRASH_KEY_STRING_INTERNAL2(category, name, nonce, data, \
+ key_size) \
+ static_assert(::gurl_base::size(category "-" name) < 40, \
+ "Crash key names must be shorter than 40 characters."); \
+ ::gurl_base::debug::ScopedCrashKeyString scoped_crash_key_helper##nonce( \
+ [] { \
+ static auto* const key = ::gurl_base::debug::AllocateCrashKeyString( \
+ category "-" name, key_size); \
+ return key; \
+ }(), \
+ (data))
+
+// This indirection is needed to expand __COUNTER__.
+#define SCOPED_CRASH_KEY_STRING_INTERNAL(category, name, nonce, data, \
+ key_size) \
+ SCOPED_CRASH_KEY_STRING_INTERNAL2(category, name, nonce, data, key_size)
+
+// Helper macros for putting a local variable crash key on the stack before
+// causing a crash or calling CrashWithoutDumping(). `category` and `name`
+// should be string literals.
+//
+// SCOPED_CRASH_KEY_STRING32("MyCategory", "key_name", "value");
+//
+// will set the crash key annotation named "MyCategory-key_name" to "value"
+// while in scope.
+#define SCOPED_CRASH_KEY_STRING32(category, name, data) \
+ SCOPED_CRASH_KEY_STRING_INTERNAL(category, name, __COUNTER__, (data), \
+ ::gurl_base::debug::CrashKeySize::Size32)
+
+#define SCOPED_CRASH_KEY_STRING64(category, name, data) \
+ SCOPED_CRASH_KEY_STRING_INTERNAL(category, name, __COUNTER__, (data), \
+ ::gurl_base::debug::CrashKeySize::Size64)
+
+#define SCOPED_CRASH_KEY_STRING256(category, name, data) \
+ SCOPED_CRASH_KEY_STRING_INTERNAL(category, name, __COUNTER__, (data), \
+ ::gurl_base::debug::CrashKeySize::Size256)
+
+#define SCOPED_CRASH_KEY_BOOL(category, name, data) \
+ static_assert(std::is_same<std::decay_t<decltype(data)>, bool>::value, \
+ "SCOPED_CRASH_KEY_BOOL must be passed a boolean value."); \
+ SCOPED_CRASH_KEY_STRING32(category, name, (data) ? "true" : "false")
+
+#define SCOPED_CRASH_KEY_NUMBER(category, name, data) \
+ SCOPED_CRASH_KEY_STRING32(category, name, ::gurl_base::NumberToString(data))
+
+////////////////////////////////////////////////////////////////////////////////
+// The following declarations are used to initialize the crash key system
+// in //base by providing implementations for the above functions.
+
+// The virtual interface that provides the implementation for the crash key
+// API. This is implemented by a higher-layer component, and the instance is
+// set using the function below.
+class CrashKeyImplementation {
+ public:
+ virtual ~CrashKeyImplementation() = default;
+
+ virtual CrashKeyString* Allocate(const char name[], CrashKeySize size) = 0;
+ virtual void Set(CrashKeyString* crash_key, gurl_base::StringPiece value) = 0;
+ virtual void Clear(CrashKeyString* crash_key) = 0;
+ virtual void OutputCrashKeysToStream(std::ostream& out) = 0;
+};
+
+// Initializes the crash key system in base by replacing the existing
+// implementation, if it exists, with |impl|. The |impl| is copied into base.
+BASE_EXPORT void SetCrashKeyImplementation(
+ std::unique_ptr<CrashKeyImplementation> impl);
+
+// The base structure for a crash key, storing the allocation metadata.
+struct CrashKeyString {
+ constexpr CrashKeyString(const char name[], CrashKeySize size)
+ : name(name), size(size) {}
+ const char* const name;
+ const CrashKeySize size;
+};
+
+} // namespace debug
+} // namespace base
+
+#endif // BASE_DEBUG_CRASH_LOGGING_H_
diff --git a/base/debug/leak_annotations.h b/base/debug/leak_annotations.h
index b551552..89f47f4 100644
--- a/base/debug/leak_annotations.h
+++ b/base/debug/leak_annotations.h
@@ -18,7 +18,7 @@
// ANNOTATE_LEAKING_OBJECT_PTR(X): the heap object referenced by pointer X will
// be annotated as a leak.
-#if defined(LEAK_SANITIZER) && !defined(OS_NACL)
+#if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
#include <sanitizer/lsan_interface.h>
diff --git a/base/macros.h b/base/macros.h
deleted file mode 100644
index 19d15ca..0000000
--- a/base/macros.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains macros and macro-like constructs (e.g., templates) that
-// are commonly used throughout Chromium source. (It may also contain things
-// that are closely related to things that are commonly used that belong in this
-// file.)
-
-#ifndef BASE_MACROS_H_
-#define BASE_MACROS_H_
-
-// ALL DISALLOW_xxx MACROS ARE DEPRECATED; DO NOT USE IN NEW CODE.
-// Use explicit deletions instead. See the section on copyability/movability in
-// //styleguide/c++/c++-dos-and-donts.md for more information.
-
-// DEPRECATED: See above. Makes a class uncopyable.
-#define DISALLOW_COPY(TypeName) \
- TypeName(const TypeName&) = delete
-
-// DEPRECATED: See above. Makes a class unassignable.
-#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete
-
-// DEPRECATED: See above. Makes a class uncopyable and unassignable.
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- DISALLOW_COPY(TypeName); \
- DISALLOW_ASSIGN(TypeName)
-
-// DEPRECATED: See above. Disallow all implicit constructors, namely the
-// default constructor, copy constructor and operator= functions.
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
- TypeName() = delete; \
- DISALLOW_COPY_AND_ASSIGN(TypeName)
-
-// Used to explicitly mark the return value of a function as unused. If you are
-// really sure you don't want to do anything with the return value of a function
-// that has been marked WARN_UNUSED_RESULT, wrap it with this. Example:
-//
-// std::unique_ptr<MyType> my_var = ...;
-// if (TakeOwnership(my_var.get()) == SUCCESS)
-// ignore_result(my_var.release());
-//
-template<typename T>
-inline void ignore_result(const T&) {
-}
-
-#endif // BASE_MACROS_H_
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h
new file mode 100644
index 0000000..379c0d8
--- /dev/null
+++ b/base/memory/raw_ptr.h
@@ -0,0 +1,910 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_MEMORY_RAW_PTR_H_
+#define BASE_MEMORY_RAW_PTR_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <cstddef>
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+#include "polyfills/base/allocator/buildflags.h"
+#include "polyfills/base/check.h"
+#include "base/compiler_specific.h"
+#include "polyfills/base/dcheck_is_on.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
+
+#if BUILDFLAG(USE_BACKUP_REF_PTR)
+// USE_BACKUP_REF_PTR implies USE_PARTITION_ALLOC, needed for code under
+// allocator/partition_allocator/ to be built.
+#include "base/allocator/partition_allocator/address_pool_manager_bitmap.h"
+#include "base/allocator/partition_allocator/partition_address_space.h"
+#include "base/allocator/partition_allocator/partition_alloc_config.h"
+#include "base/allocator/partition_allocator/partition_alloc_constants.h"
+#include "polyfills/base/base_export.h"
+#endif // BUILDFLAG(USE_BACKUP_REF_PTR)
+
+#if BUILDFLAG(IS_WIN)
+#include "base/win/windows_types.h"
+#endif
+
+// Marks a field as excluded from the raw_ptr usage enforcement clang plugin.
+// Example: RAW_PTR_EXCLUSION Foo* foo_;
+#define RAW_PTR_EXCLUSION __attribute__((annotate("raw_ptr_exclusion")))
+
+namespace cc {
+class Scheduler;
+}
+namespace gurl_base::internal {
+class DelayTimerBase;
+}
+namespace content::responsiveness {
+class Calculator;
+}
+
+namespace gurl_base {
+
+// NOTE: All methods should be `ALWAYS_INLINE NO_STACK_PROTECTOR`.
+// ALWAYS_INLINE: raw_ptr is meant to be a lightweight replacement of a raw
+// pointer, hence performance is critical.
+// NO_STACK_PROTECTOR: This annotation is required to avoid failures when a
+// raw_ptr is inside a NO_STACK_PROTECTOR function.
+// TODO(https://crbug.com/1274129): Remove NO_STACK_PROTECTOR.
+#define RAW_PTR_FUNC_ATTRIBUTES ALWAYS_INLINE NO_STACK_PROTECTOR
+
+namespace internal {
+// These classes/structures are part of the raw_ptr implementation.
+// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
+
+struct RawPtrNoOpImpl {
+ // Wraps a pointer.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* WrapRawPtr(T* ptr) {
+ return ptr;
+ }
+
+ // Notifies the allocator when a wrapped pointer is being removed or replaced.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES void ReleaseWrappedPtr(T*) {}
+
+ // Unwraps the pointer, while asserting that memory hasn't been freed. The
+ // function is allowed to crash on nullptr.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForDereference(
+ T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // Unwraps the pointer, while asserting that memory hasn't been freed. The
+ // function must handle nullptr gracefully.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForExtraction(
+ T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // Unwraps the pointer, without making an assertion on whether memory was
+ // freed or not.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* UnsafelyUnwrapPtrForComparison(
+ T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // Upcasts the wrapped pointer.
+ template <typename To, typename From>
+ static RAW_PTR_FUNC_ATTRIBUTES constexpr To* Upcast(From* wrapped_ptr) {
+ static_assert(std::is_convertible<From*, To*>::value,
+ "From must be convertible to To.");
+ // Note, this cast may change the address if upcasting to base that lies in
+ // the middle of the derived object.
+ return wrapped_ptr;
+ }
+
+ // Advance the wrapped pointer by |delta| bytes.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* Advance(T* wrapped_ptr,
+ ptrdiff_t delta_elems) {
+ return wrapped_ptr + delta_elems;
+ }
+
+ // Returns a copy of a wrapped pointer, without making an assertion on whether
+ // memory was freed or not.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* Duplicate(T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // This is for accounting only, used by unit tests.
+ static RAW_PTR_FUNC_ATTRIBUTES void IncrementSwapCountForTest() {}
+ static RAW_PTR_FUNC_ATTRIBUTES void
+ IncrementPointerToMemberOperatorCountForTest() {}
+};
+
+#if BUILDFLAG(USE_BACKUP_REF_PTR)
+
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+BASE_EXPORT void CheckThatAddressIsntWithinFirstPartitionPage(
+ uintptr_t address);
+#endif
+
+struct BackupRefPtrImpl {
+ // Note that `BackupRefPtrImpl` itself is not thread-safe. If multiple threads
+ // modify the same smart pointer object without synchronization, a data race
+ // will occur.
+
+ static RAW_PTR_FUNC_ATTRIBUTES bool IsSupportedAndNotNull(uintptr_t address) {
+ // This covers the nullptr case, as address 0 is never in GigaCage.
+ bool is_in_brp_pool = IsManagedByPartitionAllocBRPPool(address);
+
+ // There are many situations where the compiler can prove that
+ // ReleaseWrappedPtr is called on a value that is always nullptr, but the
+ // way the check above is written, the compiler can't prove that nullptr is
+ // not managed by PartitionAlloc; and so the compiler has to emit a useless
+ // check and dead code.
+ // To avoid that without making the runtime check slower, explicitly promise
+ // to the compiler that is_in_brp_pool will always be false for nullptr.
+ //
+ // This condition would look nicer and might also theoretically be nicer for
+ // the optimizer if it was written as "if (!address) { ... }", but
+ // LLVM currently has issues with optimizing that away properly; see:
+ // https://bugs.llvm.org/show_bug.cgi?id=49403
+ // https://reviews.llvm.org/D97848
+ // https://chromium-review.googlesource.com/c/chromium/src/+/2727400/2/base/memory/checked_ptr.h#120
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ GURL_CHECK(address || !is_in_brp_pool);
+#endif
+#if HAS_BUILTIN(__builtin_assume)
+ __builtin_assume(address || !is_in_brp_pool);
+#endif
+
+ // There may be pointers immediately after the allocation, e.g.
+ // {
+ // // Assume this allocation happens outside of PartitionAlloc.
+ // raw_ptr<T> ptr = new T[20];
+ // for (size_t i = 0; i < 20; i ++) { ptr++; }
+ // }
+ //
+ // Such pointers are *not* at risk of accidentally falling into BRP pool,
+ // because:
+ // 1) On 64-bit systems, BRP pool is preceded by a forbidden region.
+ // 2) On 32-bit systems, the guard pages and metadata of super pages in BRP
+ // pool aren't considered to be part of that pool.
+ //
+ // This allows us to make a stronger assertion that if
+ // IsManagedByPartitionAllocBRPPool returns true for a valid pointer,
+ // it must be at least partition page away from the beginning of a super
+ // page.
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ if (is_in_brp_pool) {
+ CheckThatAddressIsntWithinFirstPartitionPage(address);
+ }
+#endif
+
+ return is_in_brp_pool;
+ }
+
+ // Wraps a pointer.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* WrapRawPtr(T* ptr) {
+ uintptr_t address = reinterpret_cast<uintptr_t>(ptr);
+ if (IsSupportedAndNotNull(address)) {
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ GURL_CHECK(ptr != nullptr);
+#endif
+ AcquireInternal(address);
+ }
+#if !defined(PA_HAS_64_BITS_POINTERS)
+ else {
+ AddressPoolManagerBitmap::BanSuperPageFromBRPPool(address);
+ }
+#endif
+
+ return ptr;
+ }
+
+ // Notifies the allocator when a wrapped pointer is being removed or replaced.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES void ReleaseWrappedPtr(T* wrapped_ptr) {
+ uintptr_t address = reinterpret_cast<uintptr_t>(wrapped_ptr);
+ if (IsSupportedAndNotNull(address)) {
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ GURL_CHECK(wrapped_ptr != nullptr);
+#endif
+ ReleaseInternal(address);
+ }
+ // We are unable to counteract BanSuperPageFromBRPPool(), called from
+ // WrapRawPtr(). We only use one bit per super-page and, thus can't tell if
+ // there's more than one associated raw_ptr<T> at a given time. The risk of
+ // exhausting the entire address space is minuscule, therefore, we couldn't
+ // resist the perf gain of a single relaxed store (in the above mentioned
+ // function) over much more expensive two CAS operations, which we'd have to
+ // use if we were to un-ban a super-page.
+ }
+
+ // Unwraps the pointer, while asserting that memory hasn't been freed. The
+ // function is allowed to crash on nullptr.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForDereference(
+ T* wrapped_ptr) {
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ uintptr_t address = reinterpret_cast<uintptr_t>(wrapped_ptr);
+ if (IsSupportedAndNotNull(address)) {
+ GURL_CHECK(wrapped_ptr != nullptr);
+ GURL_CHECK(IsPointeeAlive(address));
+ }
+#endif
+ return wrapped_ptr;
+ }
+
+ // Unwraps the pointer, while asserting that memory hasn't been freed. The
+ // function must handle nullptr gracefully.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForExtraction(
+ T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // Unwraps the pointer, without making an assertion on whether memory was
+ // freed or not.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* UnsafelyUnwrapPtrForComparison(
+ T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // Upcasts the wrapped pointer.
+ template <typename To, typename From>
+ static RAW_PTR_FUNC_ATTRIBUTES constexpr To* Upcast(From* wrapped_ptr) {
+ static_assert(std::is_convertible<From*, To*>::value,
+ "From must be convertible to To.");
+ // Note, this cast may change the address if upcasting to base that lies in
+ // the middle of the derived object.
+ return wrapped_ptr;
+ }
+
+ // Advance the wrapped pointer by |delta| bytes.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* Advance(T* wrapped_ptr,
+ ptrdiff_t delta_elem) {
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ uintptr_t address = reinterpret_cast<uintptr_t>(wrapped_ptr);
+ if (IsSupportedAndNotNull(address))
+ GURL_CHECK(IsValidDelta(address, delta_elem * sizeof(T)));
+#endif
+ T* new_wrapped_ptr = WrapRawPtr(wrapped_ptr + delta_elem);
+ ReleaseWrappedPtr(wrapped_ptr);
+ return new_wrapped_ptr;
+ }
+
+ // Returns a copy of a wrapped pointer, without making an assertion on whether
+ // memory was freed or not.
+ // This method increments the reference count of the allocation slot.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* Duplicate(T* wrapped_ptr) {
+ return WrapRawPtr(wrapped_ptr);
+ }
+
+ // This is for accounting only, used by unit tests.
+ static RAW_PTR_FUNC_ATTRIBUTES void IncrementSwapCountForTest() {}
+ static RAW_PTR_FUNC_ATTRIBUTES void
+ IncrementPointerToMemberOperatorCountForTest() {}
+
+ private:
+ // We've evaluated several strategies (inline nothing, various parts, or
+ // everything in |Wrap()| and |Release()|) using the Speedometer2 benchmark
+ // to measure performance. The best results were obtained when only the
+ // lightweight |IsManagedByPartitionAllocBRPPool()| check was inlined.
+ // Therefore, we've extracted the rest into the functions below and marked
+ // them as NOINLINE to prevent unintended LTO effects.
+ static BASE_EXPORT NOINLINE void AcquireInternal(uintptr_t address);
+ static BASE_EXPORT NOINLINE void ReleaseInternal(uintptr_t address);
+ static BASE_EXPORT NOINLINE bool IsPointeeAlive(uintptr_t address);
+ static BASE_EXPORT NOINLINE bool IsValidDelta(uintptr_t address,
+ ptrdiff_t delta_in_bytes);
+};
+
+#endif // BUILDFLAG(USE_BACKUP_REF_PTR)
+
+// Implementation that allows us to detect BackupRefPtr problems in ASan builds.
+struct AsanBackupRefPtrImpl {
+ // Wraps a pointer.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* WrapRawPtr(T* ptr) {
+ AsanCheckIfValidInstantiation(ptr);
+ return ptr;
+ }
+
+ // Notifies the allocator when a wrapped pointer is being removed or replaced.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES void ReleaseWrappedPtr(T*) {}
+
+ // Unwraps the pointer, while asserting that memory hasn't been freed. The
+ // function is allowed to crash on nullptr.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForDereference(
+ T* wrapped_ptr) {
+ AsanCheckIfValidDereference(wrapped_ptr);
+ return wrapped_ptr;
+ }
+
+ // Unwraps the pointer, while asserting that memory hasn't been freed. The
+ // function must handle nullptr gracefully.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* SafelyUnwrapPtrForExtraction(
+ T* wrapped_ptr) {
+ AsanCheckIfValidExtraction(wrapped_ptr);
+ return wrapped_ptr;
+ }
+
+ // Unwraps the pointer, without making an assertion on whether memory was
+ // freed or not.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* UnsafelyUnwrapPtrForComparison(
+ T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // Upcasts the wrapped pointer.
+ template <typename To, typename From>
+ static RAW_PTR_FUNC_ATTRIBUTES constexpr To* Upcast(From* wrapped_ptr) {
+ static_assert(std::is_convertible<From*, To*>::value,
+ "From must be convertible to To.");
+ // Note, this cast may change the address if upcasting to base that lies in
+ // the middle of the derived object.
+ return wrapped_ptr;
+ }
+
+ // Advance the wrapped pointer by |delta| bytes.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* Advance(T* wrapped_ptr,
+ ptrdiff_t delta_elems) {
+ return wrapped_ptr + delta_elems;
+ }
+
+ // Returns a copy of a wrapped pointer, without making an assertion on whether
+ // memory was freed or not.
+ template <typename T>
+ static RAW_PTR_FUNC_ATTRIBUTES T* Duplicate(T* wrapped_ptr) {
+ return wrapped_ptr;
+ }
+
+ // This is for accounting only, used by unit tests.
+ static RAW_PTR_FUNC_ATTRIBUTES void IncrementSwapCountForTest() {}
+ static RAW_PTR_FUNC_ATTRIBUTES void
+ IncrementPointerToMemberOperatorCountForTest() {}
+
+ private:
+ static BASE_EXPORT NOINLINE void AsanCheckIfValidInstantiation(
+ void const volatile* ptr);
+ static BASE_EXPORT NOINLINE void AsanCheckIfValidDereference(
+ void const volatile* ptr);
+ static BASE_EXPORT NOINLINE void AsanCheckIfValidExtraction(
+ void const volatile* ptr);
+};
+
+} // namespace internal
+
+namespace raw_ptr_traits {
+
+// IsSupportedType<T>::value answers whether raw_ptr<T> 1) compiles and 2) is
+// always safe at runtime. Templates that may end up using `raw_ptr<T>` should
+// use IsSupportedType to ensure that raw_ptr is not used with unsupported
+// types. As an example, see how gurl_base::internal::StorageTraits uses
+// IsSupportedType as a condition for using gurl_base::internal::UnretainedWrapper
+// (which has a `ptr_` field that will become `raw_ptr<T>` after the Big
+// Rewrite).
+template <typename T, typename SFINAE = void>
+struct IsSupportedType {
+ static constexpr bool value = true;
+};
+
+// raw_ptr<T> is not compatible with function pointer types. Also, they don't
+// even need the raw_ptr protection, because they don't point on heap.
+template <typename T>
+struct IsSupportedType<T, std::enable_if_t<std::is_function<T>::value>> {
+ static constexpr bool value = false;
+};
+
+// This section excludes some types from raw_ptr<T> to avoid them from being
+// used inside gurl_base::Unretained in performance sensitive places. These were
+// identified from sampling profiler data. See crbug.com/1287151 for more info.
+template <>
+struct IsSupportedType<cc::Scheduler> {
+ static constexpr bool value = false;
+};
+template <>
+struct IsSupportedType<gurl_base::internal::DelayTimerBase> {
+ static constexpr bool value = false;
+};
+template <>
+struct IsSupportedType<content::responsiveness::Calculator> {
+ static constexpr bool value = false;
+};
+
+#if __OBJC__
+// raw_ptr<T> is not compatible with pointers to Objective-C classes for a
+// multitude of reasons. They may fail to compile in many cases, and wouldn't
+// work well with tagged pointers. Anyway, Objective-C objects have their own
+// way of tracking lifespan, hence don't need the raw_ptr protection as much.
+//
+// Such pointers are detected by checking if they're convertible to |id| type.
+template <typename T>
+struct IsSupportedType<T,
+ std::enable_if_t<std::is_convertible<T*, id>::value>> {
+ static constexpr bool value = false;
+};
+#endif // __OBJC__
+
+#if BUILDFLAG(IS_WIN)
+// raw_ptr<HWND__> is unsafe at runtime - if the handle happens to also
+// represent a valid pointer into a PartitionAlloc-managed region then it can
+// lead to manipulating random memory when treating it as BackupRefPtr
+// ref-count. See also https://crbug.com/1262017.
+//
+// TODO(https://crbug.com/1262017): Cover other handle types like HANDLE,
+// HLOCAL, HINTERNET, or HDEVINFO. Maybe we should avoid using raw_ptr<T> when
+// T=void (as is the case in these handle types). OTOH, explicit,
+// non-template-based raw_ptr<void> should be allowed. Maybe this can be solved
+// by having 2 traits: IsPointeeAlwaysSafe (to be used in templates) and
+// IsPointeeUsuallySafe (to be used in the static_assert in raw_ptr). The
+// upside of this approach is that it will safely handle gurl_base::Bind closing over
+// HANDLE. The downside of this approach is that gurl_base::Bind closing over a
+// void* pointer will not get UaF protection.
+#define CHROME_WINDOWS_HANDLE_TYPE(name) \
+ template <> \
+ struct IsSupportedType<name##__, void> { \
+ static constexpr bool value = false; \
+ };
+#include "base/win/win_handle_types_list.inc"
+#undef CHROME_WINDOWS_HANDLE_TYPE
+#endif
+
+} // namespace raw_ptr_traits
+
+// `raw_ptr<T>` is a non-owning smart pointer that has improved memory-safety
+// over raw pointers. It behaves just like a raw pointer on platforms where
+// USE_BACKUP_REF_PTR is off, and almost like one when it's on (the main
+// difference is that it's zero-initialized and cleared on destruction and
+// move). Unlike `std::unique_ptr<T>`, `gurl_base::scoped_refptr<T>`, etc., it
+// doesn’t manage ownership or lifetime of an allocated object - you are still
+// responsible for freeing the object when no longer used, just as you would
+// with a raw C++ pointer.
+//
+// Compared to a raw C++ pointer, on platforms where USE_BACKUP_REF_PTR is on,
+// `raw_ptr<T>` incurs additional performance overhead for initialization,
+// destruction, and assignment (including `ptr++` and `ptr += ...`). There is
+// no overhead when dereferencing a pointer.
+//
+// `raw_ptr<T>` is beneficial for security, because it can prevent a significant
+// percentage of Use-after-Free (UaF) bugs from being exploitable. `raw_ptr<T>`
+// has limited impact on stability - dereferencing a dangling pointer remains
+// Undefined Behavior. Note that the security protection is not yet enabled by
+// default.
+//
+// raw_ptr<T> is marked as [[gsl::Pointer]] which allows the compiler to catch
+// some bugs where the raw_ptr holds a dangling pointer to a temporary object.
+// However the [[gsl::Pointer]] analysis expects that such types do not have a
+// non-default move constructor/assignment. Thus, it's possible to get an error
+// where the pointer is not actually dangling, and have to work around the
+// compiler. We have not managed to construct such an example in Chromium yet.
+template <typename T,
+#if BUILDFLAG(USE_BACKUP_REF_PTR)
+ typename Impl = internal::BackupRefPtrImpl>
+#elif BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
+ typename Impl = internal::AsanBackupRefPtrImpl>
+#else
+ typename Impl = internal::RawPtrNoOpImpl>
+#endif
+class TRIVIAL_ABI GSL_POINTER raw_ptr {
+ public:
+ static_assert(raw_ptr_traits::IsSupportedType<T>::value,
+ "raw_ptr<T> doesn't work with this kind of pointee type T");
+
+#if BUILDFLAG(USE_BACKUP_REF_PTR)
+ // BackupRefPtr requires a non-trivial default constructor, destructor, etc.
+ constexpr RAW_PTR_FUNC_ATTRIBUTES raw_ptr() noexcept
+ : wrapped_ptr_(nullptr) {}
+
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr(const raw_ptr& p) noexcept
+ : wrapped_ptr_(Impl::Duplicate(p.wrapped_ptr_)) {}
+
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr(raw_ptr&& p) noexcept {
+ wrapped_ptr_ = p.wrapped_ptr_;
+ p.wrapped_ptr_ = nullptr;
+ }
+
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(const raw_ptr& p) {
+ // Duplicate before releasing, in case the pointer is assigned to itself.
+ T* new_ptr = Impl::Duplicate(p.wrapped_ptr_);
+ Impl::ReleaseWrappedPtr(wrapped_ptr_);
+ wrapped_ptr_ = new_ptr;
+ return *this;
+ }
+
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(raw_ptr&& p) {
+ if (LIKELY(this != &p)) {
+ Impl::ReleaseWrappedPtr(wrapped_ptr_);
+ wrapped_ptr_ = p.wrapped_ptr_;
+ p.wrapped_ptr_ = nullptr;
+ }
+ return *this;
+ }
+
+ RAW_PTR_FUNC_ATTRIBUTES ~raw_ptr() noexcept {
+ Impl::ReleaseWrappedPtr(wrapped_ptr_);
+ // Work around external issues where raw_ptr is used after destruction.
+ wrapped_ptr_ = nullptr;
+ }
+
+#else // BUILDFLAG(USE_BACKUP_REF_PTR)
+
+ // raw_ptr can be trivially default constructed (leaving |wrapped_ptr_|
+ // uninitialized). This is needed for compatibility with raw pointers.
+ //
+ // TODO(lukasza): Always initialize |wrapped_ptr_|. Fix resulting build
+ // errors. Analyze performance impact.
+ constexpr RAW_PTR_FUNC_ATTRIBUTES raw_ptr() noexcept = default;
+
+ // In addition to nullptr_t ctor above, raw_ptr needs to have these
+ // as |=default| or |constexpr| to avoid hitting -Wglobal-constructors in
+ // cases like this:
+ // struct SomeStruct { int int_field; raw_ptr<int> ptr_field; };
+ // SomeStruct g_global_var = { 123, nullptr };
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr(const raw_ptr&) noexcept = default;
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr(raw_ptr&&) noexcept = default;
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(const raw_ptr&) noexcept = default;
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(raw_ptr&&) noexcept = default;
+
+ RAW_PTR_FUNC_ATTRIBUTES ~raw_ptr() = default;
+
+#endif // BUILDFLAG(USE_BACKUP_REF_PTR)
+
+ // Deliberately implicit, because raw_ptr is supposed to resemble raw ptr.
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ constexpr RAW_PTR_FUNC_ATTRIBUTES raw_ptr(std::nullptr_t) noexcept
+ : wrapped_ptr_(nullptr) {}
+
+ // Deliberately implicit, because raw_ptr is supposed to resemble raw ptr.
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr(T* p) noexcept
+ : wrapped_ptr_(Impl::WrapRawPtr(p)) {}
+
+ // Deliberately implicit in order to support implicit upcast.
+ template <typename U,
+ typename Unused = std::enable_if_t<
+ std::is_convertible<U*, T*>::value &&
+ !std::is_void<typename std::remove_cv<T>::type>::value>>
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr(const raw_ptr<U, Impl>& ptr) noexcept
+ : wrapped_ptr_(
+ Impl::Duplicate(Impl::template Upcast<T, U>(ptr.wrapped_ptr_))) {}
+ // Deliberately implicit in order to support implicit upcast.
+ template <typename U,
+ typename Unused = std::enable_if_t<
+ std::is_convertible<U*, T*>::value &&
+ !std::is_void<typename std::remove_cv<T>::type>::value>>
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr(raw_ptr<U, Impl>&& ptr) noexcept
+ : wrapped_ptr_(Impl::template Upcast<T, U>(ptr.wrapped_ptr_)) {
+#if BUILDFLAG(USE_BACKUP_REF_PTR)
+ ptr.wrapped_ptr_ = nullptr;
+#endif
+ }
+
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(std::nullptr_t) noexcept {
+ Impl::ReleaseWrappedPtr(wrapped_ptr_);
+ wrapped_ptr_ = nullptr;
+ return *this;
+ }
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(T* p) noexcept {
+ Impl::ReleaseWrappedPtr(wrapped_ptr_);
+ wrapped_ptr_ = Impl::WrapRawPtr(p);
+ return *this;
+ }
+
+ // Upcast assignment
+ template <typename U,
+ typename Unused = std::enable_if_t<
+ std::is_convertible<U*, T*>::value &&
+ !std::is_void<typename std::remove_cv<T>::type>::value>>
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(
+ const raw_ptr<U, Impl>& ptr) noexcept {
+ // Make sure that pointer isn't assigned to itself (look at pointer address,
+ // not its value).
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ GURL_CHECK(reinterpret_cast<uintptr_t>(this) !=
+ reinterpret_cast<uintptr_t>(&ptr));
+#endif
+ Impl::ReleaseWrappedPtr(wrapped_ptr_);
+ wrapped_ptr_ =
+ Impl::Duplicate(Impl::template Upcast<T, U>(ptr.wrapped_ptr_));
+ return *this;
+ }
+ template <typename U,
+ typename Unused = std::enable_if_t<
+ std::is_convertible<U*, T*>::value &&
+ !std::is_void<typename std::remove_cv<T>::type>::value>>
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator=(raw_ptr<U, Impl>&& ptr) noexcept {
+ // Make sure that pointer isn't assigned to itself (look at pointer address,
+ // not its value).
+#if GURL_DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
+ GURL_CHECK(reinterpret_cast<uintptr_t>(this) !=
+ reinterpret_cast<uintptr_t>(&ptr));
+#endif
+ Impl::ReleaseWrappedPtr(wrapped_ptr_);
+ wrapped_ptr_ = Impl::template Upcast<T, U>(ptr.wrapped_ptr_);
+#if BUILDFLAG(USE_BACKUP_REF_PTR)
+ ptr.wrapped_ptr_ = nullptr;
+#endif
+ return *this;
+ }
+
+ // Avoid using. The goal of raw_ptr is to be as close to raw pointer as
+ // possible, so use it only if absolutely necessary (e.g. for const_cast).
+ RAW_PTR_FUNC_ATTRIBUTES T* get() const { return GetForExtraction(); }
+
+ explicit RAW_PTR_FUNC_ATTRIBUTES operator bool() const {
+ return !!wrapped_ptr_;
+ }
+
+ template <typename U = T,
+ typename Unused = std::enable_if_t<
+ !std::is_void<typename std::remove_cv<U>::type>::value>>
+ RAW_PTR_FUNC_ATTRIBUTES U& operator*() const {
+ return *GetForDereference();
+ }
+ RAW_PTR_FUNC_ATTRIBUTES T* operator->() const { return GetForDereference(); }
+
+ // Disables `(my_raw_ptr->*pmf)(...)` as a workaround for
+ // the ICE in GCC parsing the code, reported at
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103455
+ template <typename PMF>
+ void operator->*(PMF) const = delete;
+
+ // Deliberately implicit, because raw_ptr is supposed to resemble raw ptr.
+ // NOLINTNEXTLINE(runtime/explicit)
+ RAW_PTR_FUNC_ATTRIBUTES operator T*() const { return GetForExtraction(); }
+ template <typename U>
+ explicit RAW_PTR_FUNC_ATTRIBUTES operator U*() const {
+ // This operator may be invoked from static_cast, meaning the types may not
+ // be implicitly convertible, hence the need for static_cast here.
+ return static_cast<U*>(GetForExtraction());
+ }
+
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator++() {
+ wrapped_ptr_ = Impl::Advance(wrapped_ptr_, 1);
+ return *this;
+ }
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator--() {
+ wrapped_ptr_ = Impl::Advance(wrapped_ptr_, -1);
+ return *this;
+ }
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr operator++(int /* post_increment */) {
+ raw_ptr result = *this;
+ ++(*this);
+ return result;
+ }
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr operator--(int /* post_decrement */) {
+ raw_ptr result = *this;
+ --(*this);
+ return result;
+ }
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator+=(ptrdiff_t delta_elems) {
+ wrapped_ptr_ = Impl::Advance(wrapped_ptr_, delta_elems);
+ return *this;
+ }
+ RAW_PTR_FUNC_ATTRIBUTES raw_ptr& operator-=(ptrdiff_t delta_elems) {
+ return *this += -delta_elems;
+ }
+
+ // Stop referencing the underlying pointer and free its memory. Compared to
+ // raw delete calls, this avoids the raw_ptr to be temporarily dangling
+ // during the free operation, which will lead to taking the slower path that
+ // involves quarantine.
+ RAW_PTR_FUNC_ATTRIBUTES void ClearAndDelete() noexcept {
+ T* ptr = wrapped_ptr_;
+ operator=(nullptr);
+ delete ptr;
+ }
+ RAW_PTR_FUNC_ATTRIBUTES void ClearAndDeleteArray() noexcept {
+ T* ptr = wrapped_ptr_;
+ operator=(nullptr);
+ delete[] ptr;
+ }
+
+ // Comparison operators between raw_ptr and raw_ptr<U>/U*/std::nullptr_t.
+ // Strictly speaking, it is not necessary to provide these: the compiler can
+ // use the conversion operator implicitly to allow comparisons to fall back to
+ // comparisons between raw pointers. However, `operator T*`/`operator U*` may
+ // perform safety checks with a higher runtime cost, so to avoid this, provide
+ // explicit comparison operators for all combinations of parameters.
+
+ // Comparisons between `raw_ptr`s. This unusual declaration and separate
+ // definition below is because `GetForComparison()` is a private method. The
+ // more conventional approach of defining a comparison operator between
+ // `raw_ptr` and `raw_ptr<U>` in the friend declaration itself does not work,
+ // because a comparison operator defined inline would not be allowed to call
+ // `raw_ptr<U>`'s private `GetForComparison()` method.
+ template <typename U, typename V, typename I>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator==(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs);
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator!=(const raw_ptr& lhs,
+ const raw_ptr<U, Impl>& rhs) {
+ return !(lhs == rhs);
+ }
+ template <typename U, typename V, typename I>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator<(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs);
+ template <typename U, typename V, typename I>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator>(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs);
+ template <typename U, typename V, typename I>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator<=(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs);
+ template <typename U, typename V, typename I>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator>=(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs);
+
+ // Comparisons with U*. These operators also handle the case where the RHS is
+ // T*.
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator==(const raw_ptr& lhs, U* rhs) {
+ return lhs.GetForComparison() == rhs;
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator!=(const raw_ptr& lhs, U* rhs) {
+ return !(lhs == rhs);
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator==(U* lhs, const raw_ptr& rhs) {
+ return rhs == lhs; // Reverse order to call the operator above.
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator!=(U* lhs, const raw_ptr& rhs) {
+ return rhs != lhs; // Reverse order to call the operator above.
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator<(const raw_ptr& lhs, U* rhs) {
+ return lhs.GetForComparison() < rhs;
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator<=(const raw_ptr& lhs, U* rhs) {
+ return lhs.GetForComparison() <= rhs;
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator>(const raw_ptr& lhs, U* rhs) {
+ return lhs.GetForComparison() > rhs;
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator>=(const raw_ptr& lhs, U* rhs) {
+ return lhs.GetForComparison() >= rhs;
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator<(U* lhs, const raw_ptr& rhs) {
+ return lhs < rhs.GetForComparison();
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator<=(U* lhs, const raw_ptr& rhs) {
+ return lhs <= rhs.GetForComparison();
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator>(U* lhs, const raw_ptr& rhs) {
+ return lhs > rhs.GetForComparison();
+ }
+ template <typename U>
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator>=(U* lhs, const raw_ptr& rhs) {
+ return lhs >= rhs.GetForComparison();
+ }
+
+ // Comparisons with `std::nullptr_t`.
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator==(const raw_ptr& lhs,
+ std::nullptr_t) {
+ return !lhs;
+ }
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator!=(const raw_ptr& lhs,
+ std::nullptr_t) {
+ return !!lhs; // Use !! otherwise the costly implicit cast will be used.
+ }
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator==(std::nullptr_t,
+ const raw_ptr& rhs) {
+ return !rhs;
+ }
+ friend RAW_PTR_FUNC_ATTRIBUTES bool operator!=(std::nullptr_t,
+ const raw_ptr& rhs) {
+ return !!rhs; // Use !! otherwise the costly implicit cast will be used.
+ }
+
+ friend RAW_PTR_FUNC_ATTRIBUTES void swap(raw_ptr& lhs,
+ raw_ptr& rhs) noexcept {
+ Impl::IncrementSwapCountForTest();
+ std::swap(lhs.wrapped_ptr_, rhs.wrapped_ptr_);
+ }
+
+ private:
+ // This getter is meant for situations where the pointer is meant to be
+ // dereferenced. It is allowed to crash on nullptr (it may or may not),
+ // because it knows that the caller will crash on nullptr.
+ RAW_PTR_FUNC_ATTRIBUTES T* GetForDereference() const {
+ return Impl::SafelyUnwrapPtrForDereference(wrapped_ptr_);
+ }
+ // This getter is meant for situations where the raw pointer is meant to be
+ // extracted outside of this class, but not necessarily with an intention to
+ // dereference. It mustn't crash on nullptr.
+ RAW_PTR_FUNC_ATTRIBUTES T* GetForExtraction() const {
+ return Impl::SafelyUnwrapPtrForExtraction(wrapped_ptr_);
+ }
+ // This getter is meant *only* for situations where the pointer is meant to be
+ // compared (guaranteeing no dereference or extraction outside of this class).
+ // Any verifications can and should be skipped for performance reasons.
+ RAW_PTR_FUNC_ATTRIBUTES T* GetForComparison() const {
+ return Impl::UnsafelyUnwrapPtrForComparison(wrapped_ptr_);
+ }
+
+ T* wrapped_ptr_;
+
+ template <typename U, typename V>
+ friend class raw_ptr;
+};
+
+template <typename U, typename V, typename I>
+RAW_PTR_FUNC_ATTRIBUTES bool operator==(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs) {
+ return lhs.GetForComparison() == rhs.GetForComparison();
+}
+
+template <typename U, typename V, typename I>
+RAW_PTR_FUNC_ATTRIBUTES bool operator<(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs) {
+ return lhs.GetForComparison() < rhs.GetForComparison();
+}
+
+template <typename U, typename V, typename I>
+RAW_PTR_FUNC_ATTRIBUTES bool operator>(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs) {
+ return lhs.GetForComparison() > rhs.GetForComparison();
+}
+
+template <typename U, typename V, typename I>
+RAW_PTR_FUNC_ATTRIBUTES bool operator<=(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs) {
+ return lhs.GetForComparison() <= rhs.GetForComparison();
+}
+
+template <typename U, typename V, typename I>
+RAW_PTR_FUNC_ATTRIBUTES bool operator>=(const raw_ptr<U, I>& lhs,
+ const raw_ptr<V, I>& rhs) {
+ return lhs.GetForComparison() >= rhs.GetForComparison();
+}
+
+} // namespace base
+
+using gurl_base::raw_ptr;
+
+namespace std {
+
+// Override so set/map lookups do not create extra raw_ptr. This also allows
+// dangling pointers to be used for lookup.
+template <typename T, typename I>
+struct less<raw_ptr<T, I>> {
+ using is_transparent = void;
+
+ bool operator()(const raw_ptr<T, I>& lhs, const raw_ptr<T, I>& rhs) const {
+ return lhs < rhs;
+ }
+
+ bool operator()(T* lhs, const raw_ptr<T, I>& rhs) const { return lhs < rhs; }
+
+ bool operator()(const raw_ptr<T, I>& lhs, T* rhs) const { return lhs < rhs; }
+};
+
+} // namespace std
+
+#endif // BASE_MEMORY_RAW_PTR_H_
diff --git a/base/stl_util.h b/base/stl_util.h
index 46e91b9..a9c627d 100644
--- a/base/stl_util.h
+++ b/base/stl_util.h
@@ -10,9 +10,7 @@
#include <algorithm>
#include <forward_list>
#include <iterator>
-#include <tuple>
#include <type_traits>
-#include <utility>
#include "polyfills/base/check.h"
#include "base/ranges/algorithm.h"
@@ -111,166 +109,6 @@
return begin(c) + (it - cbegin(c));
}
-namespace internal {
-
-template <typename Map, typename Key, typename Value>
-std::pair<typename Map::iterator, bool> InsertOrAssignImpl(Map& map,
- Key&& key,
- Value&& value) {
- auto lower = map.lower_bound(key);
- if (lower != map.end() && !map.key_comp()(key, lower->first)) {
- // key already exists, perform assignment.
- lower->second = std::forward<Value>(value);
- return {lower, false};
- }
-
- // key did not yet exist, insert it.
- return {map.emplace_hint(lower, std::forward<Key>(key),
- std::forward<Value>(value)),
- true};
-}
-
-template <typename Map, typename Key, typename Value>
-typename Map::iterator InsertOrAssignImpl(Map& map,
- typename Map::const_iterator hint,
- Key&& key,
- Value&& value) {
- auto&& key_comp = map.key_comp();
- if ((hint == map.begin() || key_comp(std::prev(hint)->first, key))) {
- if (hint == map.end() || key_comp(key, hint->first)) {
- // *(hint - 1) < key < *hint => key did not exist and hint is correct.
- return map.emplace_hint(hint, std::forward<Key>(key),
- std::forward<Value>(value));
- }
-
- if (!key_comp(hint->first, key)) {
- // key == *hint => key already exists and hint is correct.
- auto mutable_hint = ConstCastIterator(map, hint);
- mutable_hint->second = std::forward<Value>(value);
- return mutable_hint;
- }
- }
-
- // hint was not helpful, dispatch to hintless version.
- return InsertOrAssignImpl(map, std::forward<Key>(key),
- std::forward<Value>(value))
- .first;
-}
-
-template <typename Map, typename Key, typename... Args>
-std::pair<typename Map::iterator, bool> TryEmplaceImpl(Map& map,
- Key&& key,
- Args&&... args) {
- auto lower = map.lower_bound(key);
- if (lower != map.end() && !map.key_comp()(key, lower->first)) {
- // key already exists, do nothing.
- return {lower, false};
- }
-
- // key did not yet exist, insert it.
- return {map.emplace_hint(lower, std::piecewise_construct,
- std::forward_as_tuple(std::forward<Key>(key)),
- std::forward_as_tuple(std::forward<Args>(args)...)),
- true};
-}
-
-template <typename Map, typename Key, typename... Args>
-typename Map::iterator TryEmplaceImpl(Map& map,
- typename Map::const_iterator hint,
- Key&& key,
- Args&&... args) {
- auto&& key_comp = map.key_comp();
- if ((hint == map.begin() || key_comp(std::prev(hint)->first, key))) {
- if (hint == map.end() || key_comp(key, hint->first)) {
- // *(hint - 1) < key < *hint => key did not exist and hint is correct.
- return map.emplace_hint(
- hint, std::piecewise_construct,
- std::forward_as_tuple(std::forward<Key>(key)),
- std::forward_as_tuple(std::forward<Args>(args)...));
- }
-
- if (!key_comp(hint->first, key)) {
- // key == *hint => no-op, return correct hint.
- return ConstCastIterator(map, hint);
- }
- }
-
- // hint was not helpful, dispatch to hintless version.
- return TryEmplaceImpl(map, std::forward<Key>(key),
- std::forward<Args>(args)...)
- .first;
-}
-
-} // namespace internal
-
-// Implementation of C++17's std::map::insert_or_assign as a free function.
-template <typename Map, typename Value>
-std::pair<typename Map::iterator, bool>
-InsertOrAssign(Map& map, const typename Map::key_type& key, Value&& value) {
- return internal::InsertOrAssignImpl(map, key, std::forward<Value>(value));
-}
-
-template <typename Map, typename Value>
-std::pair<typename Map::iterator, bool>
-InsertOrAssign(Map& map, typename Map::key_type&& key, Value&& value) {
- return internal::InsertOrAssignImpl(map, std::move(key),
- std::forward<Value>(value));
-}
-
-// Implementation of C++17's std::map::insert_or_assign with hint as a free
-// function.
-template <typename Map, typename Value>
-typename Map::iterator InsertOrAssign(Map& map,
- typename Map::const_iterator hint,
- const typename Map::key_type& key,
- Value&& value) {
- return internal::InsertOrAssignImpl(map, hint, key,
- std::forward<Value>(value));
-}
-
-template <typename Map, typename Value>
-typename Map::iterator InsertOrAssign(Map& map,
- typename Map::const_iterator hint,
- typename Map::key_type&& key,
- Value&& value) {
- return internal::InsertOrAssignImpl(map, hint, std::move(key),
- std::forward<Value>(value));
-}
-
-// Implementation of C++17's std::map::try_emplace as a free function.
-template <typename Map, typename... Args>
-std::pair<typename Map::iterator, bool>
-TryEmplace(Map& map, const typename Map::key_type& key, Args&&... args) {
- return internal::TryEmplaceImpl(map, key, std::forward<Args>(args)...);
-}
-
-template <typename Map, typename... Args>
-std::pair<typename Map::iterator, bool> TryEmplace(Map& map,
- typename Map::key_type&& key,
- Args&&... args) {
- return internal::TryEmplaceImpl(map, std::move(key),
- std::forward<Args>(args)...);
-}
-
-// Implementation of C++17's std::map::try_emplace with hint as a free
-// function.
-template <typename Map, typename... Args>
-typename Map::iterator TryEmplace(Map& map,
- typename Map::const_iterator hint,
- const typename Map::key_type& key,
- Args&&... args) {
- return internal::TryEmplaceImpl(map, hint, key, std::forward<Args>(args)...);
-}
-
-template <typename Map, typename... Args>
-typename Map::iterator TryEmplace(Map& map,
- typename Map::const_iterator hint,
- typename Map::key_type&& key,
- Args&&... args) {
- return internal::TryEmplaceImpl(map, hint, std::move(key),
- std::forward<Args>(args)...);
-}
-
// Returns a new ResultType containing the difference of two sorted containers.
template <typename ResultType, typename Arg1, typename Arg2>
ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) {
diff --git a/base/strings/BUILD b/base/strings/BUILD
deleted file mode 100644
index 257f8f9..0000000
--- a/base/strings/BUILD
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-load("//build_config:build_config.bzl", "build_config")
-load("@rules_cc//cc:defs.bzl", "cc_library")
-
-cc_library(
- name = "strings",
- srcs = [
- "string_piece.cc",
- "string_util.cc",
- "string_util_constants.cc",
- "utf_string_conversion_utils.cc",
- "utf_string_conversions.cc",
- ],
- hdrs = [
- "char_traits.h",
- "string_piece_forward.h",
- "string_piece.h",
- "string_util.h",
- "string_util_internal.h",
- "utf_string_conversions.h",
- "utf_string_conversion_utils.h",
- ] + build_config.strings_hdrs,
- copts = build_config.default_copts,
- visibility = ["//visibility:public"],
- deps = [
- "//base",
- "//base/third_party/icu",
- "//build:build_config",
- "//polyfills",
- ],
-)
diff --git a/base/strings/abseil_string_number_conversions.cc b/base/strings/abseil_string_number_conversions.cc
new file mode 100644
index 0000000..9ab1303
--- /dev/null
+++ b/base/strings/abseil_string_number_conversions.cc
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/strings/abseil_string_number_conversions.h"
+
+#include "base/strings/string_number_conversions_internal.h"
+#include "base/strings/string_piece.h"
+#include "absl/numeric/int128.h"
+
+namespace gurl_base {
+
+bool HexStringToUInt128(StringPiece input, absl::uint128* output) {
+ return internal::HexStringToIntImpl(input, *output);
+}
+
+} // namespace base
diff --git a/base/strings/abseil_string_number_conversions.h b/base/strings/abseil_string_number_conversions.h
new file mode 100644
index 0000000..7eb927d
--- /dev/null
+++ b/base/strings/abseil_string_number_conversions.h
@@ -0,0 +1,24 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_STRINGS_ABSEIL_STRING_NUMBER_CONVERSIONS_H_
+#define BASE_STRINGS_ABSEIL_STRING_NUMBER_CONVERSIONS_H_
+
+#include "polyfills/base/base_export.h"
+#include "base/strings/string_piece_forward.h"
+
+namespace absl {
+class uint128;
+} // namespace absl
+
+namespace gurl_base {
+
+// Best effort conversion, see `gurl_base::StringToInt()` for restrictions.
+// Will only successfully parse hex values that will fit into |output|.
+// The string is not required to start with 0x.
+BASE_EXPORT bool HexStringToUInt128(StringPiece input, absl::uint128* output);
+
+} // namespace base
+
+#endif // BASE_STRINGS_ABSEIL_STRING_NUMBER_CONVERSIONS_H_
diff --git a/base/strings/abseil_string_number_conversions_unittest.cc b/base/strings/abseil_string_number_conversions_unittest.cc
new file mode 100644
index 0000000..3c68cde
--- /dev/null
+++ b/base/strings/abseil_string_number_conversions_unittest.cc
@@ -0,0 +1,102 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/strings/abseil_string_number_conversions.h"
+
+#include <stdint.h>
+
+#include <limits>
+
+#include "base/cxx17_backports.h"
+#include "base/strings/string_piece.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "absl/numeric/int128.h"
+
+namespace gurl_base {
+
+TEST(AbseilStringNumberConversionsTest, HexStringToUInt128) {
+ // Test cases adapted from `StringNumberConversionsTest.HexStringToUint64`.
+ static const struct {
+ std::string input;
+ absl::uint128 output;
+ bool success;
+ } cases[] = {
+ {"0", 0, true},
+ {"42", 66, true},
+ {"-42", 0, false},
+ {"+42", 66, true},
+ {"ffffffffffffffff",
+ absl::MakeUint128(/*high=*/0,
+ /*low=*/std::numeric_limits<uint64_t>::max()),
+ true},
+ {"1ffffffffffffffff",
+ absl::MakeUint128(/*high=*/1,
+ /*low=*/std::numeric_limits<uint64_t>::max()),
+ true},
+ {"7fffffff", INT_MAX, true},
+ {"-80000000", 0, false},
+ {"ffffffff", 0xffffffff, true},
+ {"DeadBeef", 0xdeadbeef, true},
+ {"0x42", 66, true},
+ {"-0x42", 0, false},
+ {"+0x42", 66, true},
+ {"0xffffffffffffffff",
+ absl::MakeUint128(/*high=*/0,
+ /*low=*/std::numeric_limits<uint64_t>::max()),
+ true},
+ {"0x1ffffffffffffffff",
+ absl::MakeUint128(/*high=*/1,
+ /*low=*/std::numeric_limits<uint64_t>::max()),
+ true},
+ {"0x7fffffff", INT_MAX, true},
+ {"-0x80000000", 0, false},
+ {"0xffffffff", 0xffffffff, true},
+ {"0XDeadBeef", 0xdeadbeef, true},
+ {"0x7fffffffffffffffffffffffffffffff",
+ std::numeric_limits<absl::int128>::max(), true},
+ {"-0x8000000000000000", 0, false},
+ {"0x8000000000000000",
+ absl::MakeUint128(/*high=*/0, UINT64_C(0x8000000000000000)), true},
+ {"-0x8000000000000001", 0, false},
+ {"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ std::numeric_limits<absl::uint128>::max(), true},
+ {"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ std::numeric_limits<absl::uint128>::max(), true},
+ {"0x0000000000000000", 0, true},
+ {"0000000000000000", 0, true},
+ {"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ std::numeric_limits<absl::uint128>::max(), false}, // Overflow test.
+ {"0x0f", 15, true},
+ {"0f", 15, true},
+ {" 45", 0x45, false},
+ {"\t\n\v\f\r 0x45", 0x45, false},
+ {" 45", 0x45, false},
+ {"45 ", 0x45, false},
+ {"45:", 0x45, false},
+ {"efgh", 0xef, false},
+ {"0xefgh", 0xef, false},
+ {"hgfe", 0, false},
+ {"-", 0, false},
+ {"", 0, false},
+ {"0x", 0, false},
+ };
+
+ for (const auto& i : cases) {
+ absl::uint128 output = 0;
+ EXPECT_EQ(i.success, HexStringToUInt128(i.input, &output)) << i.input;
+ EXPECT_EQ(i.output, output) << i.input;
+ }
+ // One additional test to verify that conversion of numbers in strings with
+ // embedded NUL characters. The NUL and extra data after it should be
+ // interpreted as junk after the number.
+ const char input[] =
+ "0xc0ffee\0"
+ "9";
+ std::string input_string(input, gurl_base::size(input) - 1);
+ absl::uint128 output;
+ EXPECT_FALSE(HexStringToUInt128(input_string, &output));
+ EXPECT_EQ(0xc0ffeeU, output);
+}
+
+} // namespace base
diff --git a/base/strings/safe_sprintf.cc b/base/strings/safe_sprintf.cc
index c9a69ec..6c9aa19 100644
--- a/base/strings/safe_sprintf.cc
+++ b/base/strings/safe_sprintf.cc
@@ -10,7 +10,7 @@
#include <algorithm>
#include <limits>
-#include "base/macros.h"
+#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#if !defined(NDEBUG)
@@ -117,7 +117,7 @@
// MSVS2013's standard library doesn't mark max() as constexpr yet. cl.exe
// supports static_cast but doesn't really implement constexpr yet so it doesn't
// complain, but clang does.
-#if __cplusplus >= 201103 && !(defined(__clang__) && defined(OS_WIN))
+#if __cplusplus >= 201103 && !(defined(__clang__) && BUILDFLAG(IS_WIN))
static_assert(kSSizeMaxConst ==
static_cast<size_t>(std::numeric_limits<ssize_t>::max()),
"kSSizeMaxConst should be the max value of an ssize_t");
@@ -263,7 +263,7 @@
}
// User-provided buffer that will receive the fully formatted output string.
- char* buffer_;
+ raw_ptr<char> 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/safe_sprintf.h b/base/strings/safe_sprintf.h
index 40cddc5..478275e 100644
--- a/base/strings/safe_sprintf.h
+++ b/base/strings/safe_sprintf.h
@@ -11,7 +11,7 @@
#include "build/build_config.h"
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
+#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
// For ssize_t
#include <unistd.h>
#endif
diff --git a/base/strings/safe_sprintf_unittest.cc b/base/strings/safe_sprintf_unittest.cc
index be8af13..71814b3 100644
--- a/base/strings/safe_sprintf_unittest.cc
+++ b/base/strings/safe_sprintf_unittest.cc
@@ -13,14 +13,13 @@
#include <memory>
#include "polyfills/base/check_op.h"
-#include "base/macros.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
// Death tests on Android are currently very flaky. No need to add more flaky
// tests, as they just make it hard to spot real problems.
// TODO(markus): See if the restrictions on Android can eventually be lifted.
-#if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
+#if defined(GTEST_HAS_DEATH_TEST) && !BUILDFLAG(IS_ANDROID)
#define ALLOW_DEATH_TEST
#endif
diff --git a/base/strings/strcat.h b/base/strings/strcat.h
index fe35447..1cdd708 100644
--- a/base/strings/strcat.h
+++ b/base/strings/strcat.h
@@ -8,12 +8,11 @@
#include <initializer_list>
#include "polyfills/base/base_export.h"
-#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
// Guard against conflict with Win32 API StrCat macro:
// check StrCat wasn't and will not be redefined.
#define StrCat StrCat
@@ -59,14 +58,12 @@
// for this call and generate slightly less code. This is something we can
// explore more in the future.
-BASE_EXPORT std::string StrCat(span<const StringPiece> pieces)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::u16string StrCat(span<const StringPiece16> pieces)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::string StrCat(span<const std::string> pieces)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::u16string StrCat(span<const std::u16string> pieces)
- WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string StrCat(span<const StringPiece> pieces);
+[[nodiscard]] BASE_EXPORT std::u16string StrCat(
+ span<const StringPiece16> pieces);
+[[nodiscard]] BASE_EXPORT std::string StrCat(span<const std::string> pieces);
+[[nodiscard]] BASE_EXPORT std::u16string StrCat(
+ span<const std::u16string> pieces);
// Initializer list forwards to the array version.
inline std::string StrCat(std::initializer_list<StringPiece> pieces) {
@@ -105,7 +102,7 @@
} // namespace base
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
#include "base/strings/strcat_win.h"
#endif
diff --git a/base/strings/strcat_win.h b/base/strings/strcat_win.h
index 70926bc..e32a7e5 100644
--- a/base/strings/strcat_win.h
+++ b/base/strings/strcat_win.h
@@ -9,7 +9,6 @@
#include <string>
#include "polyfills/base/base_export.h"
-#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/strings/string_piece.h"
@@ -25,10 +24,8 @@
StrAppend(dest, make_span(pieces));
}
-BASE_EXPORT std::wstring StrCat(span<const WStringPiece> pieces)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::wstring StrCat(span<const std::wstring> pieces)
- WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::wstring StrCat(span<const WStringPiece> pieces);
+[[nodiscard]] BASE_EXPORT std::wstring StrCat(span<const std::wstring> pieces);
inline std::wstring StrCat(std::initializer_list<WStringPiece> pieces) {
return StrCat(make_span(pieces));
diff --git a/base/strings/string_number_conversions.h b/base/strings/string_number_conversions.h
index d2f8af3..1ef1733 100644
--- a/base/strings/string_number_conversions.h
+++ b/base/strings/string_number_conversions.h
@@ -149,7 +149,7 @@
} // namespace base
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
#include "base/strings/string_number_conversions_win.h"
#endif
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index f01722d..8d7f2c5 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -31,6 +31,7 @@
#include "polyfills/base/base_export.h"
#include "polyfills/base/check_op.h"
+#include "base/compiler_specific.h"
#include "base/strings/char_traits.h"
#include "base/strings/string_piece_forward.h"
#include "build/build_config.h"
@@ -96,7 +97,7 @@
// Mirrors the C++17 version of std::basic_string_view<> as closely as possible,
// except where noted below.
template <typename CharT, typename Traits>
-class BasicStringPiece {
+class GSL_POINTER BasicStringPiece {
public:
using traits_type = Traits;
using value_type = CharT;
@@ -185,9 +186,7 @@
return std::numeric_limits<size_type>::max() / sizeof(CharT);
}
- constexpr bool empty() const noexcept WARN_UNUSED_RESULT {
- return size() == 0;
- }
+ [[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
constexpr void remove_prefix(size_type n) {
// Intentional STL deviation: Bounds-check instead of UB.
diff --git a/base/strings/string_piece_forward.h b/base/strings/string_piece_forward.h
index ce7e489..e257528 100644
--- a/base/strings/string_piece_forward.h
+++ b/base/strings/string_piece_forward.h
@@ -7,7 +7,7 @@
#ifndef BASE_STRINGS_STRING_PIECE_FORWARD_H_
#define BASE_STRINGS_STRING_PIECE_FORWARD_H_
-#include <string>
+#include <iosfwd>
namespace gurl_base {
diff --git a/base/strings/string_piece_rust.h b/base/strings/string_piece_rust.h
new file mode 100644
index 0000000..1542c17
--- /dev/null
+++ b/base/strings/string_piece_rust.h
@@ -0,0 +1,38 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_STRINGS_STRING_PIECE_RUST_H_
+#define BASE_STRINGS_STRING_PIECE_RUST_H_
+
+#include <stdint.h>
+
+#include "base/strings/string_piece.h"
+#include "third_party/rust/cxx/v1/crate/include/cxx.h"
+
+namespace gurl_base {
+
+// Create a Rust str from a gurl_base::BasicStringPiece. This will call std::abort
+// if there is any invalid UTF8. If you're concerned about this, then
+// instead use StringPieceToRustSlice and convert the data to a string on
+// the Rust side (or pass in a std::string).
+inline rust::Str StringPieceToRustStrUTF8(StringPiece string_piece) {
+ return rust::Str(string_piece.data(), string_piece.size());
+}
+
+// Create a Rust slice from a StringPiece. No UTF8 check is performed.
+inline rust::Slice<const uint8_t> StringPieceToRustSlice(
+ StringPiece string_piece) {
+ return rust::Slice<const uint8_t>(
+ reinterpret_cast<const uint8_t*>(string_piece.data()),
+ string_piece.length() * sizeof(StringPiece::value_type));
+}
+
+// Create a StringPiece from a Rust str.
+inline StringPiece RustStrToStringPiece(rust::Str str) {
+ return StringPiece(str.data(), str.size());
+}
+
+} // namespace base
+
+#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
new file mode 100644
index 0000000..bf860fb
--- /dev/null
+++ b/base/strings/string_piece_rust_unittest.cc
@@ -0,0 +1,30 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/strings/string_piece_rust.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gurl_base {
+namespace {
+
+TEST(BaseStringPieceRustTest, StrRoundTrip) {
+ std::string data = "hello";
+ StringPiece data_piece(data);
+ rust::Str rust_str = StringPieceToRustStrUTF8(data_piece);
+ EXPECT_EQ(5ul, rust_str.length());
+ StringPiece data_piece2 = RustStrToStringPiece(rust_str);
+ EXPECT_EQ(data_piece, data_piece2);
+}
+
+TEST(BaseStringPieceRustTest, StrToSlice) {
+ std::string data = "hello";
+ StringPiece data_piece(data);
+ rust::Slice<const uint8_t> rust_slice = StringPieceToRustSlice(data_piece);
+ EXPECT_EQ(5ul, rust_slice.length());
+ EXPECT_EQ('e', rust_slice[1]);
+}
+
+} // namespace
+} // namespace base
diff --git a/base/strings/string_split.h b/base/strings/string_split.h
index d7f56a6..b464f08 100644
--- a/base/strings/string_split.h
+++ b/base/strings/string_split.h
@@ -45,16 +45,16 @@
//
// std::vector<std::string> tokens = gurl_base::SplitString(
// input, ",;", gurl_base::KEEP_WHITESPACE, gurl_base::SPLIT_WANT_ALL);
-BASE_EXPORT std::vector<std::string> SplitString(StringPiece input,
- StringPiece separators,
- WhitespaceHandling whitespace,
- SplitResult result_type)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::vector<std::u16string> SplitString(
+[[nodiscard]] BASE_EXPORT std::vector<std::string> SplitString(
+ StringPiece input,
+ StringPiece separators,
+ WhitespaceHandling whitespace,
+ SplitResult result_type);
+[[nodiscard]] BASE_EXPORT std::vector<std::u16string> SplitString(
StringPiece16 input,
StringPiece16 separators,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
+ SplitResult result_type);
// Like SplitString above except it returns a vector of StringPieces which
// reference the original buffer without copying. Although you have to be
@@ -70,16 +70,16 @@
// gurl_base::KEEP_WHITESPACE,
// gurl_base::SPLIT_WANT_NONEMPTY)) {
// ...
-BASE_EXPORT std::vector<StringPiece> SplitStringPiece(
+[[nodiscard]] BASE_EXPORT std::vector<StringPiece> SplitStringPiece(
StringPiece input,
StringPiece separators,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
-BASE_EXPORT std::vector<StringPiece16> SplitStringPiece(
+ SplitResult result_type);
+[[nodiscard]] BASE_EXPORT std::vector<StringPiece16> SplitStringPiece(
StringPiece16 input,
StringPiece16 separators,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
+ SplitResult result_type);
using StringPairs = std::vector<std::pair<std::string, std::string>>;
@@ -102,16 +102,16 @@
// Similar to SplitString, but use a substring delimiter instead of a list of
// characters that are all possible delimiters.
-BASE_EXPORT std::vector<std::u16string> SplitStringUsingSubstr(
+[[nodiscard]] BASE_EXPORT std::vector<std::u16string> SplitStringUsingSubstr(
StringPiece16 input,
StringPiece16 delimiter,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
-BASE_EXPORT std::vector<std::string> SplitStringUsingSubstr(
+ SplitResult result_type);
+[[nodiscard]] BASE_EXPORT std::vector<std::string> SplitStringUsingSubstr(
StringPiece input,
StringPiece delimiter,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
+ SplitResult result_type);
// Like SplitStringUsingSubstr above except it returns a vector of StringPieces
// which reference the original buffer without copying. Although you have to be
@@ -125,20 +125,20 @@
// gurl_base::KEEP_WHITESPACE,
// gurl_base::SPLIT_WANT_NONEMPTY)) {
// ...
-BASE_EXPORT std::vector<StringPiece16> SplitStringPieceUsingSubstr(
- StringPiece16 input,
- StringPiece16 delimiter,
- WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
-BASE_EXPORT std::vector<StringPiece> SplitStringPieceUsingSubstr(
+[[nodiscard]] BASE_EXPORT std::vector<StringPiece16>
+SplitStringPieceUsingSubstr(StringPiece16 input,
+ StringPiece16 delimiter,
+ WhitespaceHandling whitespace,
+ SplitResult result_type);
+[[nodiscard]] BASE_EXPORT std::vector<StringPiece> SplitStringPieceUsingSubstr(
StringPiece input,
StringPiece delimiter,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
+ SplitResult result_type);
} // namespace base
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
#include "base/strings/string_split_win.h"
#endif
diff --git a/base/strings/string_split_win.h b/base/strings/string_split_win.h
index 850d2ca..74efb5d 100644
--- a/base/strings/string_split_win.h
+++ b/base/strings/string_split_win.h
@@ -9,7 +9,6 @@
#include <vector>
#include "polyfills/base/base_export.h"
-#include "base/compiler_specific.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
@@ -17,29 +16,29 @@
// The following section contains overloads of the cross-platform APIs for
// std::wstring and gurl_base::WStringPiece.
-BASE_EXPORT std::vector<std::wstring> SplitString(WStringPiece input,
- WStringPiece separators,
- WhitespaceHandling whitespace,
- SplitResult result_type)
- WARN_UNUSED_RESULT;
-
-BASE_EXPORT std::vector<WStringPiece> SplitStringPiece(
+[[nodiscard]] BASE_EXPORT std::vector<std::wstring> SplitString(
WStringPiece input,
WStringPiece separators,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
+ SplitResult result_type);
-BASE_EXPORT std::vector<std::wstring> SplitStringUsingSubstr(
+[[nodiscard]] BASE_EXPORT std::vector<WStringPiece> SplitStringPiece(
+ WStringPiece input,
+ WStringPiece separators,
+ WhitespaceHandling whitespace,
+ SplitResult result_type);
+
+[[nodiscard]] BASE_EXPORT std::vector<std::wstring> SplitStringUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
+ SplitResult result_type);
-BASE_EXPORT std::vector<WStringPiece> SplitStringPieceUsingSubstr(
+[[nodiscard]] BASE_EXPORT std::vector<WStringPiece> SplitStringPieceUsingSubstr(
WStringPiece input,
WStringPiece delimiter,
WhitespaceHandling whitespace,
- SplitResult result_type) WARN_UNUSED_RESULT;
+ SplitResult result_type);
} // namespace base
diff --git a/base/strings/string_tokenizer_fuzzer.cc b/base/strings/string_tokenizer_fuzzer.cc
index 3aaee7b..b3b046b 100644
--- a/base/strings/string_tokenizer_fuzzer.cc
+++ b/base/strings/string_tokenizer_fuzzer.cc
@@ -6,12 +6,13 @@
#include <stdint.h>
#include <string>
+#include <tuple>
#include "base/strings/string_tokenizer.h"
void GetAllTokens(gurl_base::StringTokenizer& t) {
while (t.GetNext()) {
- (void)t.token();
+ std::ignore = t.token();
}
}
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 5995c2d..5d570e2 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -505,9 +505,9 @@
} // namespace base
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
#include "base/strings/string_util_win.h"
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
+#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include "base/strings/string_util_posix.h"
#else
#error Define string operations appropriately for your platform
diff --git a/base/strings/stringprintf.cc b/base/strings/stringprintf.cc
index 3f74e07..aed9b04 100644
--- a/base/strings/stringprintf.cc
+++ b/base/strings/stringprintf.cc
@@ -33,7 +33,7 @@
return gurl_base::vsnprintf(buffer, buf_size, format, argptr);
}
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
inline int vsnprintfT(wchar_t* buffer,
size_t buf_size,
const wchar_t* format,
@@ -77,7 +77,7 @@
int mem_length = gurl_base::size(stack_buf);
while (true) {
if (result < 0) {
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
// On Windows, vsnprintfT always returns the number of characters in a
// fully-formatted string, so if we reach this point, something else is
// wrong and no amount of buffer-doubling is going to fix it.
@@ -128,7 +128,7 @@
return result;
}
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
std::wstring StringPrintf(const wchar_t* format, ...) {
va_list ap;
va_start(ap, format);
@@ -163,7 +163,7 @@
return *dst;
}
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
const std::wstring& SStringPrintf(std::wstring* dst,
const wchar_t* format, ...) {
va_list ap;
@@ -193,7 +193,7 @@
va_end(ap);
}
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
void StringAppendF(std::wstring* dst, const wchar_t* format, ...) {
va_list ap;
va_start(ap, format);
@@ -213,7 +213,7 @@
StringAppendVT(dst, format, ap);
}
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap) {
StringAppendVT(dst, format, ap);
}
diff --git a/base/strings/stringprintf.h b/base/strings/stringprintf.h
index 5768bcc..b0d473b 100644
--- a/base/strings/stringprintf.h
+++ b/base/strings/stringprintf.h
@@ -16,28 +16,29 @@
namespace gurl_base {
// Return a C++ string given printf-like input.
-BASE_EXPORT std::string StringPrintf(const char* format, ...)
- PRINTF_FORMAT(1, 2) WARN_UNUSED_RESULT;
-#if defined(OS_WIN)
+[[nodiscard]] BASE_EXPORT std::string StringPrintf(const char* format, ...)
+ PRINTF_FORMAT(1, 2);
+#if BUILDFLAG(IS_WIN)
// Note: Unfortunately compile time checking of the format string for UTF-16
// strings is not supported by any compiler, thus these functions should be used
// carefully and sparingly. Also applies to SStringPrintf and StringAppendV
// below.
-BASE_EXPORT std::wstring StringPrintf(const wchar_t* format, ...)
- WPRINTF_FORMAT(1, 2) WARN_UNUSED_RESULT;
-BASE_EXPORT std::u16string StringPrintf(const char16_t* format, ...)
- WPRINTF_FORMAT(1, 2) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::wstring StringPrintf(const wchar_t* format, ...)
+ WPRINTF_FORMAT(1, 2);
+[[nodiscard]] BASE_EXPORT std::u16string StringPrintf(const char16_t* format,
+ ...) WPRINTF_FORMAT(1, 2);
#endif
// Return a C++ string given vprintf-like input.
-BASE_EXPORT std::string StringPrintV(const char* format, va_list ap)
- PRINTF_FORMAT(1, 0) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string StringPrintV(const char* format,
+ va_list ap)
+ PRINTF_FORMAT(1, 0);
// Store result into a supplied string and return it.
BASE_EXPORT const std::string& SStringPrintf(std::string* dst,
const char* format,
...) PRINTF_FORMAT(2, 3);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
BASE_EXPORT const std::wstring& SStringPrintf(std::wstring* dst,
const wchar_t* format,
...) WPRINTF_FORMAT(2, 3);
@@ -49,7 +50,7 @@
// Append result to a supplied string.
BASE_EXPORT void StringAppendF(std::string* dst, const char* format, ...)
PRINTF_FORMAT(2, 3);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
BASE_EXPORT void StringAppendF(std::wstring* dst, const wchar_t* format, ...)
WPRINTF_FORMAT(2, 3);
BASE_EXPORT void StringAppendF(std::u16string* dst, const char16_t* format, ...)
@@ -60,7 +61,7 @@
// string. All other routines are just convenience wrappers around it.
BASE_EXPORT void StringAppendV(std::string* dst, const char* format, va_list ap)
PRINTF_FORMAT(2, 0);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
BASE_EXPORT void StringAppendV(std::wstring* dst,
const wchar_t* format,
va_list ap) WPRINTF_FORMAT(2, 0);
diff --git a/base/strings/stringprintf_unittest.cc b/base/strings/stringprintf_unittest.cc
index 9da8861..334d0ba 100644
--- a/base/strings/stringprintf_unittest.cc
+++ b/base/strings/stringprintf_unittest.cc
@@ -35,7 +35,7 @@
TEST(StringPrintfTest, StringPrintfMisc) {
EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w'));
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
EXPECT_EQ(L"123hello w", StringPrintf(L"%3d%2ls %1lc", 123, L"hello", 'w'));
EXPECT_EQ(u"123hello w", StringPrintf(u"%3d%2ls %1lc", 123, u"hello", 'w'));
#endif
@@ -46,7 +46,7 @@
StringAppendF(&value, "%s", "");
EXPECT_EQ("Hello", value);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
std::wstring valuew(L"Hello");
StringAppendF(&valuew, L"%ls", L"");
EXPECT_EQ(L"Hello", valuew);
@@ -62,7 +62,7 @@
StringAppendF(&value, " %s", "World");
EXPECT_EQ("Hello World", value);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
std::wstring valuew(L"Hello");
StringAppendF(&valuew, L" %ls", L"World");
EXPECT_EQ(L"Hello World", valuew);
@@ -78,7 +78,7 @@
StringAppendF(&value, " %d", 123);
EXPECT_EQ("Hello 123", value);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
std::wstring valuew(L"Hello");
StringAppendF(&valuew, L" %d", 123);
EXPECT_EQ(L"Hello 123", valuew);
@@ -108,7 +108,7 @@
SStringPrintf(&out, "%s", src);
EXPECT_STREQ(src, out.c_str());
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
srcw[kSrcLen - i] = 0;
std::wstring outw;
SStringPrintf(&outw, L"%ls", srcw);
@@ -139,9 +139,9 @@
const int kRefSize = 320000;
char* ref = new char[kRefSize];
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
sprintf_s(ref, kRefSize, fmt, src, src, src, src, src, src, src);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
+#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
snprintf(ref, kRefSize, fmt, src, src, src, src, src, src, src);
#endif
@@ -154,7 +154,7 @@
StringAppendVTestHelper(&out, "%d foo %s", 1, "bar");
EXPECT_EQ("1 foo bar", out);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
std::wstring outw;
StringAppendVTestHelper(&outw, L"%d foo %ls", 1, L"bar");
EXPECT_EQ(L"1 foo bar", outw);
@@ -184,7 +184,7 @@
EXPECT_STREQ(src, out.c_str());
}
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
TEST(StringPrintfTest, Invalid) {
wchar_t invalid[2];
invalid[0] = 0xffff;
diff --git a/base/strings/sys_string_conversions.h b/base/strings/sys_string_conversions.h
index 51977fe..d80b178 100644
--- a/base/strings/sys_string_conversions.h
+++ b/base/strings/sys_string_conversions.h
@@ -17,79 +17,76 @@
#include "base/strings/string_piece.h"
#include "build/build_config.h"
-#if defined(OS_APPLE)
+#if BUILDFLAG(IS_APPLE)
#include <CoreFoundation/CoreFoundation.h>
#include "base/mac/scoped_cftyperef.h"
#ifdef __OBJC__
@class NSString;
-#else
-class NSString;
#endif
-#endif // OS_APPLE
+#endif // BUILDFLAG(IS_APPLE)
namespace gurl_base {
// Converts between wide and UTF-8 representations of a string. On error, the
// result is system-dependent.
-BASE_EXPORT std::string SysWideToUTF8(const std::wstring& wide)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::wstring SysUTF8ToWide(StringPiece utf8) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string SysWideToUTF8(const std::wstring& wide);
+[[nodiscard]] BASE_EXPORT std::wstring SysUTF8ToWide(StringPiece utf8);
// Converts between wide and the system multi-byte representations of a string.
// DANGER: This will lose information and can change (on Windows, this can
// change between reboots).
-BASE_EXPORT std::string SysWideToNativeMB(const std::wstring& wide)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::wstring SysNativeMBToWide(StringPiece native_mb)
- WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string SysWideToNativeMB(
+ const std::wstring& wide);
+[[nodiscard]] BASE_EXPORT std::wstring SysNativeMBToWide(StringPiece native_mb);
// Windows-specific ------------------------------------------------------------
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
// Converts between 8-bit and wide strings, using the given code page. The
// code page identifier is one accepted by the Windows function
// MultiByteToWideChar().
-BASE_EXPORT std::wstring SysMultiByteToWide(StringPiece mb, uint32_t code_page)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::string SysWideToMultiByte(const std::wstring& wide,
- uint32_t code_page)
- WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::wstring SysMultiByteToWide(StringPiece mb,
+ uint32_t code_page);
+[[nodiscard]] BASE_EXPORT std::string SysWideToMultiByte(
+ const std::wstring& wide,
+ uint32_t code_page);
-#endif // defined(OS_WIN)
+#endif // BUILDFLAG(IS_WIN)
// Mac-specific ----------------------------------------------------------------
-#if defined(OS_APPLE)
+#if BUILDFLAG(IS_APPLE)
-// Converts between STL strings and CFStringRefs/NSStrings.
+// Converts between strings and CFStringRefs/NSStrings.
-// Creates a string, and returns it with a refcount of 1. You are responsible
-// for releasing it. Returns NULL on failure.
-BASE_EXPORT ScopedCFTypeRef<CFStringRef> SysUTF8ToCFStringRef(StringPiece utf8)
- WARN_UNUSED_RESULT;
-BASE_EXPORT ScopedCFTypeRef<CFStringRef> SysUTF16ToCFStringRef(
- StringPiece16 utf16) WARN_UNUSED_RESULT;
+// Converts a string to a CFStringRef. Returns null on failure.
+[[nodiscard]] BASE_EXPORT ScopedCFTypeRef<CFStringRef> SysUTF8ToCFStringRef(
+ StringPiece utf8);
+[[nodiscard]] BASE_EXPORT ScopedCFTypeRef<CFStringRef> SysUTF16ToCFStringRef(
+ StringPiece16 utf16);
-// Same, but returns an autoreleased NSString.
-BASE_EXPORT NSString* SysUTF8ToNSString(StringPiece utf8) WARN_UNUSED_RESULT;
-BASE_EXPORT NSString* SysUTF16ToNSString(StringPiece16 utf16)
- WARN_UNUSED_RESULT;
+// Converts a CFStringRef to a string. Returns an empty string on failure. It is
+// not valid to call these with a null `ref`.
+[[nodiscard]] BASE_EXPORT std::string SysCFStringRefToUTF8(CFStringRef ref);
+[[nodiscard]] BASE_EXPORT std::u16string SysCFStringRefToUTF16(CFStringRef ref);
-// Converts a CFStringRef to an STL string. Returns an empty string on failure.
-BASE_EXPORT std::string SysCFStringRefToUTF8(CFStringRef ref)
- WARN_UNUSED_RESULT;
-BASE_EXPORT std::u16string SysCFStringRefToUTF16(CFStringRef ref)
- WARN_UNUSED_RESULT;
+#ifdef __OBJC__
-// Same, but accepts NSString input. Converts nil NSString* to the appropriate
-// string type of length 0.
-BASE_EXPORT std::string SysNSStringToUTF8(NSString* ref) WARN_UNUSED_RESULT;
-BASE_EXPORT std::u16string SysNSStringToUTF16(NSString* ref) WARN_UNUSED_RESULT;
+// Converts a string to an autoreleased NSString. Returns nil on failure.
+[[nodiscard]] BASE_EXPORT NSString* SysUTF8ToNSString(StringPiece utf8);
+[[nodiscard]] BASE_EXPORT NSString* SysUTF16ToNSString(StringPiece16 utf16);
-#endif // defined(OS_APPLE)
+// Converts an NSString to a string. Returns an empty string on failure or if
+// `ref` is nil.
+[[nodiscard]] BASE_EXPORT std::string SysNSStringToUTF8(NSString* ref);
+[[nodiscard]] BASE_EXPORT std::u16string SysNSStringToUTF16(NSString* ref);
+
+#endif // __OBJC__
+
+#endif // BUILDFLAG(IS_APPLE)
} // namespace base
diff --git a/base/strings/sys_string_conversions_posix.cc b/base/strings/sys_string_conversions_posix.cc
index f9f7312..02535ed 100644
--- a/base/strings/sys_string_conversions_posix.cc
+++ b/base/strings/sys_string_conversions_posix.cc
@@ -27,7 +27,7 @@
return out;
}
-#if defined(SYSTEM_NATIVE_UTF8) || defined(OS_ANDROID)
+#if defined(SYSTEM_NATIVE_UTF8) || BUILDFLAG(IS_ANDROID)
// TODO(port): Consider reverting the OS_ANDROID when we have wcrtomb()
// support and a better understanding of what calls these routines.
@@ -116,7 +116,7 @@
case 0:
// We hit an embedded null byte, keep going.
i += 1;
- FALLTHROUGH;
+ [[fallthrough]];
default:
i += res;
++num_out_chars;
@@ -154,6 +154,6 @@
return out;
}
-#endif // defined(SYSTEM_NATIVE_UTF8) || defined(OS_ANDROID)
+#endif // defined(SYSTEM_NATIVE_UTF8) || BUILDFLAG(IS_ANDROID)
} // namespace base
diff --git a/base/strings/sys_string_conversions_unittest.cc b/base/strings/sys_string_conversions_unittest.cc
index 95995c6..01bceb0 100644
--- a/base/strings/sys_string_conversions_unittest.cc
+++ b/base/strings/sys_string_conversions_unittest.cc
@@ -75,7 +75,7 @@
}
// Tests depend on setting a specific Linux locale.
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
TEST(SysStrings, SysWideToNativeMB) {
#if !defined(SYSTEM_NATIVE_UTF8)
ScopedLocale locale("en_US.UTF-8");
@@ -190,6 +190,6 @@
EXPECT_EQ(wide, trip);
}
}
-#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
+#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
} // namespace base
diff --git a/base/strings/utf_offset_string_conversions.h b/base/strings/utf_offset_string_conversions.h
index aa4e59e..3b2904d 100644
--- a/base/strings/utf_offset_string_conversions.h
+++ b/base/strings/utf_offset_string_conversions.h
@@ -96,9 +96,9 @@
size_t src_len,
std::u16string* output,
gurl_base::OffsetAdjuster::Adjustments* adjustments);
-BASE_EXPORT std::u16string UTF8ToUTF16WithAdjustments(
+[[nodiscard]] BASE_EXPORT std::u16string UTF8ToUTF16WithAdjustments(
const gurl_base::StringPiece& utf8,
- gurl_base::OffsetAdjuster::Adjustments* adjustments) WARN_UNUSED_RESULT;
+ gurl_base::OffsetAdjuster::Adjustments* adjustments);
// As above, but instead internally examines the adjustments and applies them
// to |offsets_for_adjustment|. Input offsets greater than the length of the
// input string will be set to std::u16string::npos. See comments by
diff --git a/base/strings/utf_string_conversion_utils.cc b/base/strings/utf_string_conversion_utils.cc
index da68dd3..9a4b4ca 100644
--- a/base/strings/utf_string_conversion_utils.cc
+++ b/base/strings/utf_string_conversion_utils.cc
@@ -122,7 +122,7 @@
}
// Instantiate versions we know callers will need.
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
// wchar_t and char16_t are the same thing on Windows.
template void PrepareForUTF8Output(const wchar_t*, size_t, std::string*);
#endif
@@ -146,7 +146,7 @@
}
// Instantiate versions we know callers will need.
-#if !defined(OS_WIN)
+#if !BUILDFLAG(IS_WIN)
// std::wstring and std::u16string are the same thing on Windows.
template void PrepareForUTF16Or32Output(const char*, size_t, std::wstring*);
#endif
diff --git a/base/strings/utf_string_conversions.h b/base/strings/utf_string_conversions.h
index ffb56e4..77dc194 100644
--- a/base/strings/utf_string_conversions.h
+++ b/base/strings/utf_string_conversions.h
@@ -23,45 +23,45 @@
// possible.
BASE_EXPORT bool WideToUTF8(const wchar_t* src, size_t src_len,
std::string* output);
-BASE_EXPORT std::string WideToUTF8(WStringPiece wide) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string WideToUTF8(WStringPiece wide);
BASE_EXPORT bool UTF8ToWide(const char* src, size_t src_len,
std::wstring* output);
-BASE_EXPORT std::wstring UTF8ToWide(StringPiece utf8) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::wstring UTF8ToWide(StringPiece utf8);
BASE_EXPORT bool WideToUTF16(const wchar_t* src,
size_t src_len,
std::u16string* output);
-BASE_EXPORT std::u16string WideToUTF16(WStringPiece wide) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::u16string WideToUTF16(WStringPiece wide);
BASE_EXPORT bool UTF16ToWide(const char16_t* src,
size_t src_len,
std::wstring* output);
-BASE_EXPORT std::wstring UTF16ToWide(StringPiece16 utf16) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::wstring UTF16ToWide(StringPiece16 utf16);
BASE_EXPORT bool UTF8ToUTF16(const char* src,
size_t src_len,
std::u16string* output);
-BASE_EXPORT std::u16string UTF8ToUTF16(StringPiece utf8) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::u16string UTF8ToUTF16(StringPiece utf8);
BASE_EXPORT bool UTF16ToUTF8(const char16_t* src,
size_t src_len,
std::string* output);
-BASE_EXPORT std::string UTF16ToUTF8(StringPiece16 utf16) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string UTF16ToUTF8(StringPiece16 utf16);
// This converts an ASCII string, typically a hardcoded constant, to a UTF16
// string.
-BASE_EXPORT std::u16string ASCIIToUTF16(StringPiece ascii) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::u16string ASCIIToUTF16(StringPiece ascii);
// Converts to 7-bit ASCII by truncating. The result must be known to be ASCII
// beforehand.
-BASE_EXPORT std::string UTF16ToASCII(StringPiece16 utf16) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string UTF16ToASCII(StringPiece16 utf16);
#if defined(WCHAR_T_IS_UTF16)
// This converts an ASCII string, typically a hardcoded constant, to a wide
// string.
-BASE_EXPORT std::wstring ASCIIToWide(StringPiece ascii) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::wstring ASCIIToWide(StringPiece ascii);
// Converts to 7-bit ASCII by truncating. The result must be known to be ASCII
// beforehand.
-BASE_EXPORT std::string WideToASCII(WStringPiece wide) WARN_UNUSED_RESULT;
+[[nodiscard]] BASE_EXPORT std::string WideToASCII(WStringPiece wide);
#endif // defined(WCHAR_T_IS_UTF16)
// The conversion functions in this file should not be used to convert string
diff --git a/base/strings/utf_string_conversions_fuzzer.cc b/base/strings/utf_string_conversions_fuzzer.cc
index 932012a..7bae707 100644
--- a/base/strings/utf_string_conversions_fuzzer.cc
+++ b/base/strings/utf_string_conversions_fuzzer.cc
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/macros.h"
+#include <tuple>
+
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -15,10 +16,10 @@
gurl_base::StringPiece string_piece_input(reinterpret_cast<const char*>(data),
size);
- ignore_result(gurl_base::UTF8ToWide(string_piece_input));
+ std::ignore = gurl_base::UTF8ToWide(string_piece_input);
gurl_base::UTF8ToWide(reinterpret_cast<const char*>(data), size,
&output_std_wstring);
- ignore_result(gurl_base::UTF8ToUTF16(string_piece_input));
+ std::ignore = gurl_base::UTF8ToUTF16(string_piece_input);
gurl_base::UTF8ToUTF16(reinterpret_cast<const char*>(data), size,
&output_string16);
@@ -26,10 +27,10 @@
if (size % 2 == 0) {
gurl_base::StringPiece16 string_piece_input16(
reinterpret_cast<const char16_t*>(data), size / 2);
- ignore_result(gurl_base::UTF16ToWide(output_string16));
+ std::ignore = gurl_base::UTF16ToWide(output_string16);
gurl_base::UTF16ToWide(reinterpret_cast<const char16_t*>(data), size / 2,
&output_std_wstring);
- ignore_result(gurl_base::UTF16ToUTF8(string_piece_input16));
+ std::ignore = gurl_base::UTF16ToUTF8(string_piece_input16);
gurl_base::UTF16ToUTF8(reinterpret_cast<const char16_t*>(data), size / 2,
&output_std_string);
}
@@ -37,10 +38,10 @@
// Test for wchar_t.
size_t wchar_t_size = sizeof(wchar_t);
if (size % wchar_t_size == 0) {
- ignore_result(gurl_base::WideToUTF8(output_std_wstring));
+ std::ignore = gurl_base::WideToUTF8(output_std_wstring);
gurl_base::WideToUTF8(reinterpret_cast<const wchar_t*>(data),
size / wchar_t_size, &output_std_string);
- ignore_result(gurl_base::WideToUTF16(output_std_wstring));
+ std::ignore = gurl_base::WideToUTF16(output_std_wstring);
gurl_base::WideToUTF16(reinterpret_cast<const wchar_t*>(data),
size / wchar_t_size, &output_string16);
}
@@ -50,7 +51,7 @@
if (gurl_base::IsStringASCII(string_piece_input)) {
output_string16 = gurl_base::ASCIIToUTF16(string_piece_input);
gurl_base::StringPiece16 string_piece_input16(output_string16);
- ignore_result(gurl_base::UTF16ToASCII(string_piece_input16));
+ std::ignore = gurl_base::UTF16ToASCII(string_piece_input16);
}
return 0;
diff --git a/base/template_util.h b/base/template_util.h
index d0803f8..3d954fd 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -12,7 +12,6 @@
#include <utility>
#include "base/compiler_specific.h"
-#include "build/build_config.h"
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 7
#include <vector>
@@ -247,7 +246,7 @@
// [1] https://en.cppreference.com/w/cpp/types/result_of
// [2] https://wg21.link/meta.trans.other#lib:invoke_result
template <typename Functor, typename... Args>
-using invoke_result = std::result_of<Functor && (Args && ...)>;
+using invoke_result = std::invoke_result<Functor, Args...>;
// Implementation of C++17's std::invoke_result_t.
//
diff --git a/build/BUILD b/build/BUILD
index 79fa1dd..5b560c9 100644
--- a/build/BUILD
+++ b/build/BUILD
@@ -10,3 +10,10 @@
copts = build_config.default_copts,
visibility = ["//visibility:public"],
)
+
+cc_library(
+ name = "buildflag",
+ hdrs = ["buildflag.h"],
+ copts = build_config.default_copts,
+ visibility = ["//visibility:public"],
+)
diff --git a/build/build_config.h b/build/build_config.h
index 63cec87..0102a93 100644
--- a/build/build_config.h
+++ b/build/build_config.h
@@ -2,33 +2,46 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This file adds defines about the platform we're currently building on.
+// This file doesn't belong to any GN target by design for faster build and
+// less developer overhead.
+
+// This file adds build flags about the OS we're currently building on. They are
+// defined directly in this file instead of via a `buildflag_header` target in a
+// GN file for faster build. They are defined using the corresponding OS defines
+// (e.g. OS_WIN) which are also defined in this file (except for OS_CHROMEOS,
+// which is set by the build system). These defines are deprecated and should
+// NOT be used directly. For example:
+// Please Use: #if BUILDFLAG(IS_WIN)
+// Deprecated: #if defined(OS_WIN)
//
// Operating System:
-// OS_AIX / OS_ANDROID / OS_ASMJS / OS_FREEBSD / OS_FUCHSIA / OS_IOS /
-// OS_LINUX / OS_MAC / OS_NACL (SFI or NONSFI) / OS_NETBSD / OS_OPENBSD /
-// OS_QNX / OS_SOLARIS / OS_WIN
+// IS_AIX / IS_ANDROID / IS_ASMJS / IS_CHROMEOS / IS_FREEBSD / IS_FUCHSIA /
+// IS_IOS / IS_LINUX / IS_MAC / IS_NACL / IS_NETBSD / IS_OPENBSD / IS_QNX /
+// IS_SOLARIS / IS_WIN
// Operating System family:
-// OS_APPLE: IOS or MAC
-// OS_BSD: FREEBSD or NETBSD or OPENBSD
-// OS_POSIX: AIX or ANDROID or ASMJS or CHROMEOS or FREEBSD or IOS or LINUX
+// IS_APPLE: IOS or MAC
+// IS_BSD: FREEBSD or NETBSD or OPENBSD
+// IS_POSIX: AIX or ANDROID or ASMJS or CHROMEOS or FREEBSD or IOS or LINUX
// or MAC or NACL or NETBSD or OPENBSD or QNX or SOLARIS
-//
-// /!\ Note: OS_CHROMEOS is set by the build system, not this file
+
+// This file also adds defines specific to the platform, architecture etc.
//
// Compiler:
// COMPILER_MSVC / COMPILER_GCC
//
// Processor:
-// ARCH_CPU_ARM64 / ARCH_CPU_ARMEL / ARCH_CPU_MIPS / ARCH_CPU_MIPS64 /
-// ARCH_CPU_MIPS64EL / ARCH_CPU_MIPSEL / ARCH_CPU_PPC64 / ARCH_CPU_S390 /
-// ARCH_CPU_S390X / ARCH_CPU_X86 / ARCH_CPU_X86_64
+// ARCH_CPU_ARM64 / ARCH_CPU_ARMEL / ARCH_CPU_LOONG32 / ARCH_CPU_LOONG64 /
+// ARCH_CPU_MIPS / ARCH_CPU_MIPS64 / ARCH_CPU_MIPS64EL / ARCH_CPU_MIPSEL /
+// ARCH_CPU_PPC64 / ARCH_CPU_S390 / ARCH_CPU_S390X / ARCH_CPU_X86 /
+// ARCH_CPU_X86_64 / ARCH_CPU_RISCV64
// Processor family:
// ARCH_CPU_ARM_FAMILY: ARMEL or ARM64
+// ARCH_CPU_LOONG_FAMILY: LOONG32 or LOONG64
// ARCH_CPU_MIPS_FAMILY: MIPS64EL or MIPSEL or MIPS64 or MIPS
// ARCH_CPU_PPC64_FAMILY: PPC64
// ARCH_CPU_S390_FAMILY: S390 or S390X
// ARCH_CPU_X86_FAMILY: X86 or X86_64
+// ARCH_CPU_RISCV_FAMILY: Riscv64
// Processor features:
// ARCH_CPU_31_BITS / ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
// ARCH_CPU_BIG_ENDIAN / ARCH_CPU_LITTLE_ENDIAN
@@ -36,18 +49,12 @@
#ifndef BUILD_BUILD_CONFIG_H_
#define BUILD_BUILD_CONFIG_H_
+#include "build/buildflag.h"
+
// A set of macros to use for platform detection.
#if defined(__native_client__)
// __native_client__ must be first, so that other OS_ defines are not set.
#define OS_NACL 1
-// OS_NACL comes in two sandboxing technology flavors, SFI or Non-SFI.
-// PNaCl toolchain defines __native_client_nonsfi__ macro in Non-SFI build
-// mode, while it does not in SFI build mode.
-#if defined(__native_client_nonsfi__)
-#define OS_NACL_NONSFI
-#else
-#define OS_NACL_SFI
-#endif
#elif defined(ANDROID)
#define OS_ANDROID 1
#elif defined(__APPLE__)
@@ -67,7 +74,7 @@
#define OS_LINUX 1
#endif // !defined(OS_CHROMEOS)
// Include a system header to pull in features.h for glibc/uclibc macros.
-#include <unistd.h>
+#include <assert.h>
#if defined(__GLIBC__) && !defined(__UCLIBC__)
// We really are using glibc, not uClibc pretending to be glibc.
#define LIBC_GLIBC 1
@@ -118,6 +125,115 @@
#define OS_POSIX 1
#endif
+// OS build flags
+#if defined(OS_AIX)
+#define BUILDFLAG_INTERNAL_IS_AIX() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_AIX() (0)
+#endif
+
+#if defined(OS_ANDROID)
+#define BUILDFLAG_INTERNAL_IS_ANDROID() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_ANDROID() (0)
+#endif
+
+#if defined(OS_APPLE)
+#define BUILDFLAG_INTERNAL_IS_APPLE() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_APPLE() (0)
+#endif
+
+#if defined(OS_ASMJS)
+#define BUILDFLAG_INTERNAL_IS_ASMJS() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_ASMJS() (0)
+#endif
+
+#if defined(OS_BSD)
+#define BUILDFLAG_INTERNAL_IS_BSD() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_BSD() (0)
+#endif
+
+#if defined(OS_CHROMEOS)
+#define BUILDFLAG_INTERNAL_IS_CHROMEOS() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_CHROMEOS() (0)
+#endif
+
+#if defined(OS_FREEBSD)
+#define BUILDFLAG_INTERNAL_IS_FREEBSD() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_FREEBSD() (0)
+#endif
+
+#if defined(OS_FUCHSIA)
+#define BUILDFLAG_INTERNAL_IS_FUCHSIA() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_FUCHSIA() (0)
+#endif
+
+#if defined(OS_IOS)
+#define BUILDFLAG_INTERNAL_IS_IOS() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_IOS() (0)
+#endif
+
+#if defined(OS_LINUX)
+#define BUILDFLAG_INTERNAL_IS_LINUX() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_LINUX() (0)
+#endif
+
+#if defined(OS_MAC)
+#define BUILDFLAG_INTERNAL_IS_MAC() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_MAC() (0)
+#endif
+
+#if defined(OS_NACL)
+#define BUILDFLAG_INTERNAL_IS_NACL() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_NACL() (0)
+#endif
+
+#if defined(OS_NETBSD)
+#define BUILDFLAG_INTERNAL_IS_NETBSD() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_NETBSD() (0)
+#endif
+
+#if defined(OS_OPENBSD)
+#define BUILDFLAG_INTERNAL_IS_OPENBSD() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_OPENBSD() (0)
+#endif
+
+#if defined(OS_POSIX)
+#define BUILDFLAG_INTERNAL_IS_POSIX() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_POSIX() (0)
+#endif
+
+#if defined(OS_QNX)
+#define BUILDFLAG_INTERNAL_IS_QNX() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_QNX() (0)
+#endif
+
+#if defined(OS_SOLARIS)
+#define BUILDFLAG_INTERNAL_IS_SOLARIS() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_SOLARIS() (0)
+#endif
+
+#if defined(OS_WIN)
+#define BUILDFLAG_INTERNAL_IS_WIN() (1)
+#else
+#define BUILDFLAG_INTERNAL_IS_WIN() (0)
+#endif
+
// Compiler detection. Note: clang masquerades as GCC on POSIX and as MSVC on
// Windows.
#if defined(__GNUC__)
@@ -199,6 +315,21 @@
#define ARCH_CPU_32_BITS 1
#define ARCH_CPU_BIG_ENDIAN 1
#endif
+#elif defined(__loongarch32)
+#define ARCH_CPU_LOONG_FAMILY 1
+#define ARCH_CPU_LOONG32 1
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__loongarch64)
+#define ARCH_CPU_LOONG_FAMILY 1
+#define ARCH_CPU_LOONG64 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__riscv) && (__riscv_xlen == 64)
+#define ARCH_CPU_RISCV_FAMILY 1
+#define ARCH_CPU_RISCV64 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
#else
#error Please add support for your architecture in build/build_config.h
#endif
diff --git a/build/buildflag.h b/build/buildflag.h
new file mode 100644
index 0000000..5776a75
--- /dev/null
+++ b/build/buildflag.h
@@ -0,0 +1,47 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BUILD_BUILDFLAG_H_
+#define BUILD_BUILDFLAG_H_
+
+// These macros un-mangle the names of the build flags in a way that looks
+// natural, and gives errors if the flag is not defined. Normally in the
+// preprocessor it's easy to make mistakes that interpret "you haven't done
+// the setup to know what the flag is" as "flag is off". Normally you would
+// include the generated header rather than include this file directly.
+//
+// This is for use with generated headers. See build/buildflag_header.gni.
+
+// This dance of two macros does a concatenation of two preprocessor args using
+// ## doubly indirectly because using ## directly prevents macros in that
+// parameter from being expanded.
+#define BUILDFLAG_CAT_INDIRECT(a, b) a ## b
+#define BUILDFLAG_CAT(a, b) BUILDFLAG_CAT_INDIRECT(a, b)
+
+// Accessor for build flags.
+//
+// To test for a value, if the build file specifies:
+//
+// ENABLE_FOO=true
+//
+// Then you would check at build-time in source code with:
+//
+// #include "foo_flags.h" // The header the build file specified.
+//
+// #if BUILDFLAG(ENABLE_FOO)
+// ...
+// #endif
+//
+// There will no #define called ENABLE_FOO so if you accidentally test for
+// whether that is defined, it will always be negative. You can also use
+// the value in expressions:
+//
+// const char kSpamServerName[] = BUILDFLAG(SPAM_SERVER_NAME);
+//
+// Because the flag is accessed as a preprocessor macro with (), an error
+// will be thrown if the proper header defining the internal flag value has
+// not been included.
+#define BUILDFLAG(flag) (BUILDFLAG_CAT(BUILDFLAG_INTERNAL_, flag)())
+
+#endif // BUILD_BUILDFLAG_H_
diff --git a/build_config/build_config.bzl b/build_config/build_config.bzl
index 117bc96..3deb9d1 100644
--- a/build_config/build_config.bzl
+++ b/build_config/build_config.bzl
@@ -11,8 +11,8 @@
})
_strings_hdrs = select({
- "//build_config:windows_x86_64": ["string_util_win.h"],
- "//conditions:default": ["string_util_posix.h"],
+ "//build_config:windows_x86_64": ["strings/string_util_win.h"],
+ "//conditions:default": ["strings/string_util_posix.h"],
})
_url_linkopts = select({
diff --git a/copy.bara.sky b/copy.bara.sky
index ffe4f61..6bf0772 100644
--- a/copy.bara.sky
+++ b/copy.bara.sky
@@ -20,10 +20,12 @@
"base/containers/util.h",
"base/cxx17_backports.h",
"base/cxx20_to_address.h",
+ "base/debug/crash_logging.cc",
+ "base/debug/crash_logging.h",
"base/debug/leak_annotations.h",
"base/functional/*.h",
"base/i18n/uchar.h",
- "base/macros.h",
+ "base/memory/raw_ptr.h",
"base/no_destructor.h",
"base/ranges/*.h",
"base/stl_util.h",
@@ -32,6 +34,7 @@
"base/template_util.h",
"base/third_party/icu/**",
"build/build_config.h",
+ "build/buildflag.h",
"url/*.cc",
"url/*.h",
"url/third_party/mozilla/**",
@@ -57,10 +60,13 @@
# Those headers are pulled from //polyfill instead of copied from Chromium.
# Should be in sync with //polyfill/BUILD.
polyfilled_headers = [
+ "base/allocator/buildflags.h",
"base/base_export.h",
"base/check.h",
"base/check_op.h",
"base/component_export.h",
+ "base/cpu_reduction_experiment.h",
+ "base/dcheck_is_on.h",
"base/debug/alias.h",
"base/export_template.h",
"base/logging.h",
diff --git a/polyfills/BUILD b/polyfills/BUILD
index 9bf74f4..6a58eec 100644
--- a/polyfills/BUILD
+++ b/polyfills/BUILD
@@ -6,10 +6,13 @@
cc_library(
name = "polyfills",
hdrs = [
+ "base/allocator/buildflags.h",
"base/base_export.h",
"base/check.h",
"base/check_op.h",
"base/component_export.h",
+ "base/cpu_reduction_experiment.h",
+ "base/dcheck_is_on.h",
"base/debug/alias.h",
"base/export_template.h",
"base/logging.h",
diff --git a/polyfills/base/allocator/buildflags.h b/polyfills/base/allocator/buildflags.h
new file mode 100644
index 0000000..54e240c
--- /dev/null
+++ b/polyfills/base/allocator/buildflags.h
@@ -0,0 +1,18 @@
+#ifndef POLYFILLS_BASE_ALLOCATOR_BUILDFLAGS_H_
+#define POLYFILLS_BASE_ALLOCATOR_BUILDFLAGS_H_
+
+#include "build/buildflag.h"
+
+#define BUILDFLAG_INTERNAL_USE_ALLOCATOR_SHIM() (1)
+#define BUILDFLAG_INTERNAL_USE_PARTITION_ALLOC() (1)
+#define BUILDFLAG_INTERNAL_USE_PARTITION_ALLOC_AS_MALLOC() (0)
+#define BUILDFLAG_INTERNAL_USE_BACKUP_REF_PTR() (0)
+#define BUILDFLAG_INTERNAL_USE_ASAN_BACKUP_REF_PTR() (0)
+#define BUILDFLAG_INTERNAL_ENABLE_BACKUP_REF_PTR_SLOW_CHECKS() (0)
+#define BUILDFLAG_INTERNAL_ENABLE_DANGLING_RAW_PTR_CHECKS() (0)
+#define BUILDFLAG_INTERNAL_PUT_REF_COUNT_IN_PREVIOUS_SLOT() (0)
+#define BUILDFLAG_INTERNAL_NEVER_REMOVE_FROM_BRP_POOL_BLOCKLIST() (0)
+#define BUILDFLAG_INTERNAL_USE_FAKE_BINARY_EXPERIMENT() (0)
+#define BUILDFLAG_INTERNAL_RECORD_ALLOC_INFO() (0)
+
+#endif // POLYFILLS_BASE_ALLOCATOR_BUILDFLAGS_H_
diff --git a/polyfills/base/check.h b/polyfills/base/check.h
index 15de08b..5c4168d 100644
--- a/polyfills/base/check.h
+++ b/polyfills/base/check.h
@@ -5,6 +5,7 @@
#ifndef POLYFILLS_BASE_CHECK_H_
#define POLYFILLS_BASE_CHECK_H_
+#include "polyfills/base/base_export.h"
#include "polyfills/base/logging.h"
#endif /* POLYFILLS_BASE_CHECK_H_ */
diff --git a/polyfills/base/cpu_reduction_experiment.h b/polyfills/base/cpu_reduction_experiment.h
new file mode 100644
index 0000000..db2ea65
--- /dev/null
+++ b/polyfills/base/cpu_reduction_experiment.h
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef POLYFILLS_BASE_CPU_REDUCTION_EXPERIMENT_H_
+#define POLYFILLS_BASE_CPU_REDUCTION_EXPERIMENT_H_
+
+namespace base {
+
+inline bool IsRunningCpuReductionExperiment() { return false; }
+
+class CpuReductionExperimentFilter {
+ public:
+ bool ShouldLogHistograms() { return false; }
+};
+
+} // namespace base
+
+
+#endif /* POLYFILLS_BASE_CPU_REDUCTION_EXPERIMENT_H_ */
diff --git a/polyfills/base/dcheck_is_on.h b/polyfills/base/dcheck_is_on.h
new file mode 100644
index 0000000..814f0d2
--- /dev/null
+++ b/polyfills/base/dcheck_is_on.h
@@ -0,0 +1,11 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef POLYFILLS_BASE_DCHECK_IS_ON_H_
+#define POLYFILLS_BASE_DCHECK_IS_ON_H_
+
+#define DCHECK_IS_ON() false
+#define EXPENSIVE_DCHECKS_ARE_ON() false
+
+#endif // POLYFILLS_BASE_DCHECK_IS_ON_H_
diff --git a/url/BUILD b/url/BUILD
index f2ec8da..24fd97e 100644
--- a/url/BUILD
+++ b/url/BUILD
@@ -48,7 +48,6 @@
visibility = ["//visibility:public"],
deps = [
"//base",
- "//base/strings",
"//polyfills",
] + build_config.icuuc_deps,
)
diff --git a/url/gurl.cc b/url/gurl.cc
index 474919a..3dd0228 100644
--- a/url/gurl.cc
+++ b/url/gurl.cc
@@ -349,7 +349,7 @@
GURL_DCHECK(gurl_base::IsStringASCII(lower_ascii_scheme));
GURL_DCHECK(gurl_base::ToLowerASCII(lower_ascii_scheme) == lower_ascii_scheme);
- if (parsed_.scheme.len <= 0)
+ if (!has_scheme())
return lower_ascii_scheme.empty();
return scheme_piece() == lower_ascii_scheme;
}
@@ -363,7 +363,7 @@
}
bool GURL::SchemeIsCryptographic() const {
- if (parsed_.scheme.len <= 0)
+ if (!has_scheme())
return false;
return SchemeIsCryptographic(scheme_piece());
}
@@ -376,6 +376,13 @@
lower_ascii_scheme == url::kWssScheme;
}
+bool GURL::SchemeIsLocal() const {
+ // The `filesystem:` scheme is not in the Fetch spec, but Chromium still
+ // supports it in large part. It should be treated as a local scheme too.
+ return SchemeIs(url::kAboutScheme) || SchemeIs(url::kBlobScheme) ||
+ SchemeIs(url::kDataScheme) || SchemeIs(url::kFileSystemScheme);
+}
+
int GURL::IntPort() const {
if (parsed_.port.is_nonempty())
return url::ParsePort(spec_.data(), parsed_.port);
@@ -546,3 +553,15 @@
bool operator!=(const gurl_base::StringPiece& spec, const GURL& x) {
return !(x == spec);
}
+
+namespace url::debug {
+
+ScopedUrlCrashKey::ScopedUrlCrashKey(gurl_base::debug::CrashKeyString* crash_key,
+ const GURL& url)
+ : scoped_string_value_(
+ crash_key,
+ url.is_empty() ? "<empty url>" : url.possibly_invalid_spec()) {}
+
+ScopedUrlCrashKey::~ScopedUrlCrashKey() = default;
+
+} // namespace url::debug
diff --git a/url/gurl.h b/url/gurl.h
index 64a2ee3..ee009de 100644
--- a/url/gurl.h
+++ b/url/gurl.h
@@ -13,6 +13,7 @@
#include "polyfills/base/component_export.h"
#include "polyfills/base/debug/alias.h"
+#include "base/debug/crash_logging.h"
#include "base/strings/string_piece.h"
#include "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"
#include "url/third_party/mozilla/url_parse.h"
@@ -265,6 +266,10 @@
return SchemeIs(url::kBlobScheme);
}
+ // Returns true if the scheme is a local scheme, as defined in Fetch:
+ // https://fetch.spec.whatwg.org/#local-scheme
+ bool SchemeIsLocal() const;
+
// For most URLs, the "content" is everything after the scheme (skipping the
// scheme delimiting colon) and before the fragment (skipping the fragment
// delimiting octothorpe). For javascript URLs the "content" also includes the
@@ -516,4 +521,20 @@
#define DEBUG_ALIAS_FOR_GURL(var_name, url) \
DEBUG_ALIAS_FOR_CSTR(var_name, (url).possibly_invalid_spec().c_str(), 128)
+namespace url::debug {
+
+class COMPONENT_EXPORT(URL) ScopedUrlCrashKey {
+ public:
+ ScopedUrlCrashKey(gurl_base::debug::CrashKeyString* crash_key, const GURL& value);
+ ~ScopedUrlCrashKey();
+
+ ScopedUrlCrashKey(const ScopedUrlCrashKey&) = delete;
+ ScopedUrlCrashKey& operator=(const ScopedUrlCrashKey&) = delete;
+
+ private:
+ gurl_base::debug::ScopedCrashKeyString scoped_string_value_;
+};
+
+} // namespace url::debug
+
#endif // URL_GURL_H_
diff --git a/url/gurl_unittest.cc b/url/gurl_unittest.cc
index 68817af..e793542 100644
--- a/url/gurl_unittest.cc
+++ b/url/gurl_unittest.cc
@@ -18,19 +18,6 @@
namespace {
-template<typename CHAR>
-void SetupReplacement(
- void (Replacements<CHAR>::*func)(const CHAR*, const Component&),
- Replacements<CHAR>* replacements,
- const CHAR* str) {
- if (str) {
- Component comp;
- if (str[0])
- comp.len = static_cast<int>(strlen(str));
- (replacements->*func)(str, comp);
- }
-}
-
// Returns the canonicalized string for the given URL string for the
// GURLTest.Types test.
std::string TypesTestCase(const char* src) {
@@ -496,60 +483,102 @@
// The most important thing to do here is to check that the proper
// canonicalizer gets called based on the scheme of the input.
struct ReplaceCase {
+ using ApplyReplacementsFunc = GURL(const GURL&);
+
const char* base;
- const char* scheme;
- const char* username;
- const char* password;
- const char* host;
- const char* port;
- const char* path;
- const char* query;
- const char* ref;
+ ApplyReplacementsFunc* apply_replacements;
const char* expected;
} replace_cases[] = {
- {"http://www.google.com/foo/bar.html?foo#bar", nullptr, nullptr, nullptr,
- nullptr, nullptr, "/", "", "", "http://www.google.com/"},
- {"http://www.google.com/foo/bar.html?foo#bar", "javascript", "", "", "",
- "", "window.open('foo');", "", "", "javascript:window.open('foo');"},
- {"file:///C:/foo/bar.txt", "http", nullptr, nullptr, "www.google.com",
- "99", "/foo", "search", "ref",
- "http://www.google.com:99/foo?search#ref"},
+ {.base = "http://www.google.com/foo/bar.html?foo#bar",
+ .apply_replacements =
+ +[](const GURL& url) {
+ GURL::Replacements replacements;
+ replacements.SetPathStr("/");
+ replacements.ClearQuery();
+ replacements.ClearRef();
+ return url.ReplaceComponents(replacements);
+ },
+ .expected = "http://www.google.com/"},
+ {.base = "http://www.google.com/foo/bar.html?foo#bar",
+ .apply_replacements =
+ +[](const GURL& url) {
+ GURL::Replacements replacements;
+ replacements.SetSchemeStr("javascript");
+ replacements.ClearUsername();
+ replacements.ClearPassword();
+ replacements.ClearHost();
+ replacements.ClearPort();
+ replacements.SetPathStr("window.open('foo');");
+ replacements.ClearQuery();
+ replacements.ClearRef();
+ return url.ReplaceComponents(replacements);
+ },
+ .expected = "javascript:window.open('foo');"},
+ {.base = "file:///C:/foo/bar.txt",
+ .apply_replacements =
+ +[](const GURL& url) {
+ GURL::Replacements replacements;
+ replacements.SetSchemeStr("http");
+ replacements.SetHostStr("www.google.com");
+ replacements.SetPortStr("99");
+ replacements.SetPathStr("/foo");
+ replacements.SetQueryStr("search");
+ replacements.SetRefStr("ref");
+ return url.ReplaceComponents(replacements);
+ },
+ .expected = "http://www.google.com:99/foo?search#ref"},
#ifdef WIN32
- {"http://www.google.com/foo/bar.html?foo#bar", "file", "", "", "", "",
- "c:\\", "", "", "file:///C:/"},
+ {.base = "http://www.google.com/foo/bar.html?foo#bar",
+ .apply_replacements =
+ +[](const GURL& url) {
+ GURL::Replacements replacements;
+ replacements.SetSchemeStr("file");
+ replacements.ClearUsername();
+ replacements.ClearPassword();
+ replacements.ClearHost();
+ replacements.ClearPort();
+ replacements.SetPathStr("c:\\");
+ replacements.ClearQuery();
+ replacements.ClearRef();
+ return url.ReplaceComponents(replacements);
+ },
+ .expected = "file:///C:/"},
#endif
- {"filesystem:http://www.google.com/foo/bar.html?foo#bar", nullptr,
- nullptr, nullptr, nullptr, nullptr, "/", "", "",
- "filesystem:http://www.google.com/foo/"},
+ {.base = "filesystem:http://www.google.com/foo/bar.html?foo#bar",
+ .apply_replacements =
+ +[](const GURL& url) {
+ GURL::Replacements replacements;
+ replacements.SetPathStr("/");
+ replacements.ClearQuery();
+ replacements.ClearRef();
+ return url.ReplaceComponents(replacements);
+ },
+ .expected = "filesystem:http://www.google.com/foo/"},
// Lengthen the URL instead of shortening it, to test creation of
// inner_url.
- {"filesystem:http://www.google.com/foo/", nullptr, nullptr, nullptr,
- nullptr, nullptr, "bar.html", "foo", "bar",
- "filesystem:http://www.google.com/foo/bar.html?foo#bar"},
+ {.base = "filesystem:http://www.google.com/foo/",
+ .apply_replacements =
+ +[](const GURL& url) {
+ GURL::Replacements replacements;
+ replacements.SetPathStr("bar.html");
+ replacements.SetQueryStr("foo");
+ replacements.SetRefStr("bar");
+ return url.ReplaceComponents(replacements);
+ },
+ .expected = "filesystem:http://www.google.com/foo/bar.html?foo#bar"},
};
- for (size_t i = 0; i < gurl_base::size(replace_cases); i++) {
- const ReplaceCase& cur = replace_cases[i];
- GURL url(cur.base);
- GURL::Replacements repl;
- SetupReplacement(&GURL::Replacements::SetScheme, &repl, cur.scheme);
- SetupReplacement(&GURL::Replacements::SetUsername, &repl, cur.username);
- SetupReplacement(&GURL::Replacements::SetPassword, &repl, cur.password);
- SetupReplacement(&GURL::Replacements::SetHost, &repl, cur.host);
- SetupReplacement(&GURL::Replacements::SetPort, &repl, cur.port);
- SetupReplacement(&GURL::Replacements::SetPath, &repl, cur.path);
- SetupReplacement(&GURL::Replacements::SetQuery, &repl, cur.query);
- SetupReplacement(&GURL::Replacements::SetRef, &repl, cur.ref);
- GURL output = url.ReplaceComponents(repl);
+ for (const ReplaceCase& c : replace_cases) {
+ GURL output = c.apply_replacements(GURL(c.base));
- EXPECT_EQ(replace_cases[i].expected, output.spec());
+ EXPECT_EQ(c.expected, output.spec());
EXPECT_EQ(output.SchemeIsFileSystem(), output.inner_url() != NULL);
if (output.SchemeIsFileSystem()) {
// TODO(mmenke): inner_url()->spec() is currently the same as the spec()
// for the GURL itself. This should be fixed.
// See https://crbug.com/619596
- EXPECT_EQ(replace_cases[i].expected, output.inner_url()->spec());
+ EXPECT_EQ(c.expected, output.inner_url()->spec());
}
}
}
@@ -847,6 +876,20 @@
EXPECT_FALSE(GURL("http://bar/").SchemeIsBlob());
}
+TEST(GURLTest, SchemeIsLocal) {
+ EXPECT_TRUE(GURL("BLOB://BAR/").SchemeIsLocal());
+ EXPECT_TRUE(GURL("blob://bar/").SchemeIsLocal());
+ EXPECT_TRUE(GURL("DATA:TEXT/HTML,BAR").SchemeIsLocal());
+ EXPECT_TRUE(GURL("data:text/html,bar").SchemeIsLocal());
+ EXPECT_TRUE(GURL("ABOUT:BAR").SchemeIsLocal());
+ EXPECT_TRUE(GURL("about:bar").SchemeIsLocal());
+ EXPECT_TRUE(GURL("FILESYSTEM:HTTP://FOO.EXAMPLE/BAR").SchemeIsLocal());
+ EXPECT_TRUE(GURL("filesystem:http://foo.example/bar").SchemeIsLocal());
+
+ EXPECT_FALSE(GURL("http://bar/").SchemeIsLocal());
+ EXPECT_FALSE(GURL("file:///bar").SchemeIsLocal());
+}
+
// Tests that the 'content' of the URL is properly extracted. This can be
// complex in cases such as multiple schemes (view-source:http:) or for
// javascript URLs. See GURL::GetContent for more details.
diff --git a/url/origin.cc b/url/origin.cc
index 6c7915f..e943d4f 100644
--- a/url/origin.cc
+++ b/url/origin.cc
@@ -60,7 +60,7 @@
}
Origin Origin::Resolve(const GURL& url, const Origin& base_origin) {
- if (url.SchemeIs(kAboutScheme))
+ if (url.SchemeIs(kAboutScheme) || url.is_empty())
return base_origin;
Origin result = Origin::Create(url);
if (!result.opaque())
@@ -163,6 +163,20 @@
return std::tie(tuple_, nonce_) == std::tie(other.tuple_, other.nonce_);
}
+bool Origin::IsSameOriginWith(const GURL& url) const {
+ if (opaque())
+ return false;
+
+ // The `url::Origin::Create` call here preserves how IsSameOriginWith was used
+ // historically, even though in some scenarios it is not clearly correct:
+ // - Origin of about:blank and about:srcdoc cannot be correctly
+ // computed/recovered.
+ // - Ideally passing an invalid `url` would be a caller error (e.g. a GURL_DCHECK).
+ // - The caller intent is not always clear wrt handling the outer-vs-inner
+ // origins/URLs in blob: and filesystem: schemes.
+ return IsSameOriginWith(url::Origin::Create(url));
+}
+
bool Origin::CanBeDerivedFrom(const GURL& url) const {
GURL_DCHECK(url.is_valid());
@@ -456,7 +470,7 @@
ScopedOriginCrashKey::ScopedOriginCrashKey(
gurl_base::debug::CrashKeyString* crash_key,
const url::Origin* value)
- : gurl_base::debug::ScopedCrashKeyString(
+ : scoped_string_value_(
crash_key,
value ? value->GetDebugString(false /* include_nonce */)
: "nullptr") {}
diff --git a/url/origin.h b/url/origin.h
index bfd3b36..c1ad177 100644
--- a/url/origin.h
+++ b/url/origin.h
@@ -25,7 +25,7 @@
#include "url/url_canon.h"
#include "url/url_constants.h"
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
#include <jni.h>
namespace gurl_base {
@@ -36,12 +36,13 @@
class JavaRef;
} // namespace android
} // namespace base
-#endif // OS_ANDROID
+#endif // BUILDFLAG(IS_ANDROID)
class GURL;
namespace blink {
class SecurityOrigin;
+class SecurityOriginTest;
} // namespace blink
namespace ipc_fuzzer {
@@ -222,6 +223,15 @@
return !IsSameOriginWith(other);
}
+ // Non-opaque origin is "same-origin" with `url` if their schemes, hosts, and
+ // ports are exact matches. Opaque origin is never "same-origin" with any
+ // `url`. about:blank, about:srcdoc, and invalid GURLs are never
+ // "same-origin" with any origin. This method is a shorthand for
+ // `origin.IsSameOriginWith(url::Origin::Create(url))`.
+ //
+ // See also CanBeDerivedFrom.
+ bool IsSameOriginWith(const GURL& url) const;
+
// This method returns true for any |url| which if navigated to could result
// in an origin compatible with |this|.
bool CanBeDerivedFrom(const GURL& url) const;
@@ -289,16 +299,17 @@
// and precursor information.
std::string GetDebugString(bool include_nonce = true) const;
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
gurl_base::android::ScopedJavaLocalRef<jobject> CreateJavaObject() const;
static Origin FromJavaObject(
const gurl_base::android::JavaRef<jobject>& java_origin);
-#endif // OS_ANDROID
+#endif // BUILDFLAG(IS_ANDROID)
void WriteIntoTrace(perfetto::TracedValue context) const;
private:
friend class blink::SecurityOrigin;
+ friend class blink::SecurityOriginTest;
// SchemefulSite needs access to the serialization/deserialization logic which
// includes the nonce.
friend class net::SchemefulSite;
@@ -440,8 +451,7 @@
namespace debug {
-class COMPONENT_EXPORT(URL) ScopedOriginCrashKey
- : public gurl_base::debug::ScopedCrashKeyString {
+class COMPONENT_EXPORT(URL) ScopedOriginCrashKey {
public:
ScopedOriginCrashKey(gurl_base::debug::CrashKeyString* crash_key,
const url::Origin* value);
@@ -449,6 +459,9 @@
ScopedOriginCrashKey(const ScopedOriginCrashKey&) = delete;
ScopedOriginCrashKey& operator=(const ScopedOriginCrashKey&) = delete;
+
+ private:
+ gurl_base::debug::ScopedCrashKeyString scoped_string_value_;
};
} // namespace debug
diff --git a/url/origin_unittest.cc b/url/origin_unittest.cc
index cb78bb6..755d2e3 100644
--- a/url/origin_unittest.cc
+++ b/url/origin_unittest.cc
@@ -5,7 +5,7 @@
#include <stddef.h>
#include <stdint.h>
-#include "base/macros.h"
+#include "base/memory/raw_ptr.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -172,6 +172,7 @@
EXPECT_LT(opaque_a, url::Origin::Create(GURL("http://www.google.com")));
EXPECT_LT(opaque_b, url::Origin::Create(GURL("http://www.google.com")));
+ EXPECT_EQ(opaque_b, url::Origin::Resolve(GURL(), opaque_b));
EXPECT_EQ(opaque_b, url::Origin::Resolve(GURL("about:blank"), opaque_b));
EXPECT_EQ(opaque_b, url::Origin::Resolve(GURL("about:srcdoc"), opaque_b));
EXPECT_EQ(opaque_b,
@@ -495,7 +496,7 @@
// and ensure that it returns |expected_value|
const struct {
const char* url;
- Origin* origin;
+ raw_ptr<Origin> origin;
bool expected_value;
} kTestCases[] = {
{"https://a.com", ®ular_origin, true},
@@ -746,6 +747,29 @@
EXPECT_EQ(opaque.GetDebugString(), deserialized.value().GetDebugString());
}
+TEST_F(OriginTest, IsSameOriginWith) {
+ url::Origin opaque_origin;
+ GURL foo_url = GURL("https://foo.com/path");
+ url::Origin foo_origin = url::Origin::Create(foo_url);
+ GURL bar_url = GURL("https://bar.com/path");
+ url::Origin bar_origin = url::Origin::Create(bar_url);
+
+ EXPECT_FALSE(opaque_origin.IsSameOriginWith(foo_origin));
+ EXPECT_FALSE(opaque_origin.IsSameOriginWith(foo_url));
+
+ EXPECT_TRUE(foo_origin.IsSameOriginWith(foo_origin));
+ EXPECT_TRUE(foo_origin.IsSameOriginWith(foo_url));
+
+ EXPECT_FALSE(foo_origin.IsSameOriginWith(bar_origin));
+ EXPECT_FALSE(foo_origin.IsSameOriginWith(bar_url));
+
+ // Documenting legacy behavior. This doesn't necessarily mean that the legacy
+ // behavior is correct (or desirable in the long-term).
+ EXPECT_FALSE(foo_origin.IsSameOriginWith(GURL("about:blank")));
+ EXPECT_FALSE(foo_origin.IsSameOriginWith(GURL())); // Invalid GURL.
+ EXPECT_TRUE(foo_origin.IsSameOriginWith(GURL("blob:https://foo.com/guid")));
+}
+
INSTANTIATE_TYPED_TEST_SUITE_P(UrlOrigin,
AbstractOriginTest,
UrlOriginTestTraits);
diff --git a/url/run_all_unittests.cc b/url/run_all_unittests.cc
index 0f6a431..cf408d4 100644
--- a/url/run_all_unittests.cc
+++ b/url/run_all_unittests.cc
@@ -10,14 +10,14 @@
#include "base/test/test_suite.h"
#include "build/build_config.h"
-#if !defined(OS_IOS)
+#if !BUILDFLAG(IS_IOS)
#include "mojo/core/embedder/embedder.h" // nogncheck
#endif
int main(int argc, char** argv) {
gurl_base::TestSuite test_suite(argc, argv);
-#if !defined(OS_IOS)
+#if !BUILDFLAG(IS_IOS)
mojo::core::Init();
#endif
diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc
index c337da3..854c6f6 100644
--- a/url/scheme_host_port.cc
+++ b/url/scheme_host_port.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <string.h>
+#include <ostream>
#include <tuple>
#include "polyfills/base/check_op.h"
diff --git a/url/url_canon.h b/url/url_canon.h
index 457f58a..32e7b15 100644
--- a/url/url_canon.h
+++ b/url/url_canon.h
@@ -139,6 +139,8 @@
return true;
}
+ // `buffer_` is not a raw_ptr<...> for performance reasons (based on analysis
+ // of sampling profiler data).
T* buffer_;
int buffer_len_;
diff --git a/url/url_canon_host.cc b/url/url_canon_host.cc
index 7a97522..370dd77 100644
--- a/url/url_canon_host.cc
+++ b/url/url_canon_host.cc
@@ -2,10 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <unordered_set>
-
#include "polyfills/base/check.h"
-#include "polyfills/base/metrics/histogram_macros.h"
+#include "polyfills/base/cpu_reduction_experiment.h"
#include "url/url_canon.h"
#include "url/url_canon_internal.h"
@@ -132,8 +130,6 @@
bool* has_non_ascii) {
*has_non_ascii = false;
- std::unordered_set<char> escaped_chars_to_measure;
-
bool success = true;
for (int i = 0; i < host_len; ++i) {
unsigned int source = host[i];
@@ -161,7 +157,6 @@
} else if (replacement == kEsc) {
// This character is valid but should be escaped.
AppendEscapedChar(source, output);
- escaped_chars_to_measure.insert(source);
} else {
// Common case, the given character is valid in a hostname, the lookup
// table tells us the canonical representation of that character (lower
@@ -176,16 +171,6 @@
*has_non_ascii = true;
}
}
- if (success) {
- bool did_escape = !escaped_chars_to_measure.empty();
- UMA_HISTOGRAM_BOOLEAN("URL.Host.DidEscape", did_escape);
- if (did_escape) {
- for (char c : escaped_chars_to_measure) {
- UMA_HISTOGRAM_ENUMERATION("URL.Host.EscapeChar",
- EscapedHostCharToEnum(c));
- }
- }
- }
return success;
}
diff --git a/url/url_canon_icu.cc b/url/url_canon_icu.cc
index b4f8f81..3a6b9be 100644
--- a/url/url_canon_icu.cc
+++ b/url/url_canon_icu.cc
@@ -9,6 +9,7 @@
#include <string.h>
#include "polyfills/base/check.h"
+#include "base/memory/raw_ptr.h"
#include <unicode/ucnv.h>
#include <unicode/ucnv_cb.h>
#include <unicode/utypes.h>
@@ -66,7 +67,7 @@
}
private:
- UConverter* converter_;
+ raw_ptr<UConverter> converter_;
UConverterFromUCallback old_callback_;
const void* old_context_;
diff --git a/url/url_canon_icu.h b/url/url_canon_icu.h
index 34bb99e..b861f7a 100644
--- a/url/url_canon_icu.h
+++ b/url/url_canon_icu.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "polyfills/base/component_export.h"
+#include "base/memory/raw_ptr.h"
#include "url/url_canon.h"
typedef struct UConverter UConverter;
@@ -32,7 +33,7 @@
private:
// The ICU converter, not owned by this class.
- UConverter* converter_;
+ raw_ptr<UConverter> converter_;
};
} // namespace url
diff --git a/url/url_canon_icu_unittest.cc b/url/url_canon_icu_unittest.cc
index ca13427..702b1d3 100644
--- a/url/url_canon_icu_unittest.cc
+++ b/url/url_canon_icu_unittest.cc
@@ -6,6 +6,7 @@
#include "base/cxx17_backports.h"
#include "polyfills/base/logging.h"
+#include "base/memory/raw_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <unicode/ucnv.h>
#include "url/url_canon.h"
@@ -38,7 +39,7 @@
UConverter* converter() const { return converter_; }
private:
- UConverter* converter_;
+ raw_ptr<UConverter> converter_;
};
TEST(URLCanonIcuTest, ICUCharsetConverter) {
diff --git a/url/url_canon_internal.cc b/url/url_canon_internal.cc
index 961a3be..99541bd 100644
--- a/url/url_canon_internal.cc
+++ b/url/url_canon_internal.cc
@@ -435,49 +435,4 @@
#endif // !WIN32
-EscapedHostChar EscapedHostCharToEnum(char c) {
- switch (c) {
- case ' ':
- return EscapedHostChar::kSpace;
- case '!':
- return EscapedHostChar::kBang;
- case '"':
- return EscapedHostChar::kDoubleQuote;
- case '#':
- return EscapedHostChar::kHash;
- case '$':
- return EscapedHostChar::kDollar;
- case '&':
- return EscapedHostChar::kAmpersand;
- case '\'':
- return EscapedHostChar::kSingleQuote;
- case '(':
- return EscapedHostChar::kLeftParen;
- case ')':
- return EscapedHostChar::kRightParen;
- case '*':
- return EscapedHostChar::kAsterisk;
- case ',':
- return EscapedHostChar::kComma;
- case '<':
- return EscapedHostChar::kLeftAngle;
- case '=':
- return EscapedHostChar::kEquals;
- case '>':
- return EscapedHostChar::kRightAngle;
- case '@':
- return EscapedHostChar::kAt;
- case '`':
- return EscapedHostChar::kBackTick;
- case '{':
- return EscapedHostChar::kLeftCurly;
- case '|':
- return EscapedHostChar::kPipe;
- case '}':
- return EscapedHostChar::kRightCurly;
- default:
- return EscapedHostChar::kUnknown;
- }
-}
-
} // namespace url
diff --git a/url/url_canon_internal.h b/url/url_canon_internal.h
index 6601587..d674976 100644
--- a/url/url_canon_internal.h
+++ b/url/url_canon_internal.h
@@ -456,35 +456,6 @@
#endif // WIN32
-// These values are logged to UMA. Entries should not be renumbered and
-// numeric values should never be reused. Please keep in sync with
-// "URLHostEscapedHostChar" in src/tools/metrics/histograms/enums.xml.
-enum class EscapedHostChar {
- kUnknown = 0,
- kSpace = 1,
- kBang = 2,
- kDoubleQuote = 3,
- kHash = 4,
- kDollar = 5,
- kAmpersand = 6,
- kSingleQuote = 7,
- kLeftParen = 8,
- kRightParen = 9,
- kAsterisk = 10,
- kComma = 11,
- kLeftAngle = 12,
- kEquals = 13,
- kRightAngle = 14,
- kAt = 15,
- kBackTick = 16,
- kLeftCurly = 17,
- kPipe = 18,
- kRightCurly = 19,
- kMaxValue = kRightCurly,
-};
-
-COMPONENT_EXPORT(URL) EscapedHostChar EscapedHostCharToEnum(char c);
-
} // namespace url
#endif // URL_URL_CANON_INTERNAL_H_
diff --git a/url/url_canon_stdstring.h b/url/url_canon_stdstring.h
index cef33cd..e9adc43 100644
--- a/url/url_canon_stdstring.h
+++ b/url/url_canon_stdstring.h
@@ -13,7 +13,6 @@
#include "base/compiler_specific.h"
#include "polyfills/base/component_export.h"
-#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "url/url_canon.h"
@@ -49,6 +48,8 @@
void Resize(int sz) override;
protected:
+ // `str_` is not a raw_ptr<...> for performance reasons (based on analysis of
+ // sampling profiler data and tab_search:top100:2020).
std::string* str_;
};
@@ -82,30 +83,47 @@
void SetUsernameStr(const CharT* str) { SetImpl(&ParentT::SetUsername, str); }
void SetUsernameStr(StringPieceT str) { SetImpl(&ParentT::SetUsername, str); }
void SetUsernameStr(const StringT&&) = delete;
+ using ParentT::ClearUsername;
void SetPasswordStr(const CharT* str) { SetImpl(&ParentT::SetPassword, str); }
void SetPasswordStr(StringPieceT str) { SetImpl(&ParentT::SetPassword, str); }
void SetPasswordStr(const StringT&&) = delete;
+ using ParentT::ClearPassword;
void SetHostStr(const CharT* str) { SetImpl(&ParentT::SetHost, str); }
void SetHostStr(StringPieceT str) { SetImpl(&ParentT::SetHost, str); }
void SetHostStr(const StringT&&) = delete;
+ using ParentT::ClearHost;
void SetPortStr(const CharT* str) { SetImpl(&ParentT::SetPort, str); }
void SetPortStr(StringPieceT str) { SetImpl(&ParentT::SetPort, str); }
void SetPortStr(const StringT&&) = delete;
+ using ParentT::ClearPort;
void SetPathStr(const CharT* str) { SetImpl(&ParentT::SetPath, str); }
void SetPathStr(StringPieceT str) { SetImpl(&ParentT::SetPath, str); }
void SetPathStr(const StringT&&) = delete;
+ using ParentT::ClearPath;
void SetQueryStr(const CharT* str) { SetImpl(&ParentT::SetQuery, str); }
void SetQueryStr(StringPieceT str) { SetImpl(&ParentT::SetQuery, str); }
void SetQueryStr(const StringT&&) = delete;
+ using ParentT::ClearQuery;
void SetRefStr(const CharT* str) { SetImpl(&ParentT::SetRef, str); }
void SetRefStr(StringPieceT str) { SetImpl(&ParentT::SetRef, str); }
void SetRefStr(const StringT&&) = delete;
+ using ParentT::ClearRef;
+
+ private:
+ using ParentT::SetHost;
+ using ParentT::SetPassword;
+ using ParentT::SetPath;
+ using ParentT::SetPort;
+ using ParentT::SetQuery;
+ using ParentT::SetRef;
+ using ParentT::SetScheme;
+ using ParentT::SetUsername;
};
} // namespace url
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc
index d7dc876..2dd5075 100644
--- a/url/url_canon_unittest.cc
+++ b/url/url_canon_unittest.cc
@@ -9,7 +9,6 @@
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/gtest_util.h"
-#include "base/test/metrics/histogram_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_canon.h"
@@ -2609,49 +2608,4 @@
output.set_length(0);
}
-TEST(URLCanonTest, EscapedHostCharToEnum) {
- EXPECT_EQ(EscapedHostChar::kSpace, EscapedHostCharToEnum(' '));
- EXPECT_EQ(EscapedHostChar::kBang, EscapedHostCharToEnum('!'));
- EXPECT_EQ(EscapedHostChar::kDoubleQuote, EscapedHostCharToEnum('"'));
- EXPECT_EQ(EscapedHostChar::kHash, EscapedHostCharToEnum('#'));
- EXPECT_EQ(EscapedHostChar::kDollar, EscapedHostCharToEnum('$'));
- EXPECT_EQ(EscapedHostChar::kAmpersand, EscapedHostCharToEnum('&'));
- EXPECT_EQ(EscapedHostChar::kSingleQuote, EscapedHostCharToEnum('\''));
- EXPECT_EQ(EscapedHostChar::kLeftParen, EscapedHostCharToEnum('('));
- EXPECT_EQ(EscapedHostChar::kRightParen, EscapedHostCharToEnum(')'));
- EXPECT_EQ(EscapedHostChar::kAsterisk, EscapedHostCharToEnum('*'));
- EXPECT_EQ(EscapedHostChar::kComma, EscapedHostCharToEnum(','));
- EXPECT_EQ(EscapedHostChar::kLeftAngle, EscapedHostCharToEnum('<'));
- EXPECT_EQ(EscapedHostChar::kEquals, EscapedHostCharToEnum('='));
- EXPECT_EQ(EscapedHostChar::kRightAngle, EscapedHostCharToEnum('>'));
- EXPECT_EQ(EscapedHostChar::kAt, EscapedHostCharToEnum('@'));
- EXPECT_EQ(EscapedHostChar::kBackTick, EscapedHostCharToEnum('`'));
- EXPECT_EQ(EscapedHostChar::kLeftCurly, EscapedHostCharToEnum('{'));
- EXPECT_EQ(EscapedHostChar::kPipe, EscapedHostCharToEnum('|'));
- EXPECT_EQ(EscapedHostChar::kRightCurly, EscapedHostCharToEnum('}'));
-
- EXPECT_EQ(EscapedHostChar::kUnknown, EscapedHostCharToEnum('a'));
- EXPECT_EQ(EscapedHostChar::kUnknown, EscapedHostCharToEnum('\\'));
-}
-
-TEST(URLCanonTest, EscapedHostCharHistograms) {
- std::string input("foo <bar>");
-
- Component in_comp(0, input.size());
- Component out_comp;
- std::string out_str;
- StdStringCanonOutput output(&out_str);
-
- gurl_base::HistogramTester histogram_tester;
- bool success = CanonicalizeHost(input.data(), in_comp, &output, &out_comp);
- ASSERT_TRUE(success);
- histogram_tester.ExpectBucketCount("URL.Host.DidEscape", 1, 1);
- histogram_tester.ExpectBucketCount("URL.Host.EscapeChar",
- EscapedHostChar::kSpace, 1);
- histogram_tester.ExpectBucketCount("URL.Host.EscapeChar",
- EscapedHostChar::kLeftAngle, 1);
- histogram_tester.ExpectBucketCount("URL.Host.EscapeChar",
- EscapedHostChar::kRightAngle, 1);
-}
-
} // namespace url
diff --git a/url/url_constants.cc b/url/url_constants.cc
index d7a5de7..9685098 100644
--- a/url/url_constants.cc
+++ b/url/url_constants.cc
@@ -7,33 +7,56 @@
namespace url {
const char kAboutBlankURL[] = "about:blank";
+const char16_t kAboutBlankURL16[] = u"about:blank";
const char kAboutSrcdocURL[] = "about:srcdoc";
+const char16_t kAboutSrcdocURL16[] = u"about:srcdoc";
const char kAboutBlankPath[] = "blank";
+const char16_t kAboutBlankPath16[] = u"blank";
const char kAboutSrcdocPath[] = "srcdoc";
+const char16_t kAboutSrcdocPath16[] = u"srcdoc";
const char kAboutScheme[] = "about";
+const char16_t kAboutScheme16[] = u"about";
const char kBlobScheme[] = "blob";
+const char16_t kBlobScheme16[] = u"blob";
const char kContentScheme[] = "content";
+const char16_t kContentScheme16[] = u"content";
const char kContentIDScheme[] = "cid";
+const char16_t kContentIDScheme16[] = u"cid";
const char kDataScheme[] = "data";
+const char16_t kDataScheme16[] = u"data";
const char kFileScheme[] = "file";
+const char16_t kFileScheme16[] = u"file";
const char kFileSystemScheme[] = "filesystem";
+const char16_t kFileSystemScheme16[] = u"filesystem";
const char kFtpScheme[] = "ftp";
+const char16_t kFtpScheme16[] = u"ftp";
const char kHttpScheme[] = "http";
+const char16_t kHttpScheme16[] = u"http";
const char kHttpsScheme[] = "https";
+const char16_t kHttpsScheme16[] = u"https";
const char kJavaScriptScheme[] = "javascript";
+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";
+const char16_t kUrnScheme16[] = u"urn";
const char kUuidInPackageScheme[] = "uuid-in-package";
+const char16_t kUuidInPackageScheme16[] = u"uuid-in-package";
const char kWsScheme[] = "ws";
+const char16_t kWsScheme16[] = u"ws";
const char kWssScheme[] = "wss";
+const char16_t kWssScheme16[] = u"wss";
const char kStandardSchemeSeparator[] = "://";
+const char16_t kStandardSchemeSeparator16[] = u"://";
const size_t kMaxURLChars = 2 * 1024 * 1024;
diff --git a/url/url_constants.h b/url/url_constants.h
index 69a72f5..b4a5889 100644
--- a/url/url_constants.h
+++ b/url/url_constants.h
@@ -12,33 +12,56 @@
namespace url {
COMPONENT_EXPORT(URL) extern const char kAboutBlankURL[];
+COMPONENT_EXPORT(URL) extern const char16_t kAboutBlankURL16[];
COMPONENT_EXPORT(URL) extern const char kAboutSrcdocURL[];
+COMPONENT_EXPORT(URL) extern const char16_t kAboutSrcdocURL16[];
COMPONENT_EXPORT(URL) extern const char kAboutBlankPath[];
+COMPONENT_EXPORT(URL) extern const char16_t kAboutBlankPath16[];
COMPONENT_EXPORT(URL) extern const char kAboutSrcdocPath[];
+COMPONENT_EXPORT(URL) extern const char16_t kAboutSrcdocPath16[];
COMPONENT_EXPORT(URL) extern const char kAboutScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kAboutScheme16[];
COMPONENT_EXPORT(URL) extern const char kBlobScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kBlobScheme16[];
// The content scheme is specific to Android for identifying a stored file.
COMPONENT_EXPORT(URL) extern const char kContentScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kContentScheme16[];
COMPONENT_EXPORT(URL) extern const char kContentIDScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kContentIDScheme16[];
COMPONENT_EXPORT(URL) extern const char kDataScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kDataScheme16[];
COMPONENT_EXPORT(URL) extern const char kFileScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kFileScheme16[];
COMPONENT_EXPORT(URL) extern const char kFileSystemScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kFileSystemScheme16[];
COMPONENT_EXPORT(URL) extern const char kFtpScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kFtpScheme16[];
COMPONENT_EXPORT(URL) extern const char kHttpScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kHttpScheme16[];
COMPONENT_EXPORT(URL) extern const char kHttpsScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kHttpsScheme16[];
COMPONENT_EXPORT(URL) extern const char kJavaScriptScheme[];
+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[];
+COMPONENT_EXPORT(URL) extern const char16_t kUrnScheme16[];
COMPONENT_EXPORT(URL) extern const char kUuidInPackageScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kUuidInPackageScheme16[];
COMPONENT_EXPORT(URL) extern const char kWsScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kWsScheme16[];
COMPONENT_EXPORT(URL) extern const char kWssScheme[];
+COMPONENT_EXPORT(URL) extern const char16_t kWssScheme16[];
// Used to separate a standard scheme and the hostname: "://".
COMPONENT_EXPORT(URL) extern const char kStandardSchemeSeparator[];
+COMPONENT_EXPORT(URL) extern const char16_t kStandardSchemeSeparator16[];
COMPONENT_EXPORT(URL) extern const size_t kMaxURLChars;
diff --git a/url/url_util_unittest.cc b/url/url_util_unittest.cc
index a455ff6..5255817 100644
--- a/url/url_util_unittest.cc
+++ b/url/url_util_unittest.cc
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "url/url_util.h"
+
#include <stddef.h>
#include "base/cxx17_backports.h"
#include "base/strings/string_piece.h"
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest-message.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "absl/types/optional.h"
@@ -13,7 +16,6 @@
#include "url/url_canon.h"
#include "url/url_canon_stdstring.h"
#include "url/url_test_utils.h"
-#include "url/url_util.h"
namespace url {
@@ -574,7 +576,7 @@
}
} // namespace
-#ifdef OS_WIN
+#if BUILDFLAG(IS_WIN)
// Regression test for https://crbug.com/1252658.
TEST_F(URLUtilTest, TestCanonicalizeWindowsPathWithLeadingNUL) {
auto PrefixWithNUL = [](std::string&& s) -> std::string { return '\0' + s; };