summaryrefslogtreecommitdiff
path: root/absl/algorithm/container.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-10-02 10:17:27 -0700
committerGravatar Andy Getz <durandal@google.com>2020-10-02 22:03:20 -0400
commit887d0eee6bab35847253181b32e78ff707010ccd (patch)
treeacaa30bb0aee7dba9371367bb4833424178cd78f /absl/algorithm/container.h
parentb978fc02f02ba79c545f99d0d65bd066fb8cebf8 (diff)
Export of internal Abseil changes
-- d6e582e21ceec768aa72e857c10ba80cad2f2202 by Abseil Team <absl-team@google.com>: adds bounds-checking for the second range in absl::c_mismatch The API for the two-range absl::c_mismatch is misleading as it doesn't check the bounds of the second range against the first one. This commit cleans up the internals of the overload to make sure that buggy calls are not exploitable; non-buggy calls are unaffected. This is consistent with both C++14's two-range std::mismatch and C++20's std::ranges::mismatch (see http://wg21.link/mismatch). PiperOrigin-RevId: 335050236 GitOrigin-RevId: d6e582e21ceec768aa72e857c10ba80cad2f2202 Change-Id: I77e0d030adf35c09069ceab5ea67efdf09377390
Diffstat (limited to 'absl/algorithm/container.h')
-rw-r--r--absl/algorithm/container.h39
1 files changed, 29 insertions, 10 deletions
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index 5c033571..7778ab17 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -340,24 +340,43 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_count_if(
// c_mismatch()
//
// Container-based version of the <algorithm> `std::mismatch()` function to
-// return the first element where two ordered containers differ.
+// return the first element where two ordered containers differ. Applies `==` to
+// the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
template <typename C1, typename C2>
container_algorithm_internal::ContainerIterPairType<C1, C2>
c_mismatch(C1& c1, C2& c2) {
- return std::mismatch(container_algorithm_internal::c_begin(c1),
- container_algorithm_internal::c_end(c1),
- container_algorithm_internal::c_begin(c2));
+ auto first1 = container_algorithm_internal::c_begin(c1);
+ auto last1 = container_algorithm_internal::c_end(c1);
+ auto first2 = container_algorithm_internal::c_begin(c2);
+ auto last2 = container_algorithm_internal::c_end(c2);
+
+ for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
+ if (*first1 != *first2) {
+ break;
+ }
+ }
+
+ return std::make_pair(first1, first2);
}
// Overload of c_mismatch() for using a predicate evaluation other than `==` as
-// the function's test condition.
+// the function's test condition. Applies `pred`to the first N elements of `c1`
+// and `c2`, where N = min(size(c1), size(c2)).
template <typename C1, typename C2, typename BinaryPredicate>
container_algorithm_internal::ContainerIterPairType<C1, C2>
-c_mismatch(C1& c1, C2& c2, BinaryPredicate&& pred) {
- return std::mismatch(container_algorithm_internal::c_begin(c1),
- container_algorithm_internal::c_end(c1),
- container_algorithm_internal::c_begin(c2),
- std::forward<BinaryPredicate>(pred));
+c_mismatch(C1& c1, C2& c2, BinaryPredicate pred) {
+ auto first1 = container_algorithm_internal::c_begin(c1);
+ auto last1 = container_algorithm_internal::c_end(c1);
+ auto first2 = container_algorithm_internal::c_begin(c2);
+ auto last2 = container_algorithm_internal::c_end(c2);
+
+ for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
+ if (!pred(*first1, *first2)) {
+ break;
+ }
+ }
+
+ return std::make_pair(first1, first2);
}
// c_equal()