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
This commit is contained in:
Totto16 2024-12-19 19:15:02 +01:00 committed by Sam Atkins
commit d21bfda900
Notes: github-actions[bot] 2024-12-19 19:37:02 +00:00
4 changed files with 59 additions and 7 deletions

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -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.

View file

@ -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;
}