Skip to content

Commit

Permalink
[:has() pseudo-class] Disallow nested :has()
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=235231

Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

* web-platform-tests/css/selectors/has-argument-with-explicit-scope.tentative-expected.txt:
* web-platform-tests/css/selectors/has-basic-expected.txt:
* web-platform-tests/css/selectors/parsing/parse-has-expected.txt:

Source/WebCore:

Nested case ':has(:has(foo))' adds no meaningful capability and would complicate invalidation.
See w3c/csswg-drafts#6952 for more details.

* css/parser/CSSSelectorParser.cpp:
(WebCore::CSSSelectorParser::consumePseudo):

Also set m_resistDefaultNamespace like other logical combination pseudo-classes.

* css/parser/CSSSelectorParser.h:



Canonical link: https://commits.webkit.org/246125@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@288111 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
anttijk committed Jan 18, 2022
1 parent 248d342 commit ba991b1
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 12 deletions.
11 changes: 11 additions & 0 deletions LayoutTests/imported/w3c/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
2022-01-17 Antti Koivisto <antti@apple.com>

[:has() pseudo-class] Disallow nested :has()
https://bugs.webkit.org/show_bug.cgi?id=235231

Reviewed by Dean Jackson.

* web-platform-tests/css/selectors/has-argument-with-explicit-scope.tentative-expected.txt:
* web-platform-tests/css/selectors/has-basic-expected.txt:
* web-platform-tests/css/selectors/parsing/parse-has-expected.txt:

2022-01-17 Myles C. Maxfield <mmaxfield@apple.com>

REGRESSION(r281389): using font-variant-ligatures causes Unicode bidi isolation control characters to render
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ PASS .parent:has(.sibling ~ .target) matches expected elements
PASS :has(:is(.target ~ .sibling .descendant)) matches expected elements
PASS .parent:has(:is(.target ~ .sibling .descendant)) matches expected elements
PASS .sibling:has(.descendant) ~ .target matches expected elements
PASS :has(.sibling:has(.descendant) ~ .target) matches expected elements
PASS :has(.sibling:has(.descendant) ~ .target) ~ .parent > .descendant matches expected elements
FAIL :has(.sibling:has(.descendant) ~ .target) matches expected elements The string did not match the expected pattern.
FAIL :has(.sibling:has(.descendant) ~ .target) ~ .parent > .descendant matches expected elements The string did not match the expected pattern.
PASS :has(> .parent) matches expected elements
PASS :has(> .target) matches expected elements
PASS :has(> .parent, > .target) matches expected elements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ PASS .y:has(> .g .h) matches expected elements
PASS .y:has(.g .h) matches expected elements
PASS .y:has(> .g .h) .i matches expected elements
PASS .y:has(.g .h) .i matches expected elements
PASS .x:has(+ .y:has(> .g .h) .i) matches expected elements
PASS .x:has(+ .y:has(.g .h) .i) matches expected elements
PASS .x:has(+ .y:has(> .g .h) .i) ~ .j matches expected elements
PASS .x:has(+ .y:has(.g .h) .i) ~ .j matches expected elements
PASS .x:has(~ .y:has(> .g .h) .i) matches expected elements
PASS .x:has(~ .y:has(.g .h) .i) matches expected elements
FAIL .x:has(+ .y:has(> .g .h) .i) matches expected elements The string did not match the expected pattern.
FAIL .x:has(+ .y:has(.g .h) .i) matches expected elements The string did not match the expected pattern.
FAIL .x:has(+ .y:has(> .g .h) .i) ~ .j matches expected elements The string did not match the expected pattern.
FAIL .x:has(+ .y:has(.g .h) .i) ~ .j matches expected elements The string did not match the expected pattern.
FAIL .x:has(~ .y:has(> .g .h) .i) matches expected elements The string did not match the expected pattern.
FAIL .x:has(~ .y:has(.g .h) .i) matches expected elements The string did not match the expected pattern.
PASS .d .x:has(.e) matches expected elements
PASS .d ~ .x:has(~ .e) matches expected elements

Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ PASS ".a:has(.b) .c" should be a valid selector
PASS ".a .b:has(.c)" should be a valid selector
PASS ".a .b:has(.c .d)" should be a valid selector
PASS ".a .b:has(.c .d) .e" should be a valid selector
PASS ".a:has(.b:has(.c))" should be a valid selector
FAIL ".a:has(.b:has(.c))" should be a valid selector The string did not match the expected pattern.
PASS ".a:has(.b:is(.c .d))" should be a valid selector
PASS ".a:has(.b:is(.c:has(.d) .e))" should be a valid selector
FAIL ".a:has(.b:is(.c:has(.d) .e))" should be a valid selector assert_equals: serialization should be canonical expected ".a:has(.b:is(.c:has(.d) .e))" but got ".a:has(.b:is())"
PASS ".a:is(.b:has(.c) .d)" should be a valid selector
PASS ".a:not(:has(.b))" should be a valid selector
PASS ".a:has(:not(.b))" should be a valid selector
Expand Down
17 changes: 17 additions & 0 deletions Source/WebCore/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
2022-01-17 Antti Koivisto <antti@apple.com>

[:has() pseudo-class] Disallow nested :has()
https://bugs.webkit.org/show_bug.cgi?id=235231

Reviewed by Dean Jackson.

Nested case ':has(:has(foo))' adds no meaningful capability and would complicate invalidation.
See https://github.com/w3c/csswg-drafts/issues/6952 for more details.

* css/parser/CSSSelectorParser.cpp:
(WebCore::CSSSelectorParser::consumePseudo):

Also set m_resistDefaultNamespace like other logical combination pseudo-classes.

* css/parser/CSSSelectorParser.h:

2022-01-17 Youenn Fablet <youenn@apple.com>

BaseAudioSharedUnit::devicesChanged is failing capture too much in GPUProcess
Expand Down
8 changes: 6 additions & 2 deletions Source/WebCore/css/parser/CSSSelectorParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumePseudo(CSSParserTok
if (selector->match() == CSSSelector::PseudoClass) {
switch (selector->pseudoClassType()) {
case CSSSelector::PseudoClassNot: {
SetForScope<bool> resistDefaultNamespace(m_resistDefaultNamespace, true);
SetForScope resistDefaultNamespace(m_resistDefaultNamespace, true);
auto selectorList = makeUnique<CSSSelectorList>();
*selectorList = consumeComplexSelectorList(block);
if (!selectorList->first() || !block.atEnd())
Expand Down Expand Up @@ -734,7 +734,7 @@ std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumePseudo(CSSParserTok
case CSSSelector::PseudoClassWhere:
case CSSSelector::PseudoClassMatches:
case CSSSelector::PseudoClassAny: {
SetForScope<bool> resistDefaultNamespace(m_resistDefaultNamespace, true);
SetForScope resistDefaultNamespace(m_resistDefaultNamespace, true);
auto selectorList = makeUnique<CSSSelectorList>();
*selectorList = consumeForgivingComplexSelectorList(block);
if (!block.atEnd())
Expand All @@ -751,6 +751,10 @@ std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumePseudo(CSSParserTok
return selector;
}
case CSSSelector::PseudoClassHas: {
if (m_disallowHasPseudoClass)
return nullptr;
SetForScope resistDefaultNamespace(m_resistDefaultNamespace, true);
SetForScope disallowNestedHas(m_disallowHasPseudoClass, true);
auto selectorList = makeUnique<CSSSelectorList>();
*selectorList = consumeForgivingRelativeSelectorList(block);
if (selectorList->isEmpty() || !block.atEnd())
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/css/parser/CSSSelectorParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class CSSSelectorParser {
const RefPtr<StyleSheetContents> m_styleSheet;
bool m_failedParsing { false };
bool m_disallowPseudoElements { false };
bool m_disallowHasPseudoClass { false };
bool m_resistDefaultNamespace { false };
bool m_ignoreDefaultNamespace { false };
std::optional<CSSSelector::PseudoElementType> m_precedingPseudoElement;
Expand Down

0 comments on commit ba991b1

Please sign in to comment.