From cd8f5f2366d66e8415f234ec4af5d69bc51e907a Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Thu, 21 Nov 2024 21:31:39 +1100 Subject: [PATCH] LibWeb: Reject selectors with named namespaces in querySelectorAll --- Libraries/LibWeb/DOM/ParentNode.cpp | 24 ++++++++++ .../nodes/ParentNode-querySelector-All.txt | 44 +++++++++---------- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/Libraries/LibWeb/DOM/ParentNode.cpp b/Libraries/LibWeb/DOM/ParentNode.cpp index 1932c78c9b8..240e12175e1 100644 --- a/Libraries/LibWeb/DOM/ParentNode.cpp +++ b/Libraries/LibWeb/DOM/ParentNode.cpp @@ -23,6 +23,26 @@ namespace Web::DOM { GC_DEFINE_ALLOCATOR(ParentNode); +static bool contains_named_namespace(const CSS::SelectorList& selectors) +{ + for (auto const& selector : selectors) { + for (auto const& compound_selector : selector->compound_selectors()) { + for (auto simple_selector : compound_selector.simple_selectors) { + if (simple_selector.value.has()) { + if (simple_selector.qualified_name().namespace_type == CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Named) + return true; + } + + if (simple_selector.value.has()) { + if (contains_named_namespace(simple_selector.pseudo_class().argument_selector_list)) + return true; + } + } + } + } + return false; +} + enum class ReturnMatches { First, All, @@ -40,6 +60,10 @@ static WebIDL::ExceptionOr, GC::Ref>> scope_m auto selectors = maybe_selectors.value(); + // "Note: Support for namespaces within selectors is not planned and will not be added." + if (contains_named_namespace(selectors)) + return WebIDL::SyntaxError::create(node.realm(), "Failed to parse selector"_string); + // 3. Return the result of match a selector against a tree with s and node’s root using scoping root node. GC::Ptr single_result; Vector> results; diff --git a/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/ParentNode-querySelector-All.txt b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/ParentNode-querySelector-All.txt index 29487d7992a..34ace2711f5 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/ParentNode-querySelector-All.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/ParentNode-querySelector-All.txt @@ -6,8 +6,8 @@ Rerun Found 1975 tests -1931 Pass -44 Fail +1951 Pass +24 Fail Details Result Test Name MessagePass Selectors-API Test Suite: HTML Pass Document supports querySelector @@ -116,10 +116,10 @@ Pass Document.querySelector: Invalid pseudo-element: :::before Pass Document.querySelectorAll: Invalid pseudo-element: :::before Pass Document.querySelector: Invalid pseudo-element: :: before Pass Document.querySelectorAll: Invalid pseudo-element: :: before -Fail Document.querySelector: Undeclared namespace: ns|div -Fail Document.querySelectorAll: Undeclared namespace: ns|div -Fail Document.querySelector: Undeclared namespace: :not(ns|div) -Fail Document.querySelectorAll: Undeclared namespace: :not(ns|div) +Pass Document.querySelector: Undeclared namespace: ns|div +Pass Document.querySelectorAll: Undeclared namespace: ns|div +Pass Document.querySelector: Undeclared namespace: :not(ns|div) +Pass Document.querySelectorAll: Undeclared namespace: :not(ns|div) Pass Document.querySelector: Invalid namespace: ^|div Pass Document.querySelectorAll: Invalid namespace: ^|div Pass Document.querySelector: Invalid namespace: $|div @@ -184,10 +184,10 @@ Pass Detached Element.querySelector: Invalid pseudo-element: :::before Pass Detached Element.querySelectorAll: Invalid pseudo-element: :::before Pass Detached Element.querySelector: Invalid pseudo-element: :: before Pass Detached Element.querySelectorAll: Invalid pseudo-element: :: before -Fail Detached Element.querySelector: Undeclared namespace: ns|div -Fail Detached Element.querySelectorAll: Undeclared namespace: ns|div -Fail Detached Element.querySelector: Undeclared namespace: :not(ns|div) -Fail Detached Element.querySelectorAll: Undeclared namespace: :not(ns|div) +Pass Detached Element.querySelector: Undeclared namespace: ns|div +Pass Detached Element.querySelectorAll: Undeclared namespace: ns|div +Pass Detached Element.querySelector: Undeclared namespace: :not(ns|div) +Pass Detached Element.querySelectorAll: Undeclared namespace: :not(ns|div) Pass Detached Element.querySelector: Invalid namespace: ^|div Pass Detached Element.querySelectorAll: Invalid namespace: ^|div Pass Detached Element.querySelector: Invalid namespace: $|div @@ -252,10 +252,10 @@ Pass Fragment.querySelector: Invalid pseudo-element: :::before Pass Fragment.querySelectorAll: Invalid pseudo-element: :::before Pass Fragment.querySelector: Invalid pseudo-element: :: before Pass Fragment.querySelectorAll: Invalid pseudo-element: :: before -Fail Fragment.querySelector: Undeclared namespace: ns|div -Fail Fragment.querySelectorAll: Undeclared namespace: ns|div -Fail Fragment.querySelector: Undeclared namespace: :not(ns|div) -Fail Fragment.querySelectorAll: Undeclared namespace: :not(ns|div) +Pass Fragment.querySelector: Undeclared namespace: ns|div +Pass Fragment.querySelectorAll: Undeclared namespace: ns|div +Pass Fragment.querySelector: Undeclared namespace: :not(ns|div) +Pass Fragment.querySelectorAll: Undeclared namespace: :not(ns|div) Pass Fragment.querySelector: Invalid namespace: ^|div Pass Fragment.querySelectorAll: Invalid namespace: ^|div Pass Fragment.querySelector: Invalid namespace: $|div @@ -320,10 +320,10 @@ Pass In-document Element.querySelector: Invalid pseudo-element: :::before Pass In-document Element.querySelectorAll: Invalid pseudo-element: :::before Pass In-document Element.querySelector: Invalid pseudo-element: :: before Pass In-document Element.querySelectorAll: Invalid pseudo-element: :: before -Fail In-document Element.querySelector: Undeclared namespace: ns|div -Fail In-document Element.querySelectorAll: Undeclared namespace: ns|div -Fail In-document Element.querySelector: Undeclared namespace: :not(ns|div) -Fail In-document Element.querySelectorAll: Undeclared namespace: :not(ns|div) +Pass In-document Element.querySelector: Undeclared namespace: ns|div +Pass In-document Element.querySelectorAll: Undeclared namespace: ns|div +Pass In-document Element.querySelector: Undeclared namespace: :not(ns|div) +Pass In-document Element.querySelectorAll: Undeclared namespace: :not(ns|div) Pass In-document Element.querySelector: Invalid namespace: ^|div Pass In-document Element.querySelectorAll: Invalid namespace: ^|div Pass In-document Element.querySelector: Invalid namespace: $|div @@ -388,10 +388,10 @@ Pass Empty Element.querySelector: Invalid pseudo-element: :::before Pass Empty Element.querySelectorAll: Invalid pseudo-element: :::before Pass Empty Element.querySelector: Invalid pseudo-element: :: before Pass Empty Element.querySelectorAll: Invalid pseudo-element: :: before -Fail Empty Element.querySelector: Undeclared namespace: ns|div -Fail Empty Element.querySelectorAll: Undeclared namespace: ns|div -Fail Empty Element.querySelector: Undeclared namespace: :not(ns|div) -Fail Empty Element.querySelectorAll: Undeclared namespace: :not(ns|div) +Pass Empty Element.querySelector: Undeclared namespace: ns|div +Pass Empty Element.querySelectorAll: Undeclared namespace: ns|div +Pass Empty Element.querySelector: Undeclared namespace: :not(ns|div) +Pass Empty Element.querySelectorAll: Undeclared namespace: :not(ns|div) Pass Empty Element.querySelector: Invalid namespace: ^|div Pass Empty Element.querySelectorAll: Invalid namespace: ^|div Pass Empty Element.querySelector: Invalid namespace: $|div