Selaa lähdekoodia

LibWeb: Handle special cases of PseudoElement::Type correctly

There are some special values for CSS::Selector::PseudoElement::Type
which are after `KnownPseudoElementCount` and therefore not present in
various arrays of pseudo elements, this leads to some errors, if a type
after `KnownPseudoElementCount` is used without checking first. This
adds explicit checks to all usages
Totto16 6 kuukautta sitten
vanhempi
commit
d21bfda900

+ 19 - 3
Libraries/LibWeb/Animations/Animatable.cpp

@@ -187,14 +187,21 @@ void Animatable::visit_edges(JS::Cell::Visitor& visitor)
 
 GC::Ptr<CSS::CSSStyleDeclaration const> Animatable::cached_animation_name_source(Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
 {
-    if (pseudo_element.has_value())
+    if (pseudo_element.has_value()) {
+        if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
+            return {};
+        }
         return m_cached_animation_name_source[to_underlying(pseudo_element.value()) + 1];
+    }
     return m_cached_animation_name_source[0];
 }
 
 void Animatable::set_cached_animation_name_source(GC::Ptr<CSS::CSSStyleDeclaration const> value, Optional<CSS::Selector::PseudoElement::Type> pseudo_element)
 {
     if (pseudo_element.has_value()) {
+        if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
+            return;
+        }
         m_cached_animation_name_source[to_underlying(pseudo_element.value()) + 1] = value;
     } else {
         m_cached_animation_name_source[0] = value;
@@ -203,18 +210,27 @@ void Animatable::set_cached_animation_name_source(GC::Ptr<CSS::CSSStyleDeclarati
 
 GC::Ptr<Animations::Animation> Animatable::cached_animation_name_animation(Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
 {
-    if (pseudo_element.has_value())
+    if (pseudo_element.has_value()) {
+        if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
+            return {};
+        }
+
         return m_cached_animation_name_animation[to_underlying(pseudo_element.value()) + 1];
+    }
     return m_cached_animation_name_animation[0];
 }
 
 void Animatable::set_cached_animation_name_animation(GC::Ptr<Animations::Animation> value, Optional<CSS::Selector::PseudoElement::Type> pseudo_element)
 {
+
     if (pseudo_element.has_value()) {
+        if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
+            return;
+        }
+
         m_cached_animation_name_animation[to_underlying(pseudo_element.value()) + 1] = value;
     } else {
         m_cached_animation_name_animation[0] = value;
     }
 }
-
 }

+ 6 - 1
Libraries/LibWeb/CSS/Selector.h

@@ -55,7 +55,7 @@ public:
         explicit PseudoElement(Type type)
             : m_type(type)
         {
-            VERIFY(type != Type::UnknownWebKit);
+            VERIFY(is_known_pseudo_element_type(type));
         }
 
         PseudoElement(Type type, String name)
@@ -68,6 +68,11 @@ public:
 
         static Optional<PseudoElement> from_string(FlyString const&);
 
+        [[nodiscard]] static bool is_known_pseudo_element_type(Type type)
+        {
+            return to_underlying(type) < to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount);
+        }
+
         static StringView name(Selector::PseudoElement::Type pseudo_element);
 
         StringView name() const

+ 9 - 3
Libraries/LibWeb/CSS/StyleComputer.cpp

@@ -466,8 +466,14 @@ Vector<MatchingRule> StyleComputer::collect_matching_rules(DOM::Element const& e
     }
     if (auto it = rule_cache.rules_by_tag_name.find(element.local_name()); it != rule_cache.rules_by_tag_name.end())
         add_rules_to_run(it->value);
-    if (pseudo_element.has_value())
-        add_rules_to_run(rule_cache.rules_by_pseudo_element[to_underlying(pseudo_element.value())]);
+    if (pseudo_element.has_value()) {
+        if (CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
+            add_rules_to_run(rule_cache.rules_by_pseudo_element.at(to_underlying(pseudo_element.value())));
+        } else {
+            // NOTE: We don't cache rules for unknown pseudo-elements. They can't match anything anyway.
+        }
+    }
+
     if (element.is_document_element())
         add_rules_to_run(rule_cache.root_rules);
 
@@ -2632,7 +2638,7 @@ NonnullOwnPtr<StyleComputer::RuleCache> StyleComputer::make_rule_cache_for_casca
                 }
                 if (!added_to_bucket) {
                     if (matching_rule.contains_pseudo_element) {
-                        if (to_underlying(pseudo_element.value()) < to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)) {
+                        if (CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
                             rule_cache->rules_by_pseudo_element[to_underlying(pseudo_element.value())].append(move(matching_rule));
                         } else {
                             // NOTE: We don't cache rules for unknown pseudo-elements. They can't match anything anyway.

+ 25 - 0
Libraries/LibWeb/DOM/Element.cpp

@@ -1069,6 +1069,10 @@ void Element::set_pseudo_element_node(Badge<Layout::TreeBuilder>, CSS::Selector:
     if (!existing_pseudo_element.has_value() && !pseudo_element_node)
         return;
 
+    if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element)) {
+        return;
+    }
+
     ensure_pseudo_element(pseudo_element).layout_node = move(pseudo_element_node);
 }
 
@@ -2279,6 +2283,11 @@ void Element::set_pseudo_element_computed_css_values(CSS::Selector::PseudoElemen
 {
     if (!m_pseudo_element_data && !style.has_value())
         return;
+
+    if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element)) {
+        return;
+    }
+
     ensure_pseudo_element(pseudo_element).computed_css_values = move(style);
 }
 
@@ -2294,6 +2303,11 @@ Optional<Element::PseudoElement&> Element::get_pseudo_element(CSS::Selector::Pse
 {
     if (!m_pseudo_element_data)
         return {};
+
+    if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(type)) {
+        return {};
+    }
+
     return m_pseudo_element_data->at(to_underlying(type));
 }
 
@@ -2301,6 +2315,9 @@ Element::PseudoElement& Element::ensure_pseudo_element(CSS::Selector::PseudoElem
 {
     if (!m_pseudo_element_data)
         m_pseudo_element_data = make<PseudoElementData>();
+
+    VERIFY(CSS::Selector::PseudoElement::is_known_pseudo_element_type(type));
+
     return m_pseudo_element_data->at(to_underlying(type));
 }
 
@@ -2310,6 +2327,11 @@ void Element::set_custom_properties(Optional<CSS::Selector::PseudoElement::Type>
         m_custom_properties = move(custom_properties);
         return;
     }
+
+    if (!CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value())) {
+        return;
+    }
+
     ensure_pseudo_element(pseudo_element.value()).custom_properties = move(custom_properties);
 }
 
@@ -2317,6 +2339,9 @@ HashMap<FlyString, CSS::StyleProperty> const& Element::custom_properties(Optiona
 {
     if (!pseudo_element.has_value())
         return m_custom_properties;
+
+    VERIFY(CSS::Selector::PseudoElement::is_known_pseudo_element_type(pseudo_element.value()));
+
     return ensure_pseudo_element(pseudo_element.value()).custom_properties;
 }