WebCore:
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Jul 2008 04:15:35 +0000 (04:15 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Jul 2008 04:15:35 +0000 (04:15 +0000)
2008-07-07  Sam Weinig  <sam@webkit.org>

        Reviewed by Anders Carlsson.

        Fix for https://bugs.webkit.org/show_bug.cgi?id=19928
        Use of CSS3 Namespaces syntax in Selectors API should throw an exception

        - Throw an NAMESPACE_ERR exception if a non-null or "*" namespace is
          used in a selector passed to querySelector or querySelectorAll.

        Test: fast/dom/SelectorAPI/not-supported-namespace-in-selector.html

        * dom/Node.cpp:
        (WebCore::selectorNeedsNamespaceResolution):
        (WebCore::Node::querySelector):
        (WebCore::Node::querySelectorAll):

LayoutTests:

2008-07-07  Sam Weinig  <sam@webkit.org>

        Reviewed by Anders Carlsson.

        Fix for https://bugs.webkit.org/show_bug.cgi?id=19928
        Use of CSS3 Namespaces syntax in Selectors API should throw an exception

        * fast/dom/SelectorAPI/not-supported-namespace-in-selector-expected.txt: Added.
        * fast/dom/SelectorAPI/not-supported-namespace-in-selector.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@35056 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/dom/SelectorAPI/not-supported-namespace-in-selector-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/SelectorAPI/not-supported-namespace-in-selector.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/dom/Node.cpp

index 823fb7d..dd7a841 100644 (file)
@@ -1,3 +1,13 @@
+2008-07-07  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Anders Carlsson.
+
+        Fix for https://bugs.webkit.org/show_bug.cgi?id=19928
+        Use of CSS3 Namespaces syntax in Selectors API should throw an exception
+
+        * fast/dom/SelectorAPI/not-supported-namespace-in-selector-expected.txt: Added.
+        * fast/dom/SelectorAPI/not-supported-namespace-in-selector.html: Added.
+
 2008-07-07  Simon Fraser  <simon.fraser@apple.com>
 
         Reviewed by Darin.
diff --git a/LayoutTests/fast/dom/SelectorAPI/not-supported-namespace-in-selector-expected.txt b/LayoutTests/fast/dom/SelectorAPI/not-supported-namespace-in-selector-expected.txt
new file mode 100644 (file)
index 0000000..9269ef0
--- /dev/null
@@ -0,0 +1,27 @@
+This tests that we throw a NAMESPACE_ERR when parsing a selector string for querySelector and querySelectorAll that contains a namespace.
+
+PASS: document.querySelector('bbb|pre') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelectorAll('bbb|pre') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelector('*|pre') did not throw
+PASS: document.querySelectorAll('*|pre') did not throw
+PASS: document.querySelector('|pre') did not throw
+PASS: document.querySelectorAll('|pre') did not throw
+PASS: document.querySelector('div bbb|pre') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelectorAll('div bbb|pre') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelector('div *|pre') did not throw
+PASS: document.querySelectorAll('div *|pre') did not throw
+PASS: document.querySelector('div |pre') did not throw
+PASS: document.querySelectorAll('div |pre') did not throw
+PASS: document.querySelector('[bbb|name=value]') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelectorAll('[bbb|name=value]') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelector('[*|name=value]') did not throw
+PASS: document.querySelectorAll('[*|name=value]') did not throw
+PASS: document.querySelector('[|name=value]') did not throw
+PASS: document.querySelectorAll('[|name=value]') did not throw
+PASS: document.querySelector('div [bbb|name=value]') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelectorAll('div [bbb|name=value]') throws: Error: NAMESPACE_ERR: DOM Exception 14
+PASS: document.querySelector('div [*|name=value]') did not throw
+PASS: document.querySelectorAll('div [*|name=value]') did not throw
+PASS: document.querySelector('div [|name=value]') did not throw
+PASS: document.querySelectorAll('div [|name=value]') did not throw
+
diff --git a/LayoutTests/fast/dom/SelectorAPI/not-supported-namespace-in-selector.html b/LayoutTests/fast/dom/SelectorAPI/not-supported-namespace-in-selector.html
new file mode 100644 (file)
index 0000000..916f6aa
--- /dev/null
@@ -0,0 +1,69 @@
+<html>
+<head>
+<script>
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+    log = function(msg)
+    {
+        document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+    }
+
+    shouldThrow = function(_a)
+    {
+        try {
+            eval(_a);
+            log("FAIL: " + _a + " did not throw");
+        } catch(ex) {
+            log("PASS: " + _a + " throws: " + ex);
+        }
+    }
+
+    shouldNotThrow = function(_a)
+    {
+        try {
+            eval(_a);
+            log("PASS: " + _a + " did not throw");
+        } catch(ex) {
+            log("FAIL: " + _a + " throws: " + ex);
+        }
+    }
+
+    onload = function()
+    {
+        shouldThrow("document.querySelector('bbb|pre')");
+        shouldThrow("document.querySelectorAll('bbb|pre')");
+        shouldNotThrow("document.querySelector('*|pre')");
+        shouldNotThrow("document.querySelectorAll('*|pre')");
+        shouldNotThrow("document.querySelector('|pre')");
+        shouldNotThrow("document.querySelectorAll('|pre')");
+
+        shouldThrow("document.querySelector('div bbb|pre')");
+        shouldThrow("document.querySelectorAll('div bbb|pre')");
+        shouldNotThrow("document.querySelector('div *|pre')");
+        shouldNotThrow("document.querySelectorAll('div *|pre')");
+        shouldNotThrow("document.querySelector('div |pre')");
+        shouldNotThrow("document.querySelectorAll('div |pre')");
+
+        shouldThrow("document.querySelector('[bbb|name=value]')");
+        shouldThrow("document.querySelectorAll('[bbb|name=value]')");
+        shouldNotThrow("document.querySelector('[*|name=value]')");
+        shouldNotThrow("document.querySelectorAll('[*|name=value]')");
+        shouldNotThrow("document.querySelector('[|name=value]')");
+        shouldNotThrow("document.querySelectorAll('[|name=value]')");
+
+        shouldThrow("document.querySelector('div [bbb|name=value]')");
+        shouldThrow("document.querySelectorAll('div [bbb|name=value]')");
+        shouldNotThrow("document.querySelector('div [*|name=value]')");
+        shouldNotThrow("document.querySelectorAll('div [*|name=value]')");
+        shouldNotThrow("document.querySelector('div [|name=value]')");
+        shouldNotThrow("document.querySelectorAll('div [|name=value]')");
+    }
+</script>
+</head>
+<body>
+    <p>This tests that we throw a NAMESPACE_ERR when parsing a selector string for querySelector and querySelectorAll
+        that contains a namespace.</p>
+    <pre id="console" name="value"></pre>
+</body>
+</html>
index 6c24fea..491bcb6 100644 (file)
@@ -1,3 +1,20 @@
+2008-07-07  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Anders Carlsson.
+
+        Fix for https://bugs.webkit.org/show_bug.cgi?id=19928
+        Use of CSS3 Namespaces syntax in Selectors API should throw an exception
+
+        - Throw an NAMESPACE_ERR exception if a non-null or "*" namespace is
+          used in a selector passed to querySelector or querySelectorAll.
+
+        Test: fast/dom/SelectorAPI/not-supported-namespace-in-selector.html
+
+        * dom/Node.cpp:
+        (WebCore::selectorNeedsNamespaceResolution):
+        (WebCore::Node::querySelector):
+        (WebCore::Node::querySelectorAll):
+
 2008-07-07  Simon Fraser  <simon.fraser@apple.com>
 
         Reviewed by Darin.
index c291b60..bea256c 100644 (file)
@@ -1226,6 +1226,17 @@ PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
     return ClassNodeList::create(this, classNames, result.first->second);
 }
 
+static bool selectorNeedsNamespaceResolution(CSSSelector* selector)
+{
+    for (; selector; selector = selector->next()) {
+        if (selector->hasTag() && selector->m_tag.prefix() != nullAtom && selector->m_tag.prefix() != starAtom)
+            return true;
+        if (selector->hasAttribute() && selector->m_attr.prefix() != nullAtom && selector->m_attr.prefix() != starAtom)
+            return true;
+    }
+    return false;
+}
+
 PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec)
 {
     if (selectors.isNull() || selectors.isEmpty()) {
@@ -1240,16 +1251,24 @@ PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode&
         return 0;
     }
 
-    CSSStyleSelector::SelectorChecker selectorChecker(document(), !document()->inCompatMode());
     CSSSelector* querySelector = static_cast<CSSStyleRule*>(rule.get())->selector();
-    
+
+    // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes, which we support in the engine
+    // but do not currently in the API due to lack of NSResolver support.
+    if (selectorNeedsNamespaceResolution(querySelector)) {
+        ec = NAMESPACE_ERR;
+        return 0;
+    }
+
     if (!querySelector->next() && querySelector->m_match == CSSSelector::Id) {
         Element* element = document()->getElementById(querySelector->m_value);
         if (element && (isDocumentNode() || element->isDescendantOf(this)))
             return element;
         return 0;
     }
-    
+
+    CSSStyleSelector::SelectorChecker selectorChecker(document(), !document()->inCompatMode());
+
     // FIXME: We can speed this up by implementing caching similar to the one use by getElementById
     for (Node* n = firstChild(); n; n = n->traverseNextNode(this)) {
         if (n->isElementNode()) {
@@ -1277,8 +1296,17 @@ PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, ExceptionCo
         ec = SYNTAX_ERR;
         return 0;
     }
-    
-    return createSelectorNodeList(this, static_cast<CSSStyleRule*>(rule.get())->selector());
+
+    CSSSelector* querySelector = static_cast<CSSStyleRule*>(rule.get())->selector();
+
+    // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes, which we support in the engine
+    // but do not currently in the API due to lack of NSResolver support.
+    if (selectorNeedsNamespaceResolution(querySelector)) {
+        ec = NAMESPACE_ERR;
+        return 0;
+    }
+
+    return createSelectorNodeList(this, querySelector);
 }
 
 Document *Node::ownerDocument() const