Update googleurl to Chromium version db5425c75e7fc1080bd06737d059 The version is from Tue Jun 7 13:29:16 2022 +0000 Change-Id: Ic4570bc199652d6fed6a21884b9256b858bb197a
diff --git a/AUTHORS b/AUTHORS index 5941416..a68e49b 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -236,6 +236,7 @@ Clemens Fruhwirth <clemens@endorphin.org> Clement Scheelfeldt Skau <clementskau@gmail.com> Clinton Staley <clintstaley@gmail.com> +Cong Zuo <zckevinzc@gmail.com> Connor Pearson <cjp822@gmail.com> Conrad Irwin <conrad.irwin@gmail.com> Craig Schlenter <craig.schlenter@gmail.com> @@ -269,6 +270,7 @@ Darshini KN <kn.darshini@samsung.com> Dave Vandyke <kzar@kzar.co.uk> David Benjamin <davidben@mit.edu> +David Brown <develop.david.brown@gmail.com> David Davidovic <david@davidovic.io> David Erceg <erceg.david@gmail.com> David Fox <david@davidjfox.com> @@ -296,6 +298,7 @@ Devlin Cronin <rdevlin.cronin@gmail.com> Dhi Aurrahman <dio@rockybars.com> Di Wu <meetwudi@gmail.com> +Di Zhang <dizhangg@chromium.org> Diana Suvorova <diana.suvorova@gmail.com> Diego Fernández Santos <agujaydedal@gmail.com> Diego Ferreiro Val <elfogris@gmail.com> @@ -470,6 +473,7 @@ Ivan Naydonov <samogot@gmail.com> Ivan Sham <ivansham@amazon.com> Jack Bates <jack@nottheoilrig.com> +Jacky Hu <flameddd@gmail.com> Jacob Clark <jacob.jh.clark@googlemail.com> Jacob Mandelson <jacob@mandelson.org> Jaehun Lim <ljaehun.lim@samsung.com> @@ -571,6 +575,7 @@ Jonathan Frazer <listedegarde@gmail.com> Jonathan Garbee <jonathan@garbee.me> Jonathan Hacker <jhacker@arcanefour.com> +Jonathan Johnson <johnsonjonathan593@gmail.com> Jonathan Kingston <kingstonmailbox@gmail.com> Jonathan Shimonovich <jonathans@talon-sec.com> Jongdeok Kim <jongdeok.kim@navercorp.com> @@ -733,12 +738,14 @@ Manish Jethani <m.jethani@eyeo.com> Manojkumar Bhosale <manojkumar.bhosale@imgtec.com> Manuel Braun <thembrown@gmail.com> +Manuel Lagana <manuel.lagana.dev@gmail.com> Mao Yujie <maojie0924@gmail.com> Mao Yujie <yujie.mao@intel.com> Marc des Garets <marc.desgarets@googlemail.com> Marcin Wiacek <marcin@mwiacek.com> Marco Rodrigues <gothicx@gmail.com> Marcos Caceres <marcos@marcosc.com> +Marek Behún <kabel@kernel.org> Mariam Ali <alimariam@noogler.google.com> Mario Pistrich <m.pistrich@gmail.com> Mario Sanchez Prada <mario.prada@samsung.com> @@ -936,6 +943,7 @@ Qiankun Miao <qiankun.miao@intel.com> Qing Zhang <qing.zhang@intel.com> Qingmei Li <qingmei.li@vivo.com> +Qiyao Yuan <qiyaoyuan@tencent.com> Radu Stavila <stavila@adobe.com> Radu Velea <radu.velea@intel.com> Rafael Antognolli <rafael.antognolli@intel.com> @@ -975,6 +983,7 @@ Robert Bear Travis <betravis@adobe.com> Robert Bradford <robert.bradford@intel.com> Robert Goldberg <goldberg@adobe.com> +Robert Günzler <r@gnzler.io> Robert Hogan <robhogan@gmail.com> Robert O'Callahan <rocallahan@gmail.com> Robert Nagy <robert.nagy@gmail.com> @@ -1001,6 +1010,7 @@ Ryan Norton <rnorton10@gmail.com> Ryan Sleevi <ryan-chromium-dev@sleevi.com> Ryan Yoakum <ryoakum@skobalt.com> +Rye Zhang <ryezhang@tencent.com> Ryo Ogawa <negibokken@gmail.com> Ryuan Choi <ryuan.choi@samsung.com> Saikrishna Arcot <saiarcot895@gmail.com> @@ -1090,8 +1100,10 @@ Simon Jackson <simon.jackson@sonocent.com> Simon La Macchia <smacchia@amazon.com> Siva Kumar Gunturi <siva.gunturi@samsung.com> -Sohan Jyoti Ghosh <sohan.jyoti@huawei.com> -Sohan Jyoti Ghosh <sohan.jyoti@samsung.com> +Slava Aseev <nullptrnine@gmail.com> +Sohan Jyoti Ghosh <sohanjg@chromium.org> +Sohom Datta <sohom.datta@learner.manipal.edu> +Sohom Datta <dattasohom1@gmail.com> Song Fangzhen <songfangzhen@bytedance.com> Song YeWen <ffmpeg@gmail.com> Sooho Park <sooho1000@gmail.com> @@ -1174,6 +1186,7 @@ Timo Gurr <timo.gurr@gmail.com> Timo Reimann <ttr314@googlemail.com> Timo Witte <timo.witte@gmail.com> +Timothy Pearson <tpearson@raptorcs.com> Ting Shao <ting.shao@intel.com> Tobias Lippert <tobias.lippert@fastmail.com> Tobias Soppa <tobias@soppa.me> @@ -1316,6 +1329,7 @@ Zhenyu Liang <zhenyu.liang@intel.com> Zhenyu Shan <zhenyu.shan@intel.com> Zhifei Fang <facetothefate@gmail.com> +Zhiyuan Ye <zhiyuanye@tencent.com> Zhuoyu Qian <zhuoyu.qian@samsung.com> Ziran Sun <ziran.sun@samsung.com> Zoltan Czirkos <czirkos.zoltan@gmail.com>
diff --git a/base/BUILD b/base/BUILD index c77528b..f86c18b 100644 --- a/base/BUILD +++ b/base/BUILD
@@ -32,6 +32,7 @@ "functional/invoke.h", "functional/not_fn.h", "memory/raw_ptr.h", + "memory/raw_ptr_exclusion.h", "no_destructor.h", "ranges/algorithm.h", "ranges/functional.h",
diff --git a/base/compiler_specific.h b/base/compiler_specific.h index 3a85453..12e09b5 100644 --- a/base/compiler_specific.h +++ b/base/compiler_specific.h
@@ -24,6 +24,13 @@ #define HAS_CPP_ATTRIBUTE(x) 0 #endif +// A wrapper around `__has_attribute`, similar to HAS_CPP_ATTRIBUTE. +#if defined(__has_attribute) +#define HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define HAS_ATTRIBUTE(x) 0 +#endif + // A wrapper around `__has_builtin`, similar to HAS_CPP_ATTRIBUTE. #if defined(__has_builtin) #define HAS_BUILTIN(x) __has_builtin(x) @@ -58,7 +65,7 @@ // prevent code folding, see NO_CODE_FOLDING() in base/debug/alias.h. // Use like: // void NOT_TAIL_CALLED FooBar(); -#if defined(__clang__) && __has_attribute(not_tail_called) +#if defined(__clang__) && HAS_ATTRIBUTE(not_tail_called) #define NOT_TAIL_CALLED __attribute__((not_tail_called)) #else #define NOT_TAIL_CALLED @@ -126,11 +133,9 @@ // __attribute__((format(wprintf, format_param, dots_param))) // Sanitizers annotations. -#if defined(__has_attribute) -#if __has_attribute(no_sanitize) +#if HAS_ATTRIBUTE(no_sanitize) #define NO_SANITIZE(what) __attribute__((no_sanitize(what))) #endif -#endif #if !defined(NO_SANITIZE) #define NO_SANITIZE(what) #endif @@ -238,7 +243,7 @@ #endif #endif -#if defined(__clang__) && __has_attribute(uninitialized) +#if defined(__clang__) && HAS_ATTRIBUTE(uninitialized) // Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for // the specified variable. // Library-wide alternative is @@ -285,13 +290,9 @@ // In some cases it's desirable to remove this, e.g. on hot functions, or if // we have purposely changed the reference canary. #if defined(COMPILER_GCC) || defined(__clang__) -#if defined(__has_attribute) -#if __has_attribute(__no_stack_protector__) +#if HAS_ATTRIBUTE(__no_stack_protector__) #define NO_STACK_PROTECTOR __attribute__((__no_stack_protector__)) -#else // __has_attribute(__no_stack_protector__) -#define NO_STACK_PROTECTOR __attribute__((__optimize__("-fno-stack-protector"))) -#endif -#else // defined(__has_attribute) +#else #define NO_STACK_PROTECTOR __attribute__((__optimize__("-fno-stack-protector"))) #endif #else @@ -328,7 +329,7 @@ #endif // defined(__clang_analyzer__) // Use nomerge attribute to disable optimization of merging multiple same calls. -#if defined(__clang__) && __has_attribute(nomerge) +#if defined(__clang__) && HAS_ATTRIBUTE(nomerge) #define NOMERGE [[clang::nomerge]] #else #define NOMERGE @@ -355,7 +356,7 @@ // See also: // https://clang.llvm.org/docs/AttributeReference.html#trivial-abi // https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html -#if defined(__clang__) && __has_attribute(trivial_abi) +#if defined(__clang__) && HAS_ATTRIBUTE(trivial_abi) #define TRIVIAL_ABI [[clang::trivial_abi]] #else #define TRIVIAL_ABI @@ -364,7 +365,7 @@ // Marks a member function as reinitializing a moved-from variable. // See also // https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html#reinitialization -#if defined(__clang__) && __has_attribute(reinitializes) +#if defined(__clang__) && HAS_ATTRIBUTE(reinitializes) #define REINITIALIZES_AFTER_MOVE [[clang::reinitializes]] #else #define REINITIALIZES_AFTER_MOVE @@ -373,11 +374,9 @@ // Requires constant initialization. See constinit in C++20. Allows to rely on a // variable being initialized before execution, and not requiring a global // constructor. -#if defined(__has_attribute) -#if __has_attribute(require_constant_initialization) +#if HAS_ATTRIBUTE(require_constant_initialization) #define CONSTINIT __attribute__((require_constant_initialization)) #endif -#endif #if !defined(CONSTINIT) #define CONSTINIT #endif
diff --git a/base/containers/contiguous_iterator.h b/base/containers/contiguous_iterator.h index f17a8ed..6229efb 100644 --- a/base/containers/contiguous_iterator.h +++ b/base/containers/contiguous_iterator.h
@@ -18,7 +18,10 @@ namespace internal { template <typename T> -struct PointsToObject : std::is_object<iter_value_t<T>> {}; +struct PointsToObject : std::true_type {}; +// std::iter_value_t is not defined for `T*` where T is not an object type. +template <typename T> +struct PointsToObject<T*> : std::is_object<T> {}; // A pointer is a contiguous iterator. // Reference: https://wg21.link/iterator.traits#5 @@ -74,15 +77,16 @@ // Check that the iterator points to an actual object, and is one of the // iterator types mentioned above. +template <typename T, bool B = PointsToObject<T>::value> +struct IsContiguousIteratorImpl : std::false_type {}; template <typename T> -struct IsContiguousIteratorImpl - : std::conjunction<PointsToObject<T>, - std::disjunction<IsPointer<T>, - IsStringIter<T>, - IsArrayIter<T>, - IsVectorIter<T>, - IsValueArrayIter<T>, - IsCheckedContiguousIter<T>>> {}; +struct IsContiguousIteratorImpl<T, true> + : std::disjunction<IsPointer<T>, + IsStringIter<T>, + IsArrayIter<T>, + IsVectorIter<T>, + IsValueArrayIter<T>, + IsCheckedContiguousIter<T>> {}; } // namespace internal
diff --git a/base/containers/span.h b/base/containers/span.h index c0fb0b6..5bb30d1 100644 --- a/base/containers/span.h +++ b/base/containers/span.h
@@ -7,7 +7,6 @@ #include <stddef.h> -#include <algorithm> #include <array> #include <iterator> #include <limits> @@ -470,10 +469,19 @@ } // Type-deducing helpers for constructing a span. -template <int&... ExplicitArgumentBarrier, typename It, typename EndOrSize> -constexpr auto make_span(It it, EndOrSize end_or_size) noexcept { +template <int&... ExplicitArgumentBarrier, typename It> +constexpr auto make_span(It it, size_t size) noexcept { using T = std::remove_reference_t<iter_reference_t<It>>; - return span<T>(it, end_or_size); + return span<T>(it, size); +} + +template <int&... ExplicitArgumentBarrier, + typename It, + typename End, + typename = std::enable_if_t<!std::is_convertible_v<End, size_t>>> +constexpr auto make_span(It it, End end) noexcept { + using T = std::remove_reference_t<iter_reference_t<It>>; + return span<T>(it, end); } // make_span utility function that deduces both the span's value_type and extent @@ -488,7 +496,7 @@ return span<T, Extent::value>(std::forward<Container>(container)); } -// make_span utility function that allows callers to explicit specify the span's +// make_span utility functions that allow callers to explicit specify the span's // extent, the value_type is deduced automatically. This is useful when passing // a dynamically sized container to a method expecting static spans, when the // container is known to have the correct size. @@ -496,13 +504,20 @@ // Note: This will GURL_CHECK that N indeed matches size(container). // // Usage: auto static_span = gurl_base::make_span<N>(...); +template <size_t N, int&... ExplicitArgumentBarrier, typename It> +constexpr auto make_span(It it, size_t size) noexcept { + using T = std::remove_reference_t<iter_reference_t<It>>; + return span<T, N>(it, size); +} + template <size_t N, int&... ExplicitArgumentBarrier, typename It, - typename EndOrSize> -constexpr auto make_span(It it, EndOrSize end_or_size) noexcept { + typename End, + typename = std::enable_if_t<!std::is_convertible_v<End, size_t>>> +constexpr auto make_span(It it, End end) noexcept { using T = std::remove_reference_t<iter_reference_t<It>>; - return span<T, N>(it, end_or_size); + return span<T, N>(it, end); } template <size_t N, int&... ExplicitArgumentBarrier, typename Container>
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h index ad53dc5..f1ef810 100644 --- a/base/memory/raw_ptr.h +++ b/base/memory/raw_ptr.h
@@ -36,21 +36,11 @@ #if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) #include "base/allocator/partition_allocator/partition_tag.h" #include "base/allocator/partition_allocator/tagging.h" +#include "polyfills/base/check_op.h" #endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) #if BUILDFLAG(IS_WIN) -#include <windows.h> -#endif - -#if defined(OFFICIAL_BUILD) -// The annotation changed compiler output and increased binary size so disable -// for official builds. -// TODO(crbug.com/1320670): Remove when issue is resolved. -#define RAW_PTR_EXCLUSION -#else -// 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"))) +#include "base/win/win_handle_types.h" #endif namespace cc { @@ -114,7 +104,7 @@ return wrapped_ptr; } - // Advance the wrapped pointer by |delta| bytes. + // Advance the wrapped pointer by `delta_elems`. template <typename T> static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elems) { return wrapped_ptr + delta_elems; @@ -161,8 +151,8 @@ // allocated by PartitionAlloc, from normal buckets pool. // // TODO(crbug.com/1307514): Allow direct-map buckets. - return IsManagedByPartitionAlloc(as_uintptr) && - IsManagedByNormalBuckets(as_uintptr); + return partition_alloc::IsManagedByPartitionAlloc(as_uintptr) && + partition_alloc::internal::IsManagedByNormalBuckets(as_uintptr); } // Returns pointer to the tag that protects are pointed by |ptr|. @@ -255,10 +245,10 @@ return static_cast<To*>(wrapped_ptr); } - // Advance the wrapped pointer by |delta| bytes. + // Advance the wrapped pointer by `delta_elems`. template <typename T> - static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elem) { - return wrapped_ptr + delta_elem; + static ALWAYS_INLINE 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 @@ -305,7 +295,8 @@ static ALWAYS_INLINE bool IsSupportedAndNotNull(uintptr_t address) { // This covers the nullptr case, as address 0 is never in GigaCage. - bool is_in_brp_pool = IsManagedByPartitionAllocBRPPool(address); + bool is_in_brp_pool = + partition_alloc::IsManagedByPartitionAllocBRPPool(address); // There are many situations where the compiler can prove that // ReleaseWrappedPtr is called on a value that is always nullptr, but the @@ -366,7 +357,8 @@ } #if !defined(PA_HAS_64_BITS_POINTERS) else { - AddressPoolManagerBitmap::BanSuperPageFromBRPPool(address); + partition_alloc::internal::AddressPoolManagerBitmap:: + BanSuperPageFromBRPPool(address); } #endif @@ -430,15 +422,15 @@ return wrapped_ptr; } - // Advance the wrapped pointer by |delta| bytes. + // Advance the wrapped pointer by `delta_elems`. template <typename T> - static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elem) { + static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elems) { #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))); + GURL_CHECK(IsValidDelta(address, delta_elems * sizeof(T))); #endif - T* new_wrapped_ptr = WrapRawPtr(wrapped_ptr + delta_elem); + T* new_wrapped_ptr = WrapRawPtr(wrapped_ptr + delta_elems); ReleaseWrappedPtr(wrapped_ptr); return new_wrapped_ptr; } @@ -517,7 +509,7 @@ return wrapped_ptr; } - // Advance the wrapped pointer by |delta| bytes. + // Advance the wrapped pointer by `delta_elems`. template <typename T> static ALWAYS_INLINE T* Advance(T* wrapped_ptr, ptrdiff_t delta_elems) { return wrapped_ptr + delta_elems;
diff --git a/base/memory/raw_ptr_exclusion.h b/base/memory/raw_ptr_exclusion.h new file mode 100644 index 0000000..37e9eac --- /dev/null +++ b/base/memory/raw_ptr_exclusion.h
@@ -0,0 +1,21 @@ +// 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_MEMORY_RAW_PTR_EXCLUSION_H_ +#define BASE_MEMORY_RAW_PTR_EXCLUSION_H_ + +#include "build/build_config.h" + +#if defined(OFFICIAL_BUILD) +// The annotation changed compiler output and increased binary size so disable +// for official builds. +// TODO(crbug.com/1320670): Remove when issue is resolved. +#define RAW_PTR_EXCLUSION +#else +// 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"))) +#endif + +#endif // BASE_MEMORY_RAW_PTR_EXCLUSION_H_
diff --git a/base/strings/escape.cc b/base/strings/escape.cc index 8324aae..011b79c 100644 --- a/base/strings/escape.cc +++ b/base/strings/escape.cc
@@ -7,6 +7,8 @@ #include <ostream> #include "polyfills/base/check_op.h" +#include "base/feature_list.h" +#include "base/features.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversion_utils.h" @@ -210,7 +212,7 @@ // |escaped_text| that corresponds to the unescaped character. bool UnescapeUTF8CharacterAtIndex(StringPiece escaped_text, size_t index, - uint32_t* code_point_out, + base_icu::UChar32* code_point_out, std::string* unescaped_out) { GURL_DCHECK(unescaped_out->empty()); @@ -404,7 +406,7 @@ // Locations of adjusted text. for (size_t i = 0, max = escaped_text.size(); i < max;) { // Try to unescape the character. - uint32_t code_point; + base_icu::UChar32 code_point; std::string unescaped; if (!UnescapeUTF8CharacterAtIndex(escaped_text, i, &code_point, &unescaped)) { @@ -540,6 +542,16 @@ GURL_DCHECK(!(rules & ~(UnescapeRule::NORMAL | UnescapeRule::REPLACE_PLUS_WITH_SPACE))); + // If there are no '%' characters in the string, there will be nothing to + // unescape, so we can take the fast path. + if (gurl_base::FeatureList::IsEnabled(features::kOptimizeDataUrls) && + escaped_text.find('%') == StringPiece::npos) { + std::string unescaped_text(escaped_text); + if (rules & UnescapeRule::REPLACE_PLUS_WITH_SPACE) + std::replace(unescaped_text.begin(), unescaped_text.end(), '+', ' '); + return unescaped_text; + } + std::string unescaped_text; // The output of the unescaping is always smaller than the input, so we can
diff --git a/base/strings/safe_sprintf.h b/base/strings/safe_sprintf.h index 478275e..8e6c922 100644 --- a/base/strings/safe_sprintf.h +++ b/base/strings/safe_sprintf.h
@@ -175,7 +175,7 @@ integer.width = sizeof(long long); } Arg(unsigned long long j) : type(UINT) { - integer.i = j; + integer.i = static_cast<int64_t>(j); integer.width = sizeof(long long); }
diff --git a/base/strings/string_number_conversions.cc b/base/strings/string_number_conversions.cc index b0eeafd..929b650 100644 --- a/base/strings/string_number_conversions.cc +++ b/base/strings/string_number_conversions.cc
@@ -155,19 +155,21 @@ bool HexStringToBytes(StringPiece input, std::vector<uint8_t>* output) { GURL_DCHECK(output->empty()); - return internal::HexStringToByteContainer(input, std::back_inserter(*output)); + return internal::HexStringToByteContainer<uint8_t>( + input, std::back_inserter(*output)); } bool HexStringToString(StringPiece input, std::string* output) { GURL_DCHECK(output->empty()); - return internal::HexStringToByteContainer(input, std::back_inserter(*output)); + return internal::HexStringToByteContainer<char>(input, + std::back_inserter(*output)); } bool HexStringToSpan(StringPiece input, gurl_base::span<uint8_t> output) { if (input.size() / 2 != output.size()) return false; - return internal::HexStringToByteContainer(input, output.begin()); + return internal::HexStringToByteContainer<uint8_t>(input, output.begin()); } } // namespace base
diff --git a/base/strings/string_number_conversions_internal.h b/base/strings/string_number_conversions_internal.h index 6de9e2e..2abd324 100644 --- a/base/strings/string_number_conversions_internal.h +++ b/base/strings/string_number_conversions_internal.h
@@ -252,7 +252,7 @@ char buffer[32]; double_conversion::StringBuilder builder(buffer, sizeof(buffer)); GetDoubleToStringConverter()->ToShortest(value, &builder); - return ToString<StringT>(buffer, builder.position()); + return ToString<StringT>(buffer, static_cast<size_t>(builder.position())); } template <typename STRING, typename CHAR> @@ -263,8 +263,8 @@ 0.0, 0, nullptr, nullptr); int processed_characters_count; - output = - converter.StringToDouble(data, input.size(), &processed_characters_count); + output = converter.StringToDouble(data, checked_cast<int>(input.size()), + &processed_characters_count); // Cases to return false: // - If the input string is empty, there was nothing to parse. @@ -278,7 +278,7 @@ !IsUnicodeWhitespace(input[0]); } -template <typename OutIter> +template <typename Char, typename OutIter> static bool HexStringToByteContainer(StringPiece input, OutIter output) { size_t count = input.size(); if (count == 0 || (count % 2) != 0) @@ -291,7 +291,7 @@ if (!msb || !lsb) { return false; } - *(output++) = (*msb << 4) | *lsb; + *(output++) = static_cast<Char>((*msb << 4) | *lsb); } return true; }
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h index 21ee624..68d6205 100644 --- a/base/strings/string_piece.h +++ b/base/strings/string_piece.h
@@ -607,10 +607,10 @@ // This is a custom hash function. We don't use the ones already defined for // string and std::u16string directly because it would require the string // constructors to be called, which we don't want. - std::size_t operator()(StringPieceType sp) const { - std::size_t result = 0; + size_t operator()(StringPieceType sp) const { + size_t result = 0; for (auto c : sp) - result = (result * 131) + c; + result = (result * 131) + static_cast<size_t>(c); return result; } };
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc index 937c603..8729bf4 100644 --- a/base/strings/string_util.cc +++ b/base/strings/string_util.cc
@@ -90,16 +90,6 @@ return internal::CompareCaseInsensitiveASCIIT(a, b); } -bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) { - return a.size() == b.size() && - internal::CompareCaseInsensitiveASCIIT(a, b) == 0; -} - -bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { - return a.size() == b.size() && - internal::CompareCaseInsensitiveASCIIT(a, b) == 0; -} - const std::string& EmptyString() { static const gurl_base::NoDestructor<std::string> s; return *s; @@ -185,8 +175,7 @@ int32_t prev = char_index; base_icu::UChar32 code_point = 0; CBU8_NEXT(data, char_index, truncation_length, code_point); - if (!IsValidCharacter(code_point) || - !IsValidCodepoint(code_point)) { + if (!IsValidCharacter(code_point)) { char_index = prev - 1; } else { break; @@ -301,24 +290,12 @@ return internal::EndsWithT(str, search_for, case_sensitivity); } -char HexDigitToInt(wchar_t c) { +char HexDigitToInt(char c) { GURL_DCHECK(IsHexDigit(c)); if (c >= '0' && c <= '9') return static_cast<char>(c - '0'); - if (c >= 'A' && c <= 'F') - return static_cast<char>(c - 'A' + 10); - if (c >= 'a' && c <= 'f') - return static_cast<char>(c - 'a' + 10); - return 0; -} - -bool IsUnicodeWhitespace(wchar_t c) { - // kWhitespaceWide is a NULL-terminated string - for (const wchar_t* cur = kWhitespaceWide; *cur; ++cur) { - if (*cur == c) - return true; - } - return false; + return (c >= 'A' && c <= 'F') ? static_cast<char>(c - 'A' + 10) + : static_cast<char>(c - 'a' + 10); } static const char* const kByteStringsUnlocalized[] = {
diff --git a/base/strings/string_util.h b/base/strings/string_util.h index cd90a94..435b5c6 100644 --- a/base/strings/string_util.h +++ b/base/strings/string_util.h
@@ -12,6 +12,7 @@ #include <stddef.h> #include <stdint.h> +#include <algorithm> #include <initializer_list> #include <string> #include <type_traits> @@ -122,7 +123,7 @@ template <typename CharT, typename = std::enable_if_t<std::is_integral<CharT>::value>> CharT ToUpperASCII(CharT c) { - return (c >= 'a' && c <= 'z') ? (c + ('A' - 'a')) : c; + return (c >= 'a' && c <= 'z') ? static_cast<CharT>(c + 'A' - 'a') : c; } // Converts the given string to it's ASCII-lowercase equivalent. @@ -153,16 +154,37 @@ // 0 (a == b) // 1 (a > b) // (unlike strcasecmp which can return values greater or less than 1/-1). For -// full Unicode support, use gurl_base::i18n::ToLower or gurl_base::i18h::FoldCase +// full Unicode support, use gurl_base::i18n::ToLower or gurl_base::i18n::FoldCase // and then just call the normal string operators on the result. BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b); BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b); +namespace internal { +template <typename CharT, typename CharU> +inline bool EqualsCaseInsensitiveASCIIT(BasicStringPiece<CharT> a, + BasicStringPiece<CharU> b) { + return std::equal(a.begin(), a.end(), b.begin(), b.end(), + [](auto lhs, auto rhs) { + return ToLowerASCII(lhs) == ToLowerASCII(rhs); + }); +} +} // namespace internal + // Equality for ASCII case-insensitive comparisons. For full Unicode support, -// use gurl_base::i18n::ToLower or gurl_base::i18h::FoldCase and then compare with either +// use gurl_base::i18n::ToLower or gurl_base::i18n::FoldCase and then compare with either // == or !=. -BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b); -BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b); +inline bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) { + return internal::EqualsCaseInsensitiveASCIIT(a, b); +} +inline bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { + return internal::EqualsCaseInsensitiveASCIIT(a, b); +} +inline bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece b) { + return internal::EqualsCaseInsensitiveASCIIT(a, b); +} +inline bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece16 b) { + return internal::EqualsCaseInsensitiveASCIIT(a, b); +} // These threadsafe functions return references to globally unique empty // strings. @@ -395,11 +417,24 @@ // '4' -> 4 // 'a' -> 10 // 'B' -> 11 -// Assumes the input is a valid hex character. DCHECKs in debug builds if not. -BASE_EXPORT char HexDigitToInt(wchar_t c); +// Assumes the input is a valid hex character. +BASE_EXPORT char HexDigitToInt(char c); +inline char HexDigitToInt(char16_t c) { + GURL_DCHECK(IsHexDigit(c)); + return HexDigitToInt(static_cast<char>(c)); +} // Returns true if it's a Unicode whitespace character. -BASE_EXPORT bool IsUnicodeWhitespace(wchar_t c); +template <typename Char> +inline bool IsUnicodeWhitespace(Char c) { + // kWhitespaceWide is a NUL-terminated string + for (const auto* cur = kWhitespaceWide; *cur; ++cur) { + if (static_cast<typename std::make_unsigned_t<wchar_t>>(*cur) == + static_cast<typename std::make_unsigned_t<Char>>(c)) + return true; + } + return false; +}; // Return a byte string in human-readable format with a unit suffix. Not // appropriate for use in any UI; use of FormatBytes and friends in ui/base is
diff --git a/base/strings/string_util_internal.h b/base/strings/string_util_internal.h index 2497c8d..173cfaa 100644 --- a/base/strings/string_util_internal.h +++ b/base/strings/string_util_internal.h
@@ -26,7 +26,7 @@ : parameter(parameter), offset(offset) {} // Index of the parameter. - uintptr_t parameter; + size_t parameter; // Starting position in the string. size_t offset; @@ -147,7 +147,7 @@ bool in_whitespace = true; bool already_trimmed = true; - int chars_written = 0; + size_t chars_written = 0; for (auto c : text) { if (IsUnicodeWhitespace(c)) { if (!in_whitespace) { @@ -196,7 +196,7 @@ // Prologue: align the input. while (!IsMachineWordAligned(characters) && characters < end) - all_char_bits |= *characters++; + all_char_bits |= static_cast<MachineWord>(*characters++); if (all_char_bits & non_ascii_bit_mask) return false; @@ -222,19 +222,19 @@ // Process the remaining bytes. while (characters < end) - all_char_bits |= *characters++; + all_char_bits |= static_cast<MachineWord>(*characters++); return !(all_char_bits & non_ascii_bit_mask); } -template <bool (*Validator)(uint32_t)> +template <bool (*Validator)(base_icu::UChar32)> inline bool DoIsStringUTF8(StringPiece str) { - const char* src = str.data(); - int32_t src_len = static_cast<int32_t>(str.length()); - int32_t char_index = 0; + const uint8_t* src = reinterpret_cast<const uint8_t*>(str.data()); + size_t src_len = str.length(); + size_t char_index = 0; while (char_index < src_len) { - int32_t code_point; + base_icu::UChar32 code_point; CBU8_NEXT(src, char_index, src_len, code_point); if (!Validator(code_point)) return false; @@ -583,10 +583,9 @@ GURL_DLOG(ERROR) << "Invalid placeholder: $" << *i; continue; } - uintptr_t index = *i - '1'; + size_t index = static_cast<size_t>(*i - '1'); if (offsets) { - ReplacementOffset r_offset(index, - static_cast<int>(formatted.size())); + ReplacementOffset r_offset(index, formatted.size()); r_offsets.insert( ranges::upper_bound(r_offsets, r_offset, &CompareParameter), r_offset);
diff --git a/base/strings/string_util_unittest.cc b/base/strings/string_util_unittest.cc index b5d9a67..f41f6d8 100644 --- a/base/strings/string_util_unittest.cc +++ b/base/strings/string_util_unittest.cc
@@ -1472,6 +1472,39 @@ EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", "aSDF")); EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", "aSDF")); EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", "aSDFz")); + + EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"", u"")); + EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"Asdf", u"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"bsdf", u"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"Asdf", u"aSDFz")); + + EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"", "")); + EXPECT_TRUE(EqualsCaseInsensitiveASCII(u"Asdf", "aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"bsdf", "aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(u"Asdf", "aSDFz")); + + EXPECT_TRUE(EqualsCaseInsensitiveASCII("", u"")); + EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", u"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", u"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", u"aSDFz")); + + // The `WStringPiece` overloads are only defined on Windows. +#if BUILDFLAG(IS_WIN) + EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"", L"")); + EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"Asdf", L"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"bsdf", L"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"Asdf", L"aSDFz")); + + EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"", "")); + EXPECT_TRUE(EqualsCaseInsensitiveASCII(L"Asdf", "aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"bsdf", "aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII(L"Asdf", "aSDFz")); + + EXPECT_TRUE(EqualsCaseInsensitiveASCII("", L"")); + EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", L"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", L"aSDF")); + EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", L"aSDFz")); +#endif } TEST(StringUtilTest, IsUnicodeWhitespace) {
diff --git a/base/strings/string_util_win.cc b/base/strings/string_util_win.cc index 9d475ba..7a9b891 100644 --- a/base/strings/string_util_win.cc +++ b/base/strings/string_util_win.cc
@@ -24,11 +24,6 @@ return internal::CompareCaseInsensitiveASCIIT(a, b); } -bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b) { - return a.size() == b.size() && - internal::CompareCaseInsensitiveASCIIT(a, b) == 0; -} - bool RemoveChars(WStringPiece input, WStringPiece remove_chars, std::wstring* output) {
diff --git a/base/strings/string_util_win.h b/base/strings/string_util_win.h index 7c04176..fbf815b 100644 --- a/base/strings/string_util_win.h +++ b/base/strings/string_util_win.h
@@ -117,7 +117,15 @@ BASE_EXPORT int CompareCaseInsensitiveASCII(WStringPiece a, WStringPiece b); -BASE_EXPORT bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b); +inline bool EqualsCaseInsensitiveASCII(WStringPiece a, WStringPiece b) { + return internal::EqualsCaseInsensitiveASCIIT(a, b); +} +inline bool EqualsCaseInsensitiveASCII(WStringPiece a, StringPiece b) { + return internal::EqualsCaseInsensitiveASCIIT(a, b); +} +inline bool EqualsCaseInsensitiveASCII(StringPiece a, WStringPiece b) { + return internal::EqualsCaseInsensitiveASCIIT(a, b); +} BASE_EXPORT bool RemoveChars(WStringPiece input, WStringPiece remove_chars,
diff --git a/base/strings/utf_offset_string_conversions.cc b/base/strings/utf_offset_string_conversions.cc index 6120b71..e6bb6d6 100644 --- a/base/strings/utf_offset_string_conversions.cc +++ b/base/strings/utf_offset_string_conversions.cc
@@ -192,7 +192,7 @@ bool success = true; int32_t src_len32 = static_cast<int32_t>(src_len); for (int32_t i = 0; i < src_len32; i++) { - uint32_t code_point; + base_icu::UChar32 code_point; size_t original_i = i; size_t chars_written = 0; if (ReadUnicodeCharacter(src, src_len32, &i, &code_point)) {
diff --git a/base/strings/utf_string_conversion_utils.cc b/base/strings/utf_string_conversion_utils.cc index 9a4b4ca..76dd725 100644 --- a/base/strings/utf_string_conversion_utils.cc +++ b/base/strings/utf_string_conversion_utils.cc
@@ -14,13 +14,10 @@ bool ReadUnicodeCharacter(const char* src, int32_t src_len, int32_t* char_index, - uint32_t* code_point_out) { - // U8_NEXT expects to be able to use -1 to signal an error, so we must - // use a signed type for code_point. But this function returns false - // on error anyway, so code_point_out is unsigned. - int32_t code_point; + base_icu::UChar32* code_point_out) { + base_icu::UChar32 code_point; CBU8_NEXT(src, *char_index, src_len, code_point); - *code_point_out = static_cast<uint32_t>(code_point); + *code_point_out = code_point; // The ICU macro above moves to the next char, we want to point to the last // char consumed. @@ -33,7 +30,7 @@ bool ReadUnicodeCharacter(const char16_t* src, int32_t src_len, int32_t* char_index, - uint32_t* code_point) { + base_icu::UChar32* code_point) { if (CBU16_IS_SURROGATE(src[*char_index])) { if (!CBU16_IS_SURROGATE_LEAD(src[*char_index]) || *char_index + 1 >= src_len || @@ -58,7 +55,7 @@ bool ReadUnicodeCharacter(const wchar_t* src, int32_t src_len, int32_t* char_index, - uint32_t* code_point) { + base_icu::UChar32* code_point) { // Conversion is easy since the source is 32-bit. *code_point = src[*char_index];
diff --git a/base/strings/utf_string_conversion_utils.h b/base/strings/utf_string_conversion_utils.h index 640c7c6..877d264 100644 --- a/base/strings/utf_string_conversion_utils.h +++ b/base/strings/utf_string_conversion_utils.h
@@ -14,26 +14,29 @@ #include <string> #include "polyfills/base/base_export.h" +#include "base/third_party/icu/icu_utf.h" +#include "build/build_config.h" namespace gurl_base { -inline bool IsValidCodepoint(uint32_t code_point) { +inline bool IsValidCodepoint(base_icu::UChar32 code_point) { // Excludes code points that are not Unicode scalar values, i.e. // surrogate code points ([0xD800, 0xDFFF]). Additionally, excludes // code points larger than 0x10FFFF (the highest codepoint allowed). // Non-characters and unassigned code points are allowed. // https://unicode.org/glossary/#unicode_scalar_value - return code_point < 0xD800u || - (code_point >= 0xE000u && code_point <= 0x10FFFFu); + return (code_point >= 0 && code_point < 0xD800) || + (code_point >= 0xE000 && code_point <= 0x10FFFF); } -inline bool IsValidCharacter(uint32_t code_point) { +inline bool IsValidCharacter(base_icu::UChar32 code_point) { // Excludes non-characters (U+FDD0..U+FDEF, and all code points // ending in 0xFFFE or 0xFFFF) from the set of valid code points. // https://unicode.org/faq/private_use.html#nonchar1 - return code_point < 0xD800u || (code_point >= 0xE000u && - code_point < 0xFDD0u) || (code_point > 0xFDEFu && - code_point <= 0x10FFFFu && (code_point & 0xFFFEu) != 0xFFFEu); + return (code_point >= 0 && code_point < 0xD800) || + (code_point >= 0xE000 && code_point < 0xFDD0) || + (code_point > 0xFDEF && code_point <= 0x10FFFF && + (code_point & 0xFFFE) != 0xFFFE); } // ReadUnicodeCharacter -------------------------------------------------------- @@ -48,20 +51,20 @@ BASE_EXPORT bool ReadUnicodeCharacter(const char* src, int32_t src_len, int32_t* char_index, - uint32_t* code_point_out); + base_icu::UChar32* code_point_out); // Reads a UTF-16 character. The usage is the same as the 8-bit version above. BASE_EXPORT bool ReadUnicodeCharacter(const char16_t* src, int32_t src_len, int32_t* char_index, - uint32_t* code_point); + base_icu::UChar32* code_point); #if defined(WCHAR_T_IS_UTF32) // Reads UTF-32 character. The usage is the same as the 8-bit version above. BASE_EXPORT bool ReadUnicodeCharacter(const wchar_t* src, int32_t src_len, int32_t* char_index, - uint32_t* code_point); + base_icu::UChar32* code_point); #endif // defined(WCHAR_T_IS_UTF32) // WriteUnicodeCharacter -------------------------------------------------------
diff --git a/base/strings/utf_string_conversions.cc b/base/strings/utf_string_conversions.cc index 8cf90f1..2124231 100644 --- a/base/strings/utf_string_conversions.cc +++ b/base/strings/utf_string_conversions.cc
@@ -20,7 +20,7 @@ namespace { -constexpr int32_t kErrorCodePoint = 0xFFFD; +constexpr base_icu::UChar32 kErrorCodePoint = 0xFFFD; // Size coefficient ---------------------------------------------------------- // The maximum number of codeunits in the destination encoding corresponding to @@ -71,17 +71,23 @@ bool>; template <typename Char, EnableIfBitsAre<Char, 8> = true> -void UnicodeAppendUnsafe(Char* out, int32_t* size, uint32_t code_point) { - CBU8_APPEND_UNSAFE(out, *size, code_point); +void UnicodeAppendUnsafe(Char* out, + size_t* size, + base_icu::UChar32 code_point) { + CBU8_APPEND_UNSAFE(reinterpret_cast<uint8_t*>(out), *size, code_point); } template <typename Char, EnableIfBitsAre<Char, 16> = true> -void UnicodeAppendUnsafe(Char* out, int32_t* size, uint32_t code_point) { +void UnicodeAppendUnsafe(Char* out, + size_t* size, + base_icu::UChar32 code_point) { CBU16_APPEND_UNSAFE(out, *size, code_point); } template <typename Char, EnableIfBitsAre<Char, 32> = true> -void UnicodeAppendUnsafe(Char* out, int32_t* size, uint32_t code_point) { +void UnicodeAppendUnsafe(Char* out, + size_t* size, + base_icu::UChar32 code_point) { out[(*size)++] = code_point; } @@ -91,14 +97,14 @@ template <typename DestChar> bool DoUTFConversion(const char* src, - int32_t src_len, + size_t src_len, DestChar* dest, - int32_t* dest_len) { + size_t* dest_len) { bool success = true; - for (int32_t i = 0; i < src_len;) { - int32_t code_point; - CBU8_NEXT(src, i, src_len, code_point); + for (size_t i = 0; i < src_len;) { + base_icu::UChar32 code_point; + CBU8_NEXT(reinterpret_cast<const uint8_t*>(src), i, src_len, code_point); if (!IsValidCodepoint(code_point)) { success = false; @@ -113,12 +119,12 @@ template <typename DestChar> bool DoUTFConversion(const char16_t* src, - int32_t src_len, + size_t src_len, DestChar* dest, - int32_t* dest_len) { + size_t* dest_len) { bool success = true; - auto ConvertSingleChar = [&success](char16_t in) -> int32_t { + auto ConvertSingleChar = [&success](char16_t in) -> base_icu::UChar32 { if (!CBU16_IS_SINGLE(in) || !IsValidCodepoint(in)) { success = false; return kErrorCodePoint; @@ -126,12 +132,12 @@ return in; }; - int32_t i = 0; + size_t i = 0; // Always have another symbol in order to avoid checking boundaries in the // middle of the surrogate pair. - while (i < src_len - 1) { - int32_t code_point; + while (i + 1 < src_len) { + base_icu::UChar32 code_point; if (CBU16_IS_LEAD(src[i]) && CBU16_IS_TRAIL(src[i + 1])) { code_point = CBU16_GET_SUPPLEMENTARY(src[i], src[i + 1]); @@ -148,8 +154,9 @@ UnicodeAppendUnsafe(dest, dest_len, code_point); } - if (i < src_len) + if (i < src_len) { UnicodeAppendUnsafe(dest, dest_len, ConvertSingleChar(src[i])); + } return success; } @@ -158,13 +165,13 @@ template <typename DestChar> bool DoUTFConversion(const wchar_t* src, - int32_t src_len, + size_t src_len, DestChar* dest, - int32_t* dest_len) { + size_t* dest_len) { bool success = true; - for (int32_t i = 0; i < src_len; ++i) { - int32_t code_point = src[i]; + for (size_t i = 0; i < src_len; ++i) { + base_icu::UChar32 code_point = src[i]; if (!IsValidCodepoint(code_point)) { success = false; @@ -197,12 +204,12 @@ auto* dest = &(*dest_str)[0]; // ICU requires 32 bit numbers. - int32_t src_len32 = static_cast<int32_t>(src_str.length()); - int32_t dest_len32 = 0; + size_t src_len = src_str.length(); + size_t dest_len = 0; - bool res = DoUTFConversion(src_str.data(), src_len32, dest, &dest_len32); + bool res = DoUTFConversion(src_str.data(), src_len, dest, &dest_len); - dest_str->resize(dest_len32); + dest_str->resize(dest_len); dest_str->shrink_to_fit(); return res;
diff --git a/base/template_util.h b/base/template_util.h index c00791b..17db620 100644 --- a/base/template_util.h +++ b/base/template_util.h
@@ -6,6 +6,7 @@ #define BASE_TEMPLATE_UTIL_H_ #include <stddef.h> + #include <iosfwd> #include <iterator> #include <type_traits> @@ -15,10 +16,6 @@ namespace gurl_base { -template <class T> struct is_non_const_reference : std::false_type {}; -template <class T> struct is_non_const_reference<T&> : std::true_type {}; -template <class T> struct is_non_const_reference<const T&> : std::false_type {}; - namespace internal { // Uses expression SFINAE to detect whether using operator<< would work. @@ -59,35 +56,6 @@ } // namespace internal -// gurl_base::in_place_t is an implementation of std::in_place_t from -// C++17. A tag type used to request in-place construction in template vararg -// constructors. - -// Specification: -// https://en.cppreference.com/w/cpp/utility/in_place -struct in_place_t {}; -constexpr in_place_t in_place = {}; - -// gurl_base::in_place_type_t is an implementation of std::in_place_type_t from -// C++17. A tag type used for in-place construction when the type to construct -// needs to be specified, such as with gurl_base::unique_any, designed to be a -// drop-in replacement. - -// Specification: -// http://en.cppreference.com/w/cpp/utility/in_place -template <typename T> -struct in_place_type_t {}; - -template <typename T> -struct is_in_place_type_t { - static constexpr bool value = false; -}; - -template <typename... Ts> -struct is_in_place_type_t<in_place_type_t<Ts...>> { - static constexpr bool value = true; -}; - namespace internal { // The indirection with std::is_enum<T> is required, because instantiating @@ -145,8 +113,28 @@ // // Reference: https://wg21.link/readable.traits#2 template <typename Iter> -using iter_value_t = - typename std::iterator_traits<remove_cvref_t<Iter>>::value_type; +struct IterValueImpl { + using value_type = typename std::iterator_traits<Iter>::value_type; +}; + +template <typename T, bool Cond = false> +struct IterValuePointerImpl { + // The `iterator_traits<T*>::value_type` member is not defined if T is not an + // object in C++20. +}; +template <typename T> +struct IterValuePointerImpl<T*, true> { + using value_type = typename std::iterator_traits<T*>::value_type; +}; + +template <typename T> +struct IterValueImpl<T*> { + using value_type = + typename IterValuePointerImpl<T*, std::is_object_v<T>>::value_type; +}; + +template <typename Iter> +using iter_value_t = typename IterValueImpl<remove_cvref_t<Iter>>::value_type; // Simplified implementation of C++20's std::iter_reference_t. // As opposed to std::iter_reference_t, this implementation does not restrict
diff --git a/build/build_config.h b/build/build_config.h index 0102a93..a993e1e 100644 --- a/build/build_config.h +++ b/build/build_config.h
@@ -16,10 +16,10 @@ // // Operating System: // 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 +// IS_IOS / IS_IOS_MACCATALYST / IS_LINUX / IS_MAC / IS_NACL / IS_NETBSD / +// IS_OPENBSD / IS_QNX / IS_SOLARIS / IS_WIN // Operating System family: -// IS_APPLE: IOS or MAC +// IS_APPLE: IOS or MAC or IOS_MACCATALYST // 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 @@ -64,6 +64,11 @@ #include <TargetConditionals.h> #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE #define OS_IOS 1 +// Catalyst is the technology that allows running iOS apps on macOS. These +// builds are both OS_IOS and OS_IOS_MACCATALYST. +#if defined(TARGET_OS_MACCATALYST) && TARGET_OS_MACCATALYST +#define OS_IOS_MACCATALYST +#endif // defined(TARGET_OS_MACCATALYST) && TARGET_OS_MACCATALYST #else #define OS_MAC 1 #endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE @@ -180,6 +185,12 @@ #define BUILDFLAG_INTERNAL_IS_IOS() (0) #endif +#if defined(OS_IOS_MACCATALYST) +#define BUILDFLAG_INTERNAL_IS_IOS_MACCATALYST() (1) +#else +#define BUILDFLAG_INTERNAL_IS_IOS_MACCATALYST() (0) +#endif + #if defined(OS_LINUX) #define BUILDFLAG_INTERNAL_IS_LINUX() (1) #else
diff --git a/copy.bara.sky b/copy.bara.sky index 9741b8b..b1d8df5 100644 --- a/copy.bara.sky +++ b/copy.bara.sky
@@ -26,6 +26,7 @@ "base/functional/*.h", "base/i18n/uchar.h", "base/memory/raw_ptr.h", + "base/memory/raw_ptr_exclusion.h", "base/no_destructor.h", "base/ranges/*.h", "base/stl_util.h", @@ -101,7 +102,6 @@ # Fix some Perfetto includes. core.replace("perfetto/tracing/traced_value_forward.h", "perfetto/tracing/traced_value.h"), - core.replace("#include \"base/win/windows_types.h\"", "#include <windows.h>"), core.replace("#include \"base/strings/string_number_conversions_win.h\"", ""), core.replace("#include \"base/allocator/partition_allocator/partition_alloc_config.h\"", ""), core.replace("base/trace_event/base_tracing_forward.h", "polyfills/third_party/perfetto/include/perfetto/tracing/traced_value.h"),
diff --git a/url/gurl.cc b/url/gurl.cc index 5c6b76c..1337666 100644 --- a/url/gurl.cc +++ b/url/gurl.cc
@@ -439,12 +439,16 @@ } std::string GURL::GetContent() const { + return std::string(GetContentPiece()); +} + +gurl_base::StringPiece GURL::GetContentPiece() const { if (!is_valid_) - return std::string(); - std::string content = ComponentString(parsed_.GetContent()); + return gurl_base::StringPiece(); + url::Component content_component = parsed_.GetContent(); if (!SchemeIs(url::kJavaScriptScheme) && parsed_.ref.len >= 0) - content.erase(content.size() - parsed_.ref.len - 1); - return content; + content_component.len -= parsed_.ref.len + 1; + return ComponentStringPiece(content_component); } bool GURL::HostIsIPAddress() const {
diff --git a/url/gurl.h b/url/gurl.h index 63729ee..10ba992 100644 --- a/url/gurl.h +++ b/url/gurl.h
@@ -278,6 +278,7 @@ // It is an error to get the content of an invalid URL: the result will be an // empty string. std::string GetContent() const; + gurl_base::StringPiece GetContentPiece() const; // Returns true if the hostname is an IP address. Note: this function isn't // as cheap as a simple getter because it re-parses the hostname to verify.
diff --git a/url/gurl_unittest.cc b/url/gurl_unittest.cc index 6dd1fc0..24e8f94 100644 --- a/url/gurl_unittest.cc +++ b/url/gurl_unittest.cc
@@ -929,6 +929,7 @@ for (const auto& test : cases) { GURL url(test.url); EXPECT_EQ(test.expected, url.GetContent()) << test.url; + EXPECT_EQ(test.expected, url.GetContentPiece()) << test.url; } }
diff --git a/url/origin.h b/url/origin.h index 1b0a407..6769535 100644 --- a/url/origin.h +++ b/url/origin.h
@@ -119,16 +119,9 @@ // * The host component of an IPv6 address includes brackets, just like the URL // representation. // -// Usage: -// -// * Origins are generally constructed from an already-canonicalized GURL: -// -// GURL url("https://example.com/"); -// url::Origin origin = Origin::Create(url); -// origin.scheme(); // "https" -// origin.host(); // "example.com" -// origin.port(); // 443 -// origin.opaque(); // false +// * Constructing origins from GURLs (or from SchemeHostPort) is typically a red +// flag (this is true for `url::Origin::Create` but also to some extent for +// `url::Origin::Resolve`). See docs/security/origin-vs-url.md for more. // // * To answer the question "Are |this| and |that| "same-origin" with each // other?", use |Origin::IsSameOriginWith|: @@ -142,29 +135,46 @@ // existing origins. Origin(); - // Creates an Origin from |url|, as described at - // https://url.spec.whatwg.org/#origin, with the following additions: + // WARNING: Converting an URL into an Origin is usually a red flag. See + // //docs/security/origin-vs-url.md for more details. Some discussion about + // deprecating the Create method can be found in https://crbug.com/1270878. // - // 1. If |url| is invalid or non-standard, an opaque Origin is constructed. + // Creates an Origin from `url`, as described at + // https://url.spec.whatwg.org/#origin, with the following additions: + // 1. If `url` is invalid or non-standard, an opaque Origin is constructed. // 2. 'filesystem' URLs behave as 'blob' URLs (that is, the origin is parsed // out of everything in the URL which follows the scheme). // 3. 'file' URLs all parse as ("file", "", 0). // - // Note that the returned Origin may have a different scheme and host from - // |url| (e.g. in case of blob URLs - see OriginTest.ConstructFromGURL). + // WARNING: `url::Origin::Create(url)` can give unexpected results if: + // 1) `url` is "about:blank", or "about:srcdoc" (returning unique, opaque + // origin rather than the real origin of the frame) + // 2) `url` comes from a sandboxed frame (potentially returning a non-opaque + // origin, when an opaque one is needed; see also + // https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/) + // 3) Wrong `url` is used - e.g. in some navigations `base_url_for_data_url` + // might need to be used instead of relying on + // `content::NavigationHandle::GetURL`. + // + // WARNING: The returned Origin may have a different scheme and host from + // `url` (e.g. in case of blob URLs - see OriginTest.ConstructFromGURL). + // + // WARNING: data: URLs will be correctly be translated into opaque origins, + // but the precursor origin will be lost (unlike with `url::Origin::Resolve`). static Origin Create(const GURL& url); - // Creates an Origin for the resource |url| as if it were requested - // from the context of |base_origin|. If |url| is standard + // Creates an Origin for the resource `url` as if it were requested + // from the context of `base_origin`. If `url` is standard // (in the sense that it embeds a complete origin, like http/https), // this returns the same value as would Create(). // - // If |url| is "about:blank", this returns a copy of |base_origin|. + // If `url` is "about:blank" or "about:srcdoc", this returns a copy of + // `base_origin`. // - // Otherwise, returns a new opaque origin derived from |base_origin|. + // Otherwise, returns a new opaque origin derived from `base_origin`. // In this case, the resulting opaque origin will inherit the tuple - // (or precursor tuple) of |base_origin|, but will not be same origin - // with |base_origin|, even if |base_origin| is already opaque. + // (or precursor tuple) of `base_origin`, but will not be same origin + // with `base_origin`, even if `base_origin` is already opaque. static Origin Resolve(const GURL& url, const Origin& base_origin); // Copyable and movable. @@ -222,9 +232,9 @@ } // 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 + // 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 + // "same-origin" with any origin. This method is a shorthand for // `origin.IsSameOriginWith(url::Origin::Create(url))`. // // See also CanBeDerivedFrom. @@ -442,9 +452,9 @@ COMPONENT_EXPORT(URL) bool IsSameOriginWith(const GURL& a, const GURL& b); -// DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) copies |origin| into a new -// stack-allocated variable named |<var_name>|. This helps ensure that the -// value of |origin| gets preserved in crash dumps. +// DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) copies `origin` into a new +// stack-allocated variable named `<var_name>`. This helps ensure that the +// value of `origin` gets preserved in crash dumps. #define DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) \ DEBUG_ALIAS_FOR_CSTR(var_name, (origin).Serialize().c_str(), 128)
diff --git a/url/scheme_host_port.h b/url/scheme_host_port.h index 8d5acd9..70df243 100644 --- a/url/scheme_host_port.h +++ b/url/scheme_host_port.h
@@ -133,7 +133,10 @@ std::string Serialize() const; // Efficiently returns what GURL(Serialize()) would return, without needing to - // re-parse the URL. + // re-parse the URL. Note: this still performs allocations to copy data into + // GURL, so please avoid using this method if you only need to work on + // schemes, hosts, or ports individually. + // For example, see crrev.com/c/3637099/comments/782360d0_e14757be. GURL GetURL() const; // Two SchemeHostPort objects are "equal" iff their schemes, hosts, and ports
diff --git a/url/url_canon.h b/url/url_canon.h index e935d7f..cab7d29 100644 --- a/url/url_canon.h +++ b/url/url_canon.h
@@ -10,6 +10,7 @@ #include "polyfills/base/component_export.h" #include "polyfills/base/export_template.h" +#include "base/memory/raw_ptr_exclusion.h" #include "url/third_party/mozilla/url_parse.h" namespace url { @@ -139,7 +140,7 @@ // `buffer_` is not a raw_ptr<...> for performance reasons (based on analysis // of sampling profiler data). - T* buffer_; + RAW_PTR_EXCLUSION T* buffer_; int buffer_len_; // Used characters in the buffer.
diff --git a/url/url_canon_internal.cc b/url/url_canon_internal.cc index 99541bd..bbb27a0 100644 --- a/url/url_canon_internal.cc +++ b/url/url_canon_internal.cc
@@ -25,7 +25,7 @@ if (static_cast<UCHAR>(source[i]) >= 0x80) { // ReadChar will fill the code point with kUnicodeReplacementCharacter // when the input is invalid, which is what we want. - unsigned code_point; + base_icu::UChar32 code_point; ReadUTFChar(source, &i, length, &code_point); AppendUTF8EscapedValue(code_point, output); } else { @@ -233,7 +233,7 @@ 0, // 0xE0 - 0xFF }; -const char16_t kUnicodeReplacementCharacter = 0xfffd; +const base_icu::UChar32 kUnicodeReplacementCharacter = 0xfffd; void AppendStringOfType(const char* source, int length, SharedCharTypes type, @@ -248,8 +248,10 @@ DoAppendStringOfType<char16_t, char16_t>(source, length, type, output); } -bool ReadUTFChar(const char* str, int* begin, int length, - unsigned* code_point_out) { +bool ReadUTFChar(const char* str, + int* begin, + int length, + base_icu::UChar32* code_point_out) { // This depends on ints and int32s being the same thing. If they're not, it // will fail to compile. // TODO(mmenke): This should probably be fixed. @@ -264,7 +266,7 @@ bool ReadUTFChar(const char16_t* str, int* begin, int length, - unsigned* code_point_out) { + base_icu::UChar32* code_point_out) { // This depends on ints and int32s being the same thing. If they're not, it // will fail to compile. // TODO(mmenke): This should probably be fixed. @@ -293,7 +295,7 @@ CanonOutput* output) { bool success = true; for (int i = 0; i < input_len; i++) { - unsigned code_point; + base_icu::UChar32 code_point; success &= ReadUTFChar(input, &i, input_len, &code_point); AppendUTF8Value(code_point, output); } @@ -305,7 +307,7 @@ CanonOutputT<char16_t>* output) { bool success = true; for (int i = 0; i < input_len; i++) { - unsigned code_point; + base_icu::UChar32 code_point; success &= ReadUTFChar(input, &i, input_len, &code_point); AppendUTF16Value(code_point, output); }
diff --git a/url/url_canon_internal.h b/url/url_canon_internal.h index d674976..807ddc5 100644 --- a/url/url_canon_internal.h +++ b/url/url_canon_internal.h
@@ -15,6 +15,7 @@ #include "polyfills/base/component_export.h" #include "polyfills/base/notreached.h" +#include "base/third_party/icu/icu_utf.h" #include "url/url_canon.h" namespace url { @@ -139,7 +140,7 @@ } // The character we'll substitute for undecodable or invalid characters. -extern const char16_t kUnicodeReplacementCharacter; +extern const base_icu::UChar32 kUnicodeReplacementCharacter; // UTF-8 functions ------------------------------------------------------------ @@ -155,7 +156,7 @@ bool ReadUTFChar(const char* str, int* begin, int length, - unsigned* code_point_out); + base_icu::UChar32* code_point_out); // Generic To-UTF-8 converter. This will call the given append method for each // character that should be appended, with the given output method. Wrappers @@ -163,8 +164,10 @@ // // The char_value must have already been checked that it's a valid Unicode // character. -template<class Output, void Appender(unsigned char, Output*)> -inline void DoAppendUTF8(unsigned char_value, Output* output) { +template <class Output, void Appender(unsigned char, Output*)> +inline void DoAppendUTF8(base_icu::UChar32 char_value, Output* output) { + GURL_DCHECK(char_value >= 0); + GURL_DCHECK(char_value <= 0x10FFFF); if (char_value <= 0x7f) { Appender(static_cast<unsigned char>(char_value), output); } else if (char_value <= 0x7ff) { @@ -181,7 +184,7 @@ output); Appender(static_cast<unsigned char>(0x80 | (char_value & 0x3f)), output); - } else if (char_value <= 0x10FFFF) { // Max Unicode code point. + } else { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Appender(static_cast<unsigned char>(0xf0 | (char_value >> 18)), output); @@ -189,11 +192,7 @@ output); Appender(static_cast<unsigned char>(0x80 | ((char_value >> 6) & 0x3f)), output); - Appender(static_cast<unsigned char>(0x80 | (char_value & 0x3f)), - output); - } else { - // Invalid UTF-8 character (>20 bits). - GURL_NOTREACHED(); + Appender(static_cast<unsigned char>(0x80 | (char_value & 0x3f)), output); } } @@ -207,7 +206,7 @@ // Writes the given character to the output as UTF-8. This does NO checking // of the validity of the Unicode characters; the caller should ensure that // the value it is appending is valid to append. -inline void AppendUTF8Value(unsigned char_value, CanonOutput* output) { +inline void AppendUTF8Value(base_icu::UChar32 char_value, CanonOutput* output) { DoAppendUTF8<CanonOutput, AppendCharToOutput>(char_value, output); } @@ -215,7 +214,8 @@ // characters (even when they are ASCII). This does NO checking of the // validity of the Unicode characters; the caller should ensure that the value // it is appending is valid to append. -inline void AppendUTF8EscapedValue(unsigned char_value, CanonOutput* output) { +inline void AppendUTF8EscapedValue(base_icu::UChar32 char_value, + CanonOutput* output) { DoAppendUTF8<CanonOutput, AppendEscapedChar>(char_value, output); } @@ -233,10 +233,10 @@ bool ReadUTFChar(const char16_t* str, int* begin, int length, - unsigned* code_point_out); + base_icu::UChar32* code_point_out); // Equivalent to U16_APPEND_UNSAFE in ICU but uses our output method. -inline void AppendUTF16Value(unsigned code_point, +inline void AppendUTF16Value(base_icu::UChar32 code_point, CanonOutputT<char16_t>* output) { if (code_point > 0xffff) { output->push_back(static_cast<char16_t>((code_point >> 10) + 0xd7c0)); @@ -274,7 +274,7 @@ // UTF-16 input. ReadUTFChar will handle invalid characters for us and give // us the kUnicodeReplacementCharacter, so we don't have to do special // checking after failure, just pass through the failure to the caller. - unsigned char_value; + base_icu::UChar32 char_value; bool success = ReadUTFChar(str, begin, length, &char_value); AppendUTF8EscapedValue(char_value, output); return success; @@ -286,7 +286,7 @@ // ReadUTF8Char will handle invalid characters for us and give us the // kUnicodeReplacementCharacter, so we don't have to do special checking // after failure, just pass through the failure to the caller. - unsigned ch; + base_icu::UChar32 ch; bool success = ReadUTFChar(str, begin, length, &ch); AppendUTF8EscapedValue(ch, output); return success;
diff --git a/url/url_canon_stdstring.h b/url/url_canon_stdstring.h index e9adc43..d8b94ec 100644 --- a/url/url_canon_stdstring.h +++ b/url/url_canon_stdstring.h
@@ -13,6 +13,7 @@ #include "base/compiler_specific.h" #include "polyfills/base/component_export.h" +#include "base/memory/raw_ptr_exclusion.h" #include "base/strings/string_piece.h" #include "url/url_canon.h" @@ -50,7 +51,7 @@ 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_; + RAW_PTR_EXCLUSION std::string* str_; }; // An extension of the Replacements class that allows the setters to use
diff --git a/url/url_util.cc b/url/url_util.cc index 26657f7..f56323e 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -151,9 +151,9 @@ const char* compare_to) { if (!component.is_nonempty()) return compare_to[0] == 0; // When component is empty, match empty scheme. - return gurl_base::LowerCaseEqualsASCII( - typename CharToStringPiece<CHAR>::Piece( - &spec[component.begin], component.len), + return gurl_base::EqualsCaseInsensitiveASCII( + typename CharToStringPiece<CHAR>::Piece(&spec[component.begin], + component.len), compare_to); } @@ -168,9 +168,10 @@ return false; // Empty or invalid schemes are non-standard. for (const SchemeWithType& scheme_with_type : schemes) { - if (gurl_base::LowerCaseEqualsASCII(typename CharToStringPiece<CHAR>::Piece( - &spec[scheme.begin], scheme.len), - scheme_with_type.scheme)) { + if (gurl_base::EqualsCaseInsensitiveASCII( + typename CharToStringPiece<CHAR>::Piece(&spec[scheme.begin], + scheme.len), + scheme_with_type.scheme)) { *type = scheme_with_type.type; return true; } @@ -838,14 +839,14 @@ // next_ch will point to the last character of the decoded // character. int next_character = i; - unsigned code_point; + base_icu::UChar32 code_point; if (ReadUTFChar(unescaped_chars.data(), &next_character, unescaped_chars.length(), &code_point)) { // Valid UTF-8 character, convert to UTF-16. AppendUTF16Value(code_point, output); i = next_character; } else if (mode == DecodeURLMode::kUTF8) { - GURL_DCHECK_EQ(code_point, 0xFFFDU); + GURL_DCHECK_EQ(code_point, 0xFFFD); AppendUTF16Value(code_point, output); i = next_character; } else {