Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp

Issue 1555653002: Handle some failing DocumentOrderedMap ID lookups across tree removals. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: non-assert buildfix Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 43
44 PassOwnPtrWillBeRawPtr<DocumentOrderedMap> DocumentOrderedMap::create() 44 PassOwnPtrWillBeRawPtr<DocumentOrderedMap> DocumentOrderedMap::create()
45 { 45 {
46 return adoptPtrWillBeNoop(new DocumentOrderedMap); 46 return adoptPtrWillBeNoop(new DocumentOrderedMap);
47 } 47 }
48 48
49 DocumentOrderedMap::DocumentOrderedMap() 49 DocumentOrderedMap::DocumentOrderedMap()
50 { 50 {
51 } 51 }
52 52
53 DocumentOrderedMap::~DocumentOrderedMap() 53 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentOrderedMap);
54
55 #if ENABLE(ASSERT)
56 static int s_removeScopeLevel = 0;
57
58 DocumentOrderedMap::RemoveScope::RemoveScope()
54 { 59 {
60 s_removeScopeLevel++;
55 } 61 }
56 62
63 DocumentOrderedMap::RemoveScope::~RemoveScope()
64 {
65 ASSERT(s_removeScopeLevel);
66 s_removeScopeLevel--;
67 }
68 #endif
69
57 inline bool keyMatchesId(const AtomicString& key, const Element& element) 70 inline bool keyMatchesId(const AtomicString& key, const Element& element)
58 { 71 {
59 return element.getIdAttribute() == key; 72 return element.getIdAttribute() == key;
60 } 73 }
61 74
62 inline bool keyMatchesMapName(const AtomicString& key, const Element& element) 75 inline bool keyMatchesMapName(const AtomicString& key, const Element& element)
63 { 76 {
64 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k ey; 77 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k ey;
65 } 78 }
66 79
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } else { 120 } else {
108 if (entry->element == element) { 121 if (entry->element == element) {
109 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element); 122 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element);
110 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[ 1] : nullptr; 123 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[ 1] : nullptr;
111 } 124 }
112 entry->count--; 125 entry->count--;
113 entry->orderedList.clear(); 126 entry->orderedList.clear();
114 } 127 }
115 } 128 }
116 129
117 #if ENABLE(ASSERT)
118 void DocumentOrderedMap::willRemoveId(const AtomicString& key)
119 {
120 ASSERT(m_removingId.isNull() || key.isNull());
121 m_removingId = key;
122 }
123 #endif
124
125 template<bool keyMatches(const AtomicString&, const Element&)> 130 template<bool keyMatches(const AtomicString&, const Element&)>
126 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope * scope) const 131 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope * scope) const
127 { 132 {
128 ASSERT(key); 133 ASSERT(key);
129 ASSERT(scope); 134 ASSERT(scope);
130 135
131 MapEntry* entry = m_map.get(key); 136 MapEntry* entry = m_map.get(key);
132 if (!entry) 137 if (!entry)
133 return 0; 138 return 0;
134 139
135 ASSERT(entry->count); 140 ASSERT(entry->count);
136 if (entry->element) 141 if (entry->element)
137 return entry->element; 142 return entry->element;
138 143
139 // Iterate to find the node that matches. Nothing will match iff an element 144 // Iterate to find the node that matches. Nothing will match iff an element
140 // with children having duplicate IDs is being removed -- the tree traversal 145 // with children having duplicate IDs is being removed -- the tree traversal
141 // will be over an updated tree not having that element. In all other cases, 146 // will be over an updated tree not having that subtree. In all other cases,
142 // a match is expected. 147 // a match is expected.
143 //
144 // Such calls to get()/getElementById() while handling element removals will
145 // legitimately happen when e.g., adjusting form ID associations. Quietly
146 // allow those lookups to (expectedly) fail by having the tree scope removal
147 // register the element ID it is in the process of removing.
148 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { 148 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) {
149 if (!keyMatches(key, element)) 149 if (!keyMatches(key, element))
150 continue; 150 continue;
151 entry->element = &element; 151 entry->element = &element;
152 return &element; 152 return &element;
153 } 153 }
154 ASSERT(key == m_removingId); 154 // As get()/getElementById() can legitimately be called while handling eleme nt
155 // removals, allow failure iff we're in the scope of node removals.
156 ASSERT(s_removeScopeLevel);
155 return 0; 157 return 0;
156 } 158 }
157 159
158 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS cope* scope) const 160 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS cope* scope) const
159 { 161 {
160 return get<keyMatchesId>(key, scope); 162 return get<keyMatchesId>(key, scope);
161 } 163 }
162 164
163 const WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE lementsById(const AtomicString& key, const TreeScope* scope) const 165 const WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE lementsById(const AtomicString& key, const TreeScope* scope) const
164 { 166 {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 214
213 DEFINE_TRACE(DocumentOrderedMap::MapEntry) 215 DEFINE_TRACE(DocumentOrderedMap::MapEntry)
214 { 216 {
215 visitor->trace(element); 217 visitor->trace(element);
216 #if ENABLE(OILPAN) 218 #if ENABLE(OILPAN)
217 visitor->trace(orderedList); 219 visitor->trace(orderedList);
218 #endif 220 #endif
219 } 221 }
220 222
221 } // namespace blink 223 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/DocumentOrderedMap.h ('k') | third_party/WebKit/Source/core/dom/TreeScope.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698