Diff
Modified: trunk/LayoutTests/ChangeLog (275824 => 275825)
--- trunk/LayoutTests/ChangeLog 2021-04-12 16:36:34 UTC (rev 275824)
+++ trunk/LayoutTests/ChangeLog 2021-04-12 16:49:52 UTC (rev 275825)
@@ -1,3 +1,14 @@
+2021-04-12 Antti Koivisto <[email protected]>
+
+ Descendant style relations are sometimes reset when they shouldn't
+ https://bugs.webkit.org/show_bug.cgi?id=224431
+ rdar://76267783
+
+ Reviewed by Sam Weinig.
+
+ * fast/css/first-letter-style-relation-crash-expected.txt: Added.
+ * fast/css/first-letter-style-relation-crash.html: Added.
+
2021-04-12 Rob Buis <[email protected]>
Clamp overridingContentLogicalWidth/Height to zero
Added: trunk/LayoutTests/fast/css/first-letter-style-relation-crash-expected.txt (0 => 275825)
--- trunk/LayoutTests/fast/css/first-letter-style-relation-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/css/first-letter-style-relation-crash-expected.txt 2021-04-12 16:49:52 UTC (rev 275825)
@@ -0,0 +1 @@
+
Added: trunk/LayoutTests/fast/css/first-letter-style-relation-crash.html (0 => 275825)
--- trunk/LayoutTests/fast/css/first-letter-style-relation-crash.html (rev 0)
+++ trunk/LayoutTests/fast/css/first-letter-style-relation-crash.html 2021-04-12 16:49:52 UTC (rev 275825)
@@ -0,0 +1,33 @@
+<style>
+ html {
+ -webkit-user-modify: read-write-plaintext-only;
+ }
+ * {
+ float: right;
+ border-image: url();
+ max-inline-size: 0;
+ }
+ :first-child {
+ content: url();
+ }
+ :nth-child(3)::first-letter {
+ background: grey;
+ }
+ div {
+ overflow-x: scroll;
+ }
+ div::-webkit-scrollbar {
+ background: grey;
+ }
+</style>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+_onload_ = () => {
+ document.body.appendChild(document.createElement('div'));
+ document.body.appendChild(document.createElement('div'));
+ document.body.appendChild(document.createElement('div'));
+ document.execCommand('SelectAll');
+ document.execCommand('InsertText', false, "This test passes if it doesn't crash");
+};
+</script>
Modified: trunk/Source/WebCore/ChangeLog (275824 => 275825)
--- trunk/Source/WebCore/ChangeLog 2021-04-12 16:36:34 UTC (rev 275824)
+++ trunk/Source/WebCore/ChangeLog 2021-04-12 16:49:52 UTC (rev 275825)
@@ -1,3 +1,56 @@
+2021-04-12 Antti Koivisto <[email protected]>
+
+ Descendant style relations are sometimes reset when they shouldn't
+ https://bugs.webkit.org/show_bug.cgi?id=224431
+ rdar://76267783
+
+ Reviewed by Sam Weinig.
+
+ Some style relations computed during resolution of descendants are set on a parent element.
+ The parent element shouldn't reset them unless we are actually also computing the descendants.
+
+ Test: fast/css/first-letter-style-relation-crash.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::resetStyleRelations):
+ (WebCore::Element::resetChildStyleRelations):
+ (WebCore::Element::resetAllDescendantStyleRelations):
+
+ Split resetStyleRelations into separate parts.
+
+ * dom/Element.h:
+ (WebCore::Element::styleAffectedByEmpty const):
+ (WebCore::Element::childrenAffectedByForwardPositionalRules const):
+ (WebCore::Element::descendantsAffectedByForwardPositionalRules const):
+ (WebCore::Element::childrenAffectedByBackwardPositionalRules const):
+ (WebCore::Element::descendantsAffectedByBackwardPositionalRules const):
+ (WebCore::Element::childrenAffectedByPropertyBasedBackwardPositionalRules const):
+ (WebCore::Element::setStyleAffectedByEmpty):
+ (WebCore::Element::setChildrenAffectedByForwardPositionalRules):
+ (WebCore::Element::setDescendantsAffectedByForwardPositionalRules):
+ (WebCore::Element::setChildrenAffectedByBackwardPositionalRules):
+ (WebCore::Element::setDescendantsAffectedByBackwardPositionalRules):
+ (WebCore::Element::setChildrenAffectedByPropertyBasedBackwardPositionalRules):
+ * dom/ElementRareData.h:
+ (WebCore::ElementRareData::resetStyleRelations): Deleted.
+ * dom/Node.h:
+ (WebCore::Node::StyleBitfields::clearFlags):
+ (WebCore::Node::clearStyleFlags):
+ (WebCore::Node::StyleBitfields::dynamicStyleRelations const): Deleted.
+ (WebCore::Node::StyleBitfields::setDynamicStyleRelation): Deleted.
+ (WebCore::Node::StyleBitfields::clearDynamicStyleRelations): Deleted.
+ (WebCore::Node::hasDynamicStyleRelationFlag const): Deleted.
+ (WebCore::Node::setDynamicStyleRelationFlag): Deleted.
+
+ Remove the meaningless DynamicStyleRelation concept and merge these flags with the others.
+
+ * style/StyleTreeResolver.cpp:
+ (WebCore::Style::TreeResolver::resolveElement):
+ (WebCore::Style::TreeResolver::resolveComposedTree):
+
+ Only clear the descendant or child style relation bits if we are actually re-resolving
+ descendants or children.
+
2021-04-12 Rob Buis <[email protected]>
Clamp overridingContentLogicalWidth/Height to zero
Modified: trunk/Source/WebCore/dom/Element.cpp (275824 => 275825)
--- trunk/Source/WebCore/dom/Element.cpp 2021-04-12 16:36:34 UTC (rev 275824)
+++ trunk/Source/WebCore/dom/Element.cpp 2021-04-12 16:49:52 UTC (rev 275825)
@@ -4257,15 +4257,33 @@
void Element::resetStyleRelations()
{
- // FIXME: Make this code more consistent.
- auto bitfields = styleBitfields();
- bitfields.clearDynamicStyleRelations();
- setStyleBitfields(bitfields);
+ clearStyleFlags(NodeStyleFlag::StyleAffectedByEmpty);
if (!hasRareData())
return;
- elementRareData()->resetStyleRelations();
+ elementRareData()->setChildIndex(0);
}
+void Element::resetChildStyleRelations()
+{
+ clearStyleFlags({
+ NodeStyleFlag::ChildrenAffectedByFirstChildRules,
+ NodeStyleFlag::ChildrenAffectedByLastChildRules,
+ NodeStyleFlag::ChildrenAffectedByForwardPositionalRules,
+ NodeStyleFlag::ChildrenAffectedByBackwardPositionalRules,
+ NodeStyleFlag::ChildrenAffectedByPropertyBasedBackwardPositionalRules
+ });
+}
+
+void Element::resetAllDescendantStyleRelations()
+{
+ resetChildStyleRelations();
+
+ clearStyleFlags({
+ NodeStyleFlag::DescendantsAffectedByForwardPositionalRules,
+ NodeStyleFlag::DescendantsAffectedByBackwardPositionalRules
+ });
+}
+
void Element::clearHoverAndActiveStatusBeforeDetachingRenderer()
{
if (!isUserActionElement())
Modified: trunk/Source/WebCore/dom/Element.h (275824 => 275825)
--- trunk/Source/WebCore/dom/Element.h 2021-04-12 16:36:34 UTC (rev 275824)
+++ trunk/Source/WebCore/dom/Element.h 2021-04-12 16:49:52 UTC (rev 275825)
@@ -359,15 +359,15 @@
bool isVisibleWithoutResolvingFullStyle() const;
// Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
- bool styleAffectedByEmpty() const { return hasDynamicStyleRelationFlag(DynamicStyleRelationFlag::StyleAffectedByEmpty); }
+ bool styleAffectedByEmpty() const { return hasStyleFlag(NodeStyleFlag::StyleAffectedByEmpty); }
bool descendantsAffectedByPreviousSibling() const { return hasStyleFlag(NodeStyleFlag::DescendantsAffectedByPreviousSibling); }
bool childrenAffectedByFirstChildRules() const { return hasStyleFlag(NodeStyleFlag::ChildrenAffectedByFirstChildRules); }
bool childrenAffectedByLastChildRules() const { return hasStyleFlag(NodeStyleFlag::ChildrenAffectedByLastChildRules); }
- bool childrenAffectedByForwardPositionalRules() const { return hasDynamicStyleRelationFlag(DynamicStyleRelationFlag::ChildrenAffectedByForwardPositionalRules); }
- bool descendantsAffectedByForwardPositionalRules() const { return hasDynamicStyleRelationFlag(DynamicStyleRelationFlag::DescendantsAffectedByForwardPositionalRules); }
- bool childrenAffectedByBackwardPositionalRules() const { return hasDynamicStyleRelationFlag(DynamicStyleRelationFlag::ChildrenAffectedByBackwardPositionalRules); }
- bool descendantsAffectedByBackwardPositionalRules() const { return hasDynamicStyleRelationFlag(DynamicStyleRelationFlag::DescendantsAffectedByBackwardPositionalRules); }
- bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return hasDynamicStyleRelationFlag(DynamicStyleRelationFlag::ChildrenAffectedByPropertyBasedBackwardPositionalRules); }
+ bool childrenAffectedByForwardPositionalRules() const { return hasStyleFlag(NodeStyleFlag::ChildrenAffectedByForwardPositionalRules); }
+ bool descendantsAffectedByForwardPositionalRules() const { return hasStyleFlag(NodeStyleFlag::DescendantsAffectedByForwardPositionalRules); }
+ bool childrenAffectedByBackwardPositionalRules() const { return hasStyleFlag(NodeStyleFlag::ChildrenAffectedByBackwardPositionalRules); }
+ bool descendantsAffectedByBackwardPositionalRules() const { return hasStyleFlag(NodeStyleFlag::DescendantsAffectedByBackwardPositionalRules); }
+ bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return hasStyleFlag(NodeStyleFlag::ChildrenAffectedByPropertyBasedBackwardPositionalRules); }
bool affectsNextSiblingElementStyle() const { return hasStyleFlag(NodeStyleFlag::AffectsNextSiblingElementStyle); }
bool styleIsAffectedByPreviousSibling() const { return hasStyleFlag(NodeStyleFlag::StyleIsAffectedByPreviousSibling); }
unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; }
@@ -374,15 +374,15 @@
bool hasFlagsSetDuringStylingOfChildren() const;
- void setStyleAffectedByEmpty() { setDynamicStyleRelationFlag(DynamicStyleRelationFlag::StyleAffectedByEmpty); }
+ void setStyleAffectedByEmpty() { setStyleFlag(NodeStyleFlag::StyleAffectedByEmpty); }
void setDescendantsAffectedByPreviousSibling() { setStyleFlag(NodeStyleFlag::DescendantsAffectedByPreviousSibling); }
void setChildrenAffectedByFirstChildRules() { setStyleFlag(NodeStyleFlag::ChildrenAffectedByFirstChildRules); }
void setChildrenAffectedByLastChildRules() { setStyleFlag(NodeStyleFlag::ChildrenAffectedByLastChildRules); }
- void setChildrenAffectedByForwardPositionalRules() { setDynamicStyleRelationFlag(DynamicStyleRelationFlag::ChildrenAffectedByForwardPositionalRules); }
- void setDescendantsAffectedByForwardPositionalRules() { setDynamicStyleRelationFlag(DynamicStyleRelationFlag::DescendantsAffectedByForwardPositionalRules); }
- void setChildrenAffectedByBackwardPositionalRules() { setDynamicStyleRelationFlag(DynamicStyleRelationFlag::ChildrenAffectedByBackwardPositionalRules); }
- void setDescendantsAffectedByBackwardPositionalRules() { setDynamicStyleRelationFlag(DynamicStyleRelationFlag::DescendantsAffectedByBackwardPositionalRules); }
- void setChildrenAffectedByPropertyBasedBackwardPositionalRules() { setDynamicStyleRelationFlag(DynamicStyleRelationFlag::ChildrenAffectedByPropertyBasedBackwardPositionalRules); }
+ void setChildrenAffectedByForwardPositionalRules() { setStyleFlag(NodeStyleFlag::ChildrenAffectedByForwardPositionalRules); }
+ void setDescendantsAffectedByForwardPositionalRules() { setStyleFlag(NodeStyleFlag::DescendantsAffectedByForwardPositionalRules); }
+ void setChildrenAffectedByBackwardPositionalRules() { setStyleFlag(NodeStyleFlag::ChildrenAffectedByBackwardPositionalRules); }
+ void setDescendantsAffectedByBackwardPositionalRules() { setStyleFlag(NodeStyleFlag::DescendantsAffectedByBackwardPositionalRules); }
+ void setChildrenAffectedByPropertyBasedBackwardPositionalRules() { setStyleFlag(NodeStyleFlag::ChildrenAffectedByPropertyBasedBackwardPositionalRules); }
void setAffectsNextSiblingElementStyle() { setStyleFlag(NodeStyleFlag::AffectsNextSiblingElementStyle); }
void setStyleIsAffectedByPreviousSibling() { setStyleFlag(NodeStyleFlag::StyleIsAffectedByPreviousSibling); }
void setChildIndex(unsigned);
@@ -563,6 +563,8 @@
void clearAfterPseudoElement();
void resetComputedStyle();
void resetStyleRelations();
+ void resetChildStyleRelations();
+ void resetAllDescendantStyleRelations();
void clearHoverAndActiveStatusBeforeDetachingRenderer();
WEBCORE_EXPORT URL absoluteLinkURL() const;
Modified: trunk/Source/WebCore/dom/ElementRareData.h (275824 => 275825)
--- trunk/Source/WebCore/dom/ElementRareData.h 2021-04-12 16:36:34 UTC (rev 275824)
+++ trunk/Source/WebCore/dom/ElementRareData.h 2021-04-12 16:49:52 UTC (rev 275825)
@@ -55,7 +55,6 @@
PseudoElement* afterPseudoElement() const { return m_afterPseudoElement.get(); }
void resetComputedStyle();
- void resetStyleRelations();
int unusualTabIndex() const;
void setUnusualTabIndex(int);
@@ -220,11 +219,6 @@
m_computedStyle = nullptr;
}
-inline void ElementRareData::resetStyleRelations()
-{
- setChildIndex(0);
-}
-
inline int ElementRareData::unusualTabIndex() const
{
ASSERT(m_unusualTabIndex); // setUnusualTabIndex must have been called before this.
Modified: trunk/Source/WebCore/dom/Node.h (275824 => 275825)
--- trunk/Source/WebCore/dom/Node.h 2021-04-12 16:36:34 UTC (rev 275824)
+++ trunk/Source/WebCore/dom/Node.h 2021-04-12 16:49:52 UTC (rev 275825)
@@ -613,27 +613,24 @@
static constexpr uint32_t s_refCountIncrement = 2;
static constexpr uint32_t s_refCountMask = ~static_cast<uint32_t>(1);
- enum class NodeStyleFlag : uint8_t {
- DescendantNeedsStyleResolution = 1 << 0,
- DirectChildNeedsStyleResolution = 1 << 1,
- StyleResolutionShouldRecompositeLayer = 1 << 2,
+ enum class NodeStyleFlag : uint16_t {
+ DescendantNeedsStyleResolution = 1 << 0,
+ DirectChildNeedsStyleResolution = 1 << 1,
+ StyleResolutionShouldRecompositeLayer = 1 << 2,
- ChildrenAffectedByFirstChildRules = 1 << 3,
- ChildrenAffectedByLastChildRules = 1 << 4,
- AffectsNextSiblingElementStyle = 1 << 5,
- StyleIsAffectedByPreviousSibling = 1 << 6,
- DescendantsAffectedByPreviousSibling = 1 << 7,
- };
-
- enum class DynamicStyleRelationFlag : uint8_t {
- StyleAffectedByEmpty = 1 << 0,
+ ChildrenAffectedByFirstChildRules = 1 << 3,
+ ChildrenAffectedByLastChildRules = 1 << 4,
+ AffectsNextSiblingElementStyle = 1 << 5,
+ StyleIsAffectedByPreviousSibling = 1 << 6,
+ DescendantsAffectedByPreviousSibling = 1 << 7,
+ StyleAffectedByEmpty = 1 << 8,
// We optimize for :first-child and :last-child. The other positional child selectors like nth-child or
// *-child-of-type, we will just give up and re-evaluate whenever children change at all.
- ChildrenAffectedByForwardPositionalRules = 1 << 1,
- DescendantsAffectedByForwardPositionalRules = 1 << 2,
- ChildrenAffectedByBackwardPositionalRules = 1 << 3,
- DescendantsAffectedByBackwardPositionalRules = 1 << 4,
- ChildrenAffectedByPropertyBasedBackwardPositionalRules = 1 << 5,
+ ChildrenAffectedByForwardPositionalRules = 1 << 9,
+ DescendantsAffectedByForwardPositionalRules = 1 << 10,
+ ChildrenAffectedByBackwardPositionalRules = 1 << 11,
+ DescendantsAffectedByBackwardPositionalRules = 1 << 12,
+ ChildrenAffectedByPropertyBasedBackwardPositionalRules = 1 << 13,
};
struct StyleBitfields {
@@ -644,19 +641,15 @@
Style::Validity styleValidity() const { return static_cast<Style::Validity>(m_styleValidity); }
void setStyleValidity(Style::Validity validity) { m_styleValidity = static_cast<uint8_t>(validity); }
- OptionSet<DynamicStyleRelationFlag> dynamicStyleRelations() const { return OptionSet<DynamicStyleRelationFlag>::fromRaw(m_dynamicStyleRelation); }
- void setDynamicStyleRelation(DynamicStyleRelationFlag flag) { m_dynamicStyleRelation = (dynamicStyleRelations() | flag).toRaw(); }
- void clearDynamicStyleRelations() { m_dynamicStyleRelation = 0; }
-
OptionSet<NodeStyleFlag> flags() const { return OptionSet<NodeStyleFlag>::fromRaw(m_flags); }
void setFlag(NodeStyleFlag flag) { m_flags = (flags() | flag).toRaw(); }
void clearFlag(NodeStyleFlag flag) { m_flags = (flags() - flag).toRaw(); }
+ void clearFlags(OptionSet<NodeStyleFlag> flagsToClear) { m_flags = (flags() - flagsToClear).toRaw(); }
void clearDescendantsNeedStyleResolution() { m_flags = (flags() - NodeStyleFlag::DescendantNeedsStyleResolution - NodeStyleFlag::DirectChildNeedsStyleResolution).toRaw(); }
private:
- uint8_t m_styleValidity : 2;
- uint8_t m_dynamicStyleRelation : 6;
- uint8_t m_flags : 8;
+ uint16_t m_styleValidity : 2;
+ uint16_t m_flags : 14;
};
StyleBitfields styleBitfields() const { return StyleBitfields::fromRaw(m_rendererWithStyleFlags.type()); }
@@ -663,8 +656,7 @@
void setStyleBitfields(StyleBitfields bitfields) { m_rendererWithStyleFlags.setType(bitfields.toRaw()); }
ALWAYS_INLINE bool hasStyleFlag(NodeStyleFlag flag) const { return styleBitfields().flags().contains(flag); }
ALWAYS_INLINE void setStyleFlag(NodeStyleFlag);
- ALWAYS_INLINE bool hasDynamicStyleRelationFlag(DynamicStyleRelationFlag flag) const { return styleBitfields().dynamicStyleRelations().contains(flag); }
- ALWAYS_INLINE void setDynamicStyleRelationFlag(DynamicStyleRelationFlag);
+ ALWAYS_INLINE void clearStyleFlags(OptionSet<NodeStyleFlag>);
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const { }
@@ -857,10 +849,10 @@
setStyleBitfields(bitfields);
}
-ALWAYS_INLINE void Node::setDynamicStyleRelationFlag(DynamicStyleRelationFlag flag)
+ALWAYS_INLINE void Node::clearStyleFlags(OptionSet<NodeStyleFlag> flags)
{
auto bitfields = styleBitfields();
- bitfields.setDynamicStyleRelation(flag);
+ bitfields.clearFlags(flags);
setStyleBitfields(bitfields);
}
Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (275824 => 275825)
--- trunk/Source/WebCore/style/StyleTreeResolver.cpp 2021-04-12 16:36:34 UTC (rev 275824)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp 2021-04-12 16:49:52 UTC (rev 275825)
@@ -482,6 +482,21 @@
return style;
}
+static void resetDescendantStyleRelations(Element& element, DescendantsToResolve descendantsToResolve)
+{
+ switch (descendantsToResolve) {
+ case DescendantsToResolve::None:
+ case DescendantsToResolve::ChildrenWithExplicitInherit:
+ break;
+ case DescendantsToResolve::Children:
+ element.resetChildStyleRelations();
+ break;
+ case DescendantsToResolve::All:
+ element.resetAllDescendantStyleRelations();
+ break;
+ };
+}
+
void TreeResolver::resolveComposedTree()
{
ASSERT(m_parentStack.size() == 1);
@@ -564,6 +579,8 @@
it.traverseNextSkippingChildren();
continue;
}
+
+ resetDescendantStyleRelations(element, descendantsToResolve);
pushParent(element, *style, change, descendantsToResolve);