mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibWeb/CSS: Reject invalid :has() contents after absolutizing nesting
After we absolutize the contents of :has(), we check that those child selectors don't contain anything that :has() rejects. This is a separate path than the checks inside the parser, which is unfortunate. Fixes a WPT ref test. :^)
This commit is contained in:
parent
da31c10ce1
commit
3a71b8cda3
Notes:
github-actions[bot]
2024-11-14 19:08:17 +00:00
Author: https://github.com/AtkinsSJ
Commit: 3a71b8cda3
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2340
2 changed files with 38 additions and 1 deletions
|
@ -624,6 +624,33 @@ Optional<Selector::CompoundSelector> Selector::CompoundSelector::absolutized(Sel
|
|||
};
|
||||
}
|
||||
|
||||
static bool contains_invalid_contents_for_has(Selector const& selector)
|
||||
{
|
||||
// :has() has special validity rules:
|
||||
// - It can't appear inside itself
|
||||
// - It bans most pseudo-elements
|
||||
// https://drafts.csswg.org/selectors/#relational
|
||||
|
||||
for (auto const& compound_selector : selector.compound_selectors()) {
|
||||
for (auto const& simple_selector : compound_selector.simple_selectors) {
|
||||
if (simple_selector.type == Selector::SimpleSelector::Type::PseudoElement) {
|
||||
if (!is_has_allowed_pseudo_element(simple_selector.pseudo_element().type()))
|
||||
return true;
|
||||
}
|
||||
if (simple_selector.type == Selector::SimpleSelector::Type::PseudoClass) {
|
||||
if (simple_selector.pseudo_class().type == PseudoClass::Has)
|
||||
return true;
|
||||
for (auto& child_selector : simple_selector.pseudo_class().argument_selector_list) {
|
||||
if (contains_invalid_contents_for_has(*child_selector))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<Selector::SimpleSelector> Selector::SimpleSelector::absolutized(Selector::SimpleSelector const& selector_for_nesting) const
|
||||
{
|
||||
switch (type) {
|
||||
|
@ -647,6 +674,17 @@ Optional<Selector::SimpleSelector> Selector::SimpleSelector::absolutized(Selecto
|
|||
}
|
||||
pseudo_class.argument_selector_list = move(new_selector_list);
|
||||
}
|
||||
|
||||
// :has() has special validity rules
|
||||
if (pseudo_class.type == PseudoClass::Has) {
|
||||
for (auto const& selector : pseudo_class.argument_selector_list) {
|
||||
if (contains_invalid_contents_for_has(selector)) {
|
||||
dbgln_if(CSS_PARSER_DEBUG, "After absolutizing, :has() would contain invalid contents; rejecting");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SimpleSelector {
|
||||
.type = Type::PseudoClass,
|
||||
.value = move(pseudo_class),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue