LayoutTests:
authorweinig <weinig@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Feb 2007 22:09:10 +0000 (22:09 +0000)
committerweinig <weinig@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Feb 2007 22:09:10 +0000 (22:09 +0000)
        Reviewed by Maciej.

        http://bugs.webkit.org/show_bug.cgi?id=12733
        XPath namespace is attached to a wrong step

        * fast/xpath/namespace-vs-predicate-expected.txt: Added.
        * fast/xpath/namespace-vs-predicate.xhtml: Added.

WebCore:

        Reviewed by Maciej.

        http://bugs.webkit.org/show_bug.cgi?id=12733
        XPath namespace is attached to a wrong step

        * xml/XPathGrammar.y: NAMETEST is different from other NodeTests in that its
        resulting type is an expanded name, rather than a string. It is not really possible
        to store the namespace inside Parser, because it gets used in wrong steps then.

        * xml/XPathParser.cpp:
        (WebCore::XPath::Parser::expandQName):
        * xml/XPathParser.h:
        Moved code that expands a QName from XPathGrammar.y. Removed m_currentNamespaceURI.

        * xml/XPathStep.cpp:
        (WebCore::XPath::Step::Step):
        * xml/XPathStep.h:
        Added a constructor that takes a namespace.

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

LayoutTests/ChangeLog
LayoutTests/fast/xpath/namespace-vs-predicate-expected.txt [new file with mode: 0644]
LayoutTests/fast/xpath/namespace-vs-predicate.xhtml [new file with mode: 0644]
WebCore/ChangeLog
WebCore/xml/XPathGrammar.y
WebCore/xml/XPathParser.cpp
WebCore/xml/XPathParser.h
WebCore/xml/XPathStep.cpp
WebCore/xml/XPathStep.h

index 7a300aa..993192f 100644 (file)
@@ -1,3 +1,13 @@
+2007-02-17  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Maciej.
+
+        http://bugs.webkit.org/show_bug.cgi?id=12733
+        XPath namespace is attached to a wrong step
+
+        * fast/xpath/namespace-vs-predicate-expected.txt: Added.
+        * fast/xpath/namespace-vs-predicate.xhtml: Added.
+
 2007-02-17  Mitz Pettel  <mitz@webkit.org>
 
         Reviewed by Maciej.
diff --git a/LayoutTests/fast/xpath/namespace-vs-predicate-expected.txt b/LayoutTests/fast/xpath/namespace-vs-predicate-expected.txt
new file mode 100644 (file)
index 0000000..f0853f8
--- /dev/null
@@ -0,0 +1,4 @@
+Test for bug 12733: XPath namespace is attached to a wrong step.
+
+SUCCESS
+
diff --git a/LayoutTests/fast/xpath/namespace-vs-predicate.xhtml b/LayoutTests/fast/xpath/namespace-vs-predicate.xhtml
new file mode 100644 (file)
index 0000000..b6babc0
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
+    xmlns:svg="http://www.w3.org/2000/svg"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    xmlns:ev="http://www.w3.org/2001/xml-events"
+    xml:space="preserve">
+<head>
+    <title/>
+</head>
+<body>
+    <p>Test for <a href="http://bugs.webkit.org/show_bug.cgi?id=12733">bug 12733</a>:
+    XPath namespace is attached to a wrong step.</p>
+    <div id="result">FAILURE: script did't run</div>
+    <svg:g id="r_00"/>
+    <script>
+        if (window.layoutTestController)
+            layoutTestController.dumpAsText();
+
+        function nsResolver(prefix) {
+            var ns={
+                'ev'     : 'http://www.w3.org/2001/xml-events',
+                'mathml' : 'http://www.w3.org/1998/Math/MathML',
+                'svg'    : 'http://www.w3.org/2000/svg',
+                'xhtml'  : 'http://www.w3.org/1999/xhtml',
+                'xlink'  : 'http://www.w3.org/1999/xlink'
+            };
+            return ns[prefix] || null;
+        }
+
+        var result = document.evaluate("//svg:g[@id = 'r_00']", document.documentElement, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+        if (result.snapshotLength == 1)
+            document.getElementById("result").firstChild.nodeValue = "SUCCESS";
+        else
+            document.getElementById("result").firstChild.nodeValue = "FAILURE: " + result.snapshotLength + " node(s) matched - should be 1";
+    </script>
+
+</body>
+</html>
index 3d29e6e..8b08017 100644 (file)
@@ -1,3 +1,24 @@
+2007-02-17  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Maciej.
+
+        http://bugs.webkit.org/show_bug.cgi?id=12733
+        XPath namespace is attached to a wrong step
+
+        * xml/XPathGrammar.y: NAMETEST is different from other NodeTests in that its
+        resulting type is an expanded name, rather than a string. It is not really possible 
+        to store the namespace inside Parser, because it gets used in wrong steps then.
+
+        * xml/XPathParser.cpp:
+        (WebCore::XPath::Parser::expandQName):
+        * xml/XPathParser.h:
+        Moved code that expands a QName from XPathGrammar.y. Removed m_currentNamespaceURI.
+
+        * xml/XPathStep.cpp:
+        (WebCore::XPath::Step::Step):
+        * xml/XPathStep.h:
+        Added a constructor that takes a namespace.
+
 2007-02-17  Mitz Pettel  <mitz@webkit.org>
 
         Reviewed by Maciej.
index 3742b83..615089d 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright 2005 Frerich Raabe <raabe@kde.org>
  * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -90,6 +91,7 @@ void xpathyyerror(const char *str) { }
 %type <step> DescendantOrSelf
 %type <str> NodeTest
 %type <expr> Predicate
+%type <predList> OptionalPredicateList
 %type <predList> PredicateList
 %type <step> AbbreviatedStep
 %type <expr> Expr
@@ -174,33 +176,61 @@ RelativeLocationPath:
     ;
 
 Step:
-    NodeTest
+    NodeTest OptionalPredicateList
     {
-        $$ = new Step(Step::ChildAxis, *$1);
+        if ($2) {
+            $$ = new Step(Step::ChildAxis, *$1, *$2);
+            PARSER->deletePredicateVector($2);
+        } else
+            $$ = new Step(Step::ChildAxis, *$1);
         PARSER->deleteString($1);
         PARSER->registerParseNode($$);
     }
     |
-    NodeTest PredicateList
+    NAMETEST OptionalPredicateList
     {
-        $$ = new Step(Step::ChildAxis, *$1, *$2);
+        String localName;
+        String namespaceURI;
+        if (!PARSER->expandQName(*$1, localName, namespaceURI)) {
+            PARSER->m_gotNamespaceError = true;
+            YYABORT;
+        }
+        
+        if ($2) {
+            $$ = new Step(Step::ChildAxis, localName, namespaceURI, *$2);
+            PARSER->deletePredicateVector($2);
+        } else
+            $$ = new Step(Step::ChildAxis, localName, namespaceURI);
         PARSER->deleteString($1);
-        PARSER->deletePredicateVector($2);
         PARSER->registerParseNode($$);
     }
     |
-    AxisSpecifier NodeTest
+    AxisSpecifier NodeTest OptionalPredicateList
     {
-        $$ = new Step($1, *$2);
+        if ($3) {
+            $$ = new Step($1, *$2, *$3);
+            PARSER->deletePredicateVector($3);
+        } else
+            $$ = new Step($1, *$2);
         PARSER->deleteString($2);
         PARSER->registerParseNode($$);
     }
     |
-    AxisSpecifier NodeTest PredicateList
+    AxisSpecifier NAMETEST OptionalPredicateList
     {
-        $$ = new Step($1, *$2, *$3);
+        String localName;
+        String namespaceURI;
+        if (!PARSER->expandQName(*$2, localName, namespaceURI)) {
+            PARSER->m_gotNamespaceError = true;
+            YYABORT;
+        }
+
+        if ($3) {
+            $$ = new Step($1, localName, namespaceURI, *$3);
+            PARSER->deletePredicateVector($3);
+        } else
+            $$ = new Step($1, localName, namespaceURI);
         PARSER->deleteString($2);
-        PARSER->deletePredicateVector($3);
         PARSER->registerParseNode($$);
     }
     |
@@ -217,26 +247,6 @@ AxisSpecifier:
     ;
 
 NodeTest:
-    NAMETEST
-    {
-        int colon = $$->find(':');
-        if (colon >= 0) {
-            XPathNSResolver* resolver = PARSER->resolver();
-            if (!resolver) {
-                PARSER->m_gotNamespaceError = true;
-                YYABORT;
-            }
-            PARSER->m_currentNamespaceURI = resolver->lookupNamespaceURI($$->left(colon));
-            if (PARSER->m_currentNamespaceURI.isNull()) {
-                PARSER->m_gotNamespaceError = true;
-                YYABORT;
-            }
-            $$ = new String($1->substring(colon + 1));
-            PARSER->deleteString($1);
-            PARSER->registerString($$);
-        }
-    }
-    |
     NODETYPE '(' ')'
     {
         $$ = new String(*$1 + "()");
@@ -256,6 +266,15 @@ NodeTest:
     }
     ;
 
+OptionalPredicateList:
+    /* empty */
+    {
+        $$ = 0;
+    }
+    |
+    PredicateList
+    ;
+
 PredicateList:
     Predicate
     {
index 8d9f66f..e29f248 100644 (file)
@@ -446,6 +446,22 @@ int Parser::lex(void* data)
     return tok.type;
 }
 
+bool Parser::expandQName(const String& qName, String& localName, String& namespaceURI)
+{
+    int colon = qName.find(':');
+    if (colon >= 0) {
+        if (!m_resolver)
+            return false;
+        namespaceURI = m_resolver->lookupNamespaceURI(qName.left(colon));
+        if (namespaceURI.isNull())
+            return false;
+        localName = qName.substring(colon + 1);
+    } else
+        localName = qName;
+    
+    return true;
+}
+
 Expression* Parser::parseStatement(const String& statement, PassRefPtr<XPathNSResolver> resolver, ExceptionCode& ec)
 {
     reset(statement);
index 7680d6e..8df75fa 100644 (file)
@@ -63,6 +63,8 @@ namespace WebCore {
             Parser();
 
             XPathNSResolver* resolver() const { return m_resolver.get(); }
+            bool expandQName(const String& qName, String& localName, String& namespaceURI);
+
             Expression* parseStatement(const String& statement, PassRefPtr<XPathNSResolver>, ExceptionCode&);
 
             static Parser* current() { return currentParser; }
@@ -71,7 +73,6 @@ namespace WebCore {
 
             Expression* m_topExpr;
             bool m_gotNamespaceError;
-            String m_currentNamespaceURI;
 
             void registerParseNode(ParseNode*);
             void unregisterParseNode(ParseNode*);
index 355a6d1..fa45854 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright 2005 Frerich Raabe <raabe@kde.org>
  * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,12 +39,18 @@ namespace WebCore {
 namespace XPath {
 
 Step::Step(Axis axis, const String& nodeTest, const Vector<Predicate*>& predicates)
-    : m_axis(axis), m_nodeTest(nodeTest), m_predicates(predicates)
+    : m_axis(axis)
+    , m_nodeTest(nodeTest)
+    , m_predicates(predicates)
+{
+}
+
+Step::Step(Axis axis, const String& nodeTest, const String& namespaceURI, const Vector<Predicate*>& predicates)
+    : m_axis(axis)
+    , m_nodeTest(nodeTest)
+    , m_namespaceURI(namespaceURI)
+    , m_predicates(predicates)
 {
-    Parser* parser = Parser::current();
-    ASSERT(parser);
-    m_namespaceURI = parser->m_currentNamespaceURI;
-    parser->m_currentNamespaceURI = String();
 }
 
 Step::~Step()
index bae46c5..56416fe 100644 (file)
@@ -50,6 +50,7 @@ namespace WebCore {
             };
 
             Step(Axis, const String& nodeTest, const Vector<Predicate*>& predicates = Vector<Predicate*>());
+            Step(Axis, const String& nodeTest, const String& namespaceURI, const Vector<Predicate*>& predicates = Vector<Predicate*>());
             ~Step();
 
             NodeVector evaluate(Node* context) const;