summarylogtreecommitdiffstats
path: root/fix-wrong-string-initialization-in-LinkedHashSet.patch
blob: 0047c99f044d5d77aedae041294d6e714cf026e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
From 74138b9febd37eac0fc26b8efb110014a83a52c6 Mon Sep 17 00:00:00 2001
From: Jeremy Roman <jbroman@chromium.org>
Date: Wed, 7 Aug 2019 13:26:48 +0000
Subject: [PATCH] WTF: Make LinkedHashSet understand values for which memset
 initialization would be bad.

Includes a unit test which fails before, and uses this to fix FontCacheKeyTraits.

Bug: 980025
Change-Id: If41f97444c7fd37b9b95d6dadaf3da5689079e9e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1739948
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#684731}
---
 .../renderer/platform/fonts/font_cache_key.h  |  4 ++
 .../renderer/platform/wtf/linked_hash_set.h   | 10 ++++-
 .../platform/wtf/list_hash_set_test.cc        | 45 +++++++++++++++++--
 3 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/third_party/blink/renderer/platform/fonts/font_cache_key.h b/third_party/blink/renderer/platform/fonts/font_cache_key.h
index 0efc8fb909..90063cb2ea 100644
--- a/third_party/blink/renderer/platform/fonts/font_cache_key.h
+++ b/third_party/blink/renderer/platform/fonts/font_cache_key.h
@@ -133,6 +133,10 @@ struct FontCacheKeyHash {
 
 struct FontCacheKeyTraits : WTF::SimpleClassHashTraits<FontCacheKey> {
   STATIC_ONLY(FontCacheKeyTraits);
+
+  // std::string's empty state need not be zero in all implementations,
+  // and it is held within FontFaceCreationParams.
+  static const bool kEmptyValueIsZero = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
index b35b6e95f1..77e524c084 100644
--- a/third_party/blink/renderer/platform/wtf/linked_hash_set.h
+++ b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -146,6 +146,11 @@ class LinkedHashSetNode : public LinkedHashSetNodeBase {
                     LinkedHashSetNodeBase* next)
       : LinkedHashSetNodeBase(prev, next), value_(value) {}
 
+  LinkedHashSetNode(ValueArg&& value,
+                    LinkedHashSetNodeBase* prev,
+                    LinkedHashSetNodeBase* next)
+      : LinkedHashSetNodeBase(prev, next), value_(std::move(value)) {}
+
   LinkedHashSetNode(LinkedHashSetNode&& other)
       : LinkedHashSetNodeBase(std::move(other)),
         value_(std::move(other.value_)) {}
@@ -445,10 +450,13 @@ struct LinkedHashSetTraits
 
   // The slot is empty when the next_ field is zero so it's safe to zero
   // the backing.
-  static const bool kEmptyValueIsZero = true;
+  static const bool kEmptyValueIsZero = ValueTraits::kEmptyValueIsZero;
 
   static const bool kHasIsEmptyValueFunction = true;
   static bool IsEmptyValue(const Node& node) { return !node.next_; }
+  static Node EmptyValue() {
+    return Node(ValueTraits::EmptyValue(), nullptr, nullptr);
+  }
 
   static const int kDeletedValue = -1;
 
diff --git a/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc b/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc
index 4c3f8990b0..cd1be0089b 100644
--- a/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc
+++ b/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc
@@ -487,6 +487,7 @@ struct Simple {
 };
 
 struct Complicated {
+  Complicated() : Complicated(0) {}
   Complicated(int value) : simple_(value) { objects_constructed_++; }
 
   Complicated(const Complicated& other) : simple_(other.simple_) {
@@ -495,9 +496,6 @@ struct Complicated {
 
   Simple simple_;
   static int objects_constructed_;
-
- private:
-  Complicated() = delete;
 };
 
 int Complicated::objects_constructed_ = 0;
@@ -731,4 +729,45 @@ TYPED_TEST(ListOrLinkedHashSetMoveOnlyTest, MoveOnlyValue) {
 
 }  // anonymous namespace
 
+// A unit type which objects to its state being initialized wrong.
+struct InvalidZeroValue {
+  InvalidZeroValue() = default;
+  InvalidZeroValue(WTF::HashTableDeletedValueType) : deleted_(true) {}
+  ~InvalidZeroValue() { CHECK(ok_); }
+  bool IsHashTableDeletedValue() const { return deleted_; }
+
+  bool ok_ = true;
+  bool deleted_ = false;
+};
+
+template <>
+struct HashTraits<InvalidZeroValue> : SimpleClassHashTraits<InvalidZeroValue> {
+  static const bool kEmptyValueIsZero = false;
+};
+
+template <>
+struct DefaultHash<InvalidZeroValue> {
+  struct Hash {
+    static unsigned GetHash(const InvalidZeroValue&) { return 0; }
+    static bool Equal(const InvalidZeroValue&, const InvalidZeroValue&) {
+      return true;
+    }
+  };
+};
+
+template <typename Set>
+class ListOrLinkedHashSetInvalidZeroTest : public testing::Test {};
+
+using InvalidZeroValueSetTypes =
+    testing::Types<ListHashSet<InvalidZeroValue>,
+                   ListHashSet<InvalidZeroValue, 1>,
+                   LinkedHashSet<InvalidZeroValue>>;
+TYPED_TEST_SUITE(ListOrLinkedHashSetInvalidZeroTest, InvalidZeroValueSetTypes);
+
+TYPED_TEST(ListOrLinkedHashSetInvalidZeroTest, InvalidZeroValue) {
+  using Set = TypeParam;
+  Set set;
+  set.insert(InvalidZeroValue());
+}
+
 }  // namespace WTF