Changeset 282505 in webkit
- Timestamp:
- Sep 16, 2021, 1:26:42 AM (4 years ago)
- Location:
- releases/WebKitGTK/webkit-2.32/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
releases/WebKitGTK/webkit-2.32/Source/WebCore/ChangeLog
r282504 r282505 1 2021-04-15 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 REGRESSION(r272900): Nullptr crash in ComposedTreeIterator::traverseNextInShadowTree() via ShadowRoot::hostChildElementDidChange 4 https://bugs.webkit.org/show_bug.cgi?id=222720 5 6 Reviewed by Ryosuke Niwa. 7 8 This patch reverts r274064 to apply a different fix. Instead of null-checking the nodes returned by 9 SlotAssignment::assignedNodesForSlot(), assigned nodes are removed from the list when they are about to be 10 removed from the parent. That ensures we never return nullptr nodes nor nodes with a nullptr parent from the 11 assigned nodes vector. 12 13 * dom/ComposedTreeIterator.cpp: 14 (WebCore::ComposedTreeIterator::traverseNextInShadowTree): 15 (WebCore::ComposedTreeIterator::advanceInSlot): 16 * dom/ContainerNode.cpp: 17 (WebCore::ContainerNode::removeBetween): 18 * dom/Node.h: 19 (WebCore::Node::hasShadowRootContainingSlots const): 20 (WebCore::Node::setHasShadowRootContainingSlots): 21 * dom/ShadowRoot.h: 22 * dom/SlotAssignment.cpp: 23 (WebCore::SlotAssignment::addSlotElementByName): 24 (WebCore::SlotAssignment::removeSlotElementByName): 25 (WebCore::SlotAssignment::willRemoveAssignedNode): 26 * dom/SlotAssignment.h: 27 (WebCore::ShadowRoot::willRemoveAssignedNode): 28 1 29 2021-04-14 Ryosuke Niwa <rniwa@webkit.org> 2 30 -
releases/WebKitGTK/webkit-2.32/Source/WebCore/dom/ComposedTreeIterator.cpp
r280832 r282505 163 163 auto& slot = downcast<HTMLSlotElement>(current()); 164 164 if (auto* assignedNodes = slot.assignedNodes()) { 165 if (auto assignedNode = assignedNodes->at(0)) { 166 context().slotNodeIndex = 0; 167 m_contextStack.append(Context(*assignedNode->parentElement(), *assignedNode, Context::Slotted)); 168 return; 169 } 165 context().slotNodeIndex = 0; 166 auto* assignedNode = assignedNodes->at(0).get(); 167 ASSERT(assignedNode); 168 ASSERT(assignedNode->parentElement()); 169 m_contextStack.append(Context(*assignedNode->parentElement(), *assignedNode, Context::Slotted)); 170 return; 170 171 } 171 172 } … … 200 201 201 202 auto* slotNode = assignedNodes.at(context().slotNodeIndex).get(); 202 if (!slotNode)203 return false;203 ASSERT(slotNode); 204 ASSERT(slotNode->parentElement()); 204 205 m_contextStack.append(Context(*slotNode->parentElement(), *slotNode, Context::Slotted)); 205 206 return true; -
releases/WebKitGTK/webkit-2.32/Source/WebCore/dom/ContainerNode.cpp
r280835 r282505 631 631 destroyRenderTreeIfNeeded(oldChild); 632 632 633 if (UNLIKELY(hasShadowRootContainingSlots())) 634 shadowRoot()->willRemoveAssignedNode(oldChild); 635 633 636 if (nextChild) { 634 637 nextChild->setPreviousSibling(previousChild); -
releases/WebKitGTK/webkit-2.32/Source/WebCore/dom/Node.h
r280901 r282505 223 223 void setHasSyntheticAttrChildNodes(bool flag) { setNodeFlag(NodeFlag::HasSyntheticAttrChildNodes, flag); } 224 224 225 bool hasShadowRootContainingSlots() const { return hasNodeFlag(NodeFlag::HasShadowRootContainingSlots); } 226 void setHasShadowRootContainingSlots(bool flag) { setNodeFlag(NodeFlag::HasShadowRootContainingSlots, flag); } 227 225 228 // If this node is in a shadow tree, returns its shadow host. Otherwise, returns null. 226 229 WEBCORE_EXPORT Element* shadowHost() const; … … 567 570 InclusiveAncestorStateForForm = 1 << 28, 568 571 InclusiveAncestorStateForCanvas = 1 << 29, 569 // Bits 30-31 are free. 572 HasShadowRootContainingSlots = 1 << 30, 573 // Bit 31 is free. 570 574 }; 571 575 -
releases/WebKitGTK/webkit-2.32/Source/WebCore/dom/ShadowRoot.h
r266212 r282505 94 94 void resolveSlotsBeforeNodeInsertionOrRemoval(); 95 95 void willRemoveAllChildren(ContainerNode&); 96 void willRemoveAssignedNode(const Node&); 96 97 97 98 void didRemoveAllChildrenOfShadowHost(); -
releases/WebKitGTK/webkit-2.32/Source/WebCore/dom/SlotAssignment.cpp
r282498 r282505 125 125 assignSlots(shadowRoot); 126 126 127 shadowRoot.host()->setHasShadowRootContainingSlots(true); 128 m_slotElementCount++; 129 127 130 bool needsSlotchangeEvent = shadowRoot.shouldFireSlotchangeEvent() && hasAssignedNodes(shadowRoot, slot); 128 131 … … 152 155 #endif 153 156 154 if (auto* host = shadowRoot.host()) // FIXME: We should be able to do a targeted reconstruction. 157 ASSERT(m_slotElementCount > 0); 158 m_slotElementCount--; 159 160 if (auto host = makeRefPtr(shadowRoot.host())) { 161 // FIXME: We should be able to do a targeted reconstruction. 155 162 host->invalidateStyleAndRenderersForSubtree(); 163 if (!m_slotElementCount) 164 host->setHasShadowRootContainingSlots(false); 165 } 156 166 157 167 auto* slot = m_slots.get(slotNameFromAttributeValue(name)); … … 338 348 } 339 349 350 void SlotAssignment::willRemoveAssignedNode(const Node& node) 351 { 352 if (!m_slotAssignmentsIsValid) 353 return; 354 355 if (!is<Text>(node) && !is<Element>(node)) 356 return; 357 358 auto* slot = m_slots.get(slotNameForHostChild(node)); 359 if (!slot || slot->assignedNodes.isEmpty()) 360 return; 361 362 slot->assignedNodes.removeFirstMatching([&node](const auto& item) { 363 return item.get() == &node; 364 }); 365 } 366 340 367 const AtomString& SlotAssignment::slotNameForHostChild(const Node& child) const 341 368 { -
releases/WebKitGTK/webkit-2.32/Source/WebCore/dom/SlotAssignment.h
r282498 r282505 61 61 62 62 const Vector<WeakPtr<Node>>* assignedNodesForSlot(const HTMLSlotElement&, ShadowRoot&); 63 void willRemoveAssignedNode(const Node&); 63 64 64 65 virtual void hostChildElementDidChange(const Element&, ShadowRoot&); … … 104 105 unsigned m_slotMutationVersion { 0 }; 105 106 unsigned m_slotResolutionVersion { 0 }; 107 unsigned m_slotElementCount { 0 }; 106 108 }; 107 109 … … 145 147 } 146 148 149 inline void ShadowRoot::willRemoveAssignedNode(const Node& node) 150 { 151 if (m_slotAssignment) 152 m_slotAssignment->willRemoveAssignedNode(node); 153 } 154 147 155 } // namespace WebCore
Note:
See TracChangeset
for help on using the changeset viewer.