2009-11-10 Vitaly Repeshko <vitalyr@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Nov 2009 02:15:19 +0000 (02:15 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Nov 2009 02:15:19 +0000 (02:15 +0000)
        Reviewed by Dimitri Glazkov.

        [V8] Fix crash in V8CustomXPathNSResolver (http://crbug.com/26726).
        https://bugs.webkit.org/show_bug.cgi?id=31301

        * fast/xpath/xpath-detached-iframe-resolver-crash-expected.txt: Added.
        * fast/xpath/xpath-detached-iframe-resolver-crash.html: Added.
2009-11-10  Vitaly Repeshko  <vitalyr@chromium.org>

        Reviewed by Dimitri Glazkov.

        [V8] Fix crash in V8CustomXPathNSResolver (http://crbug.com/26726).
        https://bugs.webkit.org/show_bug.cgi?id=31301

        Tested by new fast/xpath/xpath-detached-iframe-resolver-crash.html.

        Allowed passing V8Proxy for the calling JS context:
        * bindings/v8/V8DOMWrapper.h:
        (WebCore::V8DOMWrapper::getXPathNSResolver):
        * bindings/v8/custom/V8CustomXPathNSResolver.cpp:
        (WebCore::V8CustomXPathNSResolver::create):
        (WebCore::V8CustomXPathNSResolver::V8CustomXPathNSResolver):
        (WebCore::V8CustomXPathNSResolver::lookupNamespaceURI):
        * bindings/v8/custom/V8CustomXPathNSResolver.h:
        * bindings/v8/custom/V8DocumentCustom.cpp:
        (WebCore::CALLBACK_FUNC_DECL):

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

LayoutTests/ChangeLog
LayoutTests/fast/xpath/xpath-detached-iframe-resolver-crash-expected.txt [new file with mode: 0644]
LayoutTests/fast/xpath/xpath-detached-iframe-resolver-crash.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/bindings/v8/V8DOMWrapper.h
WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
WebCore/bindings/v8/custom/V8DocumentCustom.cpp

index 36c6693ea35541f0614a1c10121a6c8fb7ebd162..48c4b7217ff5257ab63f62549696f8920509c145 100644 (file)
@@ -1,3 +1,13 @@
+2009-11-10  Vitaly Repeshko  <vitalyr@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        [V8] Fix crash in V8CustomXPathNSResolver (http://crbug.com/26726).
+        https://bugs.webkit.org/show_bug.cgi?id=31301
+
+        * fast/xpath/xpath-detached-iframe-resolver-crash-expected.txt: Added.
+        * fast/xpath/xpath-detached-iframe-resolver-crash.html: Added.
+
 2009-11-10  Yael Aharon  <yael.aharon@nokia.com>
 
         Reviewed by Timothy Hatcher.
diff --git a/LayoutTests/fast/xpath/xpath-detached-iframe-resolver-crash-expected.txt b/LayoutTests/fast/xpath/xpath-detached-iframe-resolver-crash-expected.txt
new file mode 100644 (file)
index 0000000..ca8b136
--- /dev/null
@@ -0,0 +1,6 @@
+Ensure that using XPath namespace resolver with a detached iframe doesn't crash.
+
+PASS Did not crash.
+PASS dummyResolverCalled is true
+PASS foundNode.toString() is "[object HTMLDivElement]"
+
diff --git a/LayoutTests/fast/xpath/xpath-detached-iframe-resolver-crash.html b/LayoutTests/fast/xpath/xpath-detached-iframe-resolver-crash.html
new file mode 100644 (file)
index 0000000..c3e81a3
--- /dev/null
@@ -0,0 +1,41 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+    if (window.layoutTestController) {
+        layoutTestController.waitUntilDone();
+        layoutTestController.dumpAsText();
+    }
+
+    var dummyResolverCalled = false;
+    var foundNode;
+    function dummyResolver() {
+        dummyResolverCalled = true;
+        return "http://www.w3.org/1999/xhtml";
+    }
+
+    function test() {
+        var iframe = document.createElement("iframe");
+        document.body.appendChild(iframe);
+        var doc = iframe.contentWindow.document;
+        doc.open();
+        doc.write("<html><body><div></div></body></html>");
+        doc.close();
+        document.body.removeChild(iframe);
+        foundNode = doc.evaluate("//dummyns:div", doc, dummyResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
+
+        testPassed("Did not crash.");
+        shouldBeTrue("dummyResolverCalled");
+        shouldBe("foundNode.toString()", "\"[object HTMLDivElement]\"");
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
+</script>
+</head>
+<body onload="test()">
+<p>Ensure that using XPath namespace resolver with a detached iframe doesn't crash.</p>
+<div id="console"></div>
+</body>
+</html>
index 9da85cd07cd6d15b675edcd93a406d5a14664b3f..82466be74ab699aeb0eecbe6ed7129ea2b417564 100644 (file)
@@ -1,3 +1,23 @@
+2009-11-10  Vitaly Repeshko  <vitalyr@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        [V8] Fix crash in V8CustomXPathNSResolver (http://crbug.com/26726).
+        https://bugs.webkit.org/show_bug.cgi?id=31301
+
+        Tested by new fast/xpath/xpath-detached-iframe-resolver-crash.html.
+
+        Allowed passing V8Proxy for the calling JS context:
+        * bindings/v8/V8DOMWrapper.h:
+        (WebCore::V8DOMWrapper::getXPathNSResolver):
+        * bindings/v8/custom/V8CustomXPathNSResolver.cpp:
+        (WebCore::V8CustomXPathNSResolver::create):
+        (WebCore::V8CustomXPathNSResolver::V8CustomXPathNSResolver):
+        (WebCore::V8CustomXPathNSResolver::lookupNamespaceURI):
+        * bindings/v8/custom/V8CustomXPathNSResolver.h:
+        * bindings/v8/custom/V8DocumentCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+
 2009-11-10  Yael Aharon  <yael.aharon@nokia.com>
 
         Reviewed by Timothy Hatcher.
index 1bffc117e3a1f37ced3089888661cab560cb810a..9ba888f9d69b4aed72cda52f5a27cbc790c6b294 100644 (file)
@@ -253,13 +253,13 @@ namespace WebCore {
 
 
         // XPath-related utilities
-        static RefPtr<XPathNSResolver> getXPathNSResolver(v8::Handle<v8::Value> value)
+        static RefPtr<XPathNSResolver> getXPathNSResolver(v8::Handle<v8::Value> value, V8Proxy* proxy = 0)
         {
             RefPtr<XPathNSResolver> resolver;
             if (V8XPathNSResolver::HasInstance(value))
                 resolver = convertToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, v8::Handle<v8::Object>::Cast(value));
             else if (value->IsObject())
-                resolver = V8CustomXPathNSResolver::create(value->ToObject());
+                resolver = V8CustomXPathNSResolver::create(proxy, value->ToObject());
             return resolver;
         }
 
index 334192495b285f6818dff6ed3ad611fa8770c2e3..e45cba0285c48a513960742fb0d285cbb02356c0 100644 (file)
 
 namespace WebCore {
 
-PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver)
+PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
 {
-    return adoptRef(new V8CustomXPathNSResolver(resolver));
+    return adoptRef(new V8CustomXPathNSResolver(proxy, resolver));
 }
 
-V8CustomXPathNSResolver::V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver)
-    : m_resolver(resolver)
+V8CustomXPathNSResolver::V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
+        : m_proxy(proxy)
+        , m_resolver(resolver)
 {
 }
 
@@ -54,6 +55,14 @@ V8CustomXPathNSResolver::~V8CustomXPathNSResolver()
 
 String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
 {
+    V8Proxy* proxy = m_proxy;
+
+    if (!proxy) {
+        proxy = V8Proxy::retrieve();
+        if (!proxy)
+            return String();
+    }
+
     v8::Handle<v8::Function> lookupNamespaceURIFunc;
     v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI");
 
@@ -65,7 +74,7 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
     }
 
     if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
-        Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+        Frame* frame = proxy->frame();
         logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
         return String();
     }
@@ -78,7 +87,6 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
     v8::Handle<v8::Value> argv[argc] = { v8String(prefix) };
     v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc;
 
-    V8Proxy* proxy = V8Proxy::retrieve();
     v8::Handle<v8::Value> retval = proxy->callFunction(function, m_resolver, argc, argv);
 
     // Eat exceptions from namespace resolver and return an empty string. This will most likely cause NAMESPACE_ERR.
index f1dc65c70ff524d1f7a98845a2e58b2310294d6f..15ac27d09a5b389dcc3c3d2ff78171ebe28387ff 100644 (file)
 namespace WebCore {
 
 class String;
+class V8Proxy;
 
+// V8CustomXPathNSResolver does not create a persistent handle to the
+// given resolver object.  So the lifetime of V8CustomXPathNSResolver
+// must not exceed the lifetime of the passed handle.
 class V8CustomXPathNSResolver : public XPathNSResolver {
 public:
-    static PassRefPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver);
+    static PassRefPtr<V8CustomXPathNSResolver> create(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
 
     virtual ~V8CustomXPathNSResolver();
     virtual String lookupNamespaceURI(const String& prefix);
 
 private:
-    V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver);
+    V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
 
+    V8Proxy* m_proxy;
     v8::Handle<v8::Object> m_resolver;  // Handle to resolver object.
 };
 
index 2330778458e72e31a9ba5764670366c72f6b19f2..b43dfe2a7bf80ee13365dbf2731073c03fe19a1a 100644 (file)
@@ -61,7 +61,7 @@ CALLBACK_FUNC_DECL(DocumentEvaluate)
     if (V8Node::HasInstance(args[1]))
         contextNode = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1]));
 
-    RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2]);
+    RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2], V8Proxy::retrieve(V8Proxy::retrieveFrameForCallingContext()));
     if (!resolver && !args[2]->IsNull() && !args[2]->IsUndefined())
         return throwError(TYPE_MISMATCH_ERR);