Crash when calling QWebFrame::evaluateJavaScript
authorallan.jensen@digia.com <allan.jensen@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 May 2013 15:33:02 +0000 (15:33 +0000)
committerallan.jensen@digia.com <allan.jensen@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 May 2013 15:33:02 +0000 (15:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=113434

Reviewed by Simon Hausmann.

Ensure we hold the JSLock when converting JSValue to JSValueRef.

* Api/qwebelement.cpp:
(setupScriptContext):
(QWebElement::evaluateJavaScript):
* WebCoreSupport/QWebFrameAdapter.cpp:
(QWebFrameAdapter::evaluateJavaScript):

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

Source/WebKit/qt/Api/qwebelement.cpp
Source/WebKit/qt/ChangeLog
Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp

index e59a372..3ad2766 100644 (file)
@@ -45,6 +45,7 @@
 #include "NodeList.h"
 #include "RenderImage.h"
 #include "ScriptController.h"
+#include "ScriptSourceCode.h"
 #include "ScriptState.h"
 #include "StaticNodeList.h"
 #include "StyleResolver.h"
@@ -710,7 +711,7 @@ QWebFrame *QWebElement::webFrame() const
     return frameAdapter->apiHandle();
 }
 
-static bool setupScriptContext(WebCore::Element* element, JSC::JSValue& thisValue, ScriptState*& state, ScriptController*& scriptController)
+static bool setupScriptContext(WebCore::Element* element, ScriptState*& state, ScriptController*& scriptController)
 {
     if (!element)
         return false;
@@ -731,10 +732,6 @@ static bool setupScriptContext(WebCore::Element* element, JSC::JSValue& thisValu
     if (!state)
         return false;
 
-    thisValue = toJS(state, deprecatedGlobalObjectForPrototype(state), element);
-    if (!thisValue)
-        return false;
-
     return true;
 }
 
@@ -747,21 +744,29 @@ QVariant QWebElement::evaluateJavaScript(const QString& scriptSource)
         return QVariant();
 
     ScriptState* state = 0;
-    JSC::JSValue thisValue;
     ScriptController* scriptController = 0;
 
-    if (!setupScriptContext(m_element, thisValue, state, scriptController))
+    if (!setupScriptContext(m_element, state, scriptController))
+        return QVariant();
+
+    JSC::JSLockHolder lock(state);
+    RefPtr<Element> protect = m_element;
+
+    JSC::JSValue thisValue = toJS(state, toJSDOMGlobalObject(m_element->document(), state), m_element);
+    if (!thisValue)
         return QVariant();
-    String script(reinterpret_cast_ptr<const UChar*>(scriptSource.data()), scriptSource.length());
+
+    ScriptSourceCode sourceCode(scriptSource);
 
     JSC::JSValue evaluationException;
-    JSC::JSValue evaluationResult = JSC::evaluate(state, JSC::makeSource(script), thisValue, &evaluationException);
+    JSC::JSValue evaluationResult = JSC::evaluate(state, sourceCode.jsSourceCode(), thisValue, &evaluationException);
     if (evaluationException)
         return QVariant();
+    JSValueRef evaluationResultRef = toRef(state, evaluationResult);
 
     int distance = 0;
     JSValueRef* ignoredException = 0;
-    return JSC::Bindings::convertValueToQVariant(toRef(state), toRef(state, evaluationResult), QMetaType::Void, &distance, ignoredException);
+    return JSC::Bindings::convertValueToQVariant(toRef(state), evaluationResultRef, QMetaType::Void, &distance, ignoredException);
 }
 
 /*!
index 5f4bae4..bc247d6 100644 (file)
@@ -1,3 +1,18 @@
+2013-05-07  Allan Sandfeld Jensen  <allan.jensen@digia.com>
+
+        Crash when calling QWebFrame::evaluateJavaScript
+        https://bugs.webkit.org/show_bug.cgi?id=113434
+
+        Reviewed by Simon Hausmann.
+
+        Ensure we hold the JSLock when converting JSValue to JSValueRef.
+
+        * Api/qwebelement.cpp:
+        (setupScriptContext):
+        (QWebElement::evaluateJavaScript):
+        * WebCoreSupport/QWebFrameAdapter.cpp:
+        (QWebFrameAdapter::evaluateJavaScript):
+
 2013-05-03  Andreas Kling  <akling@apple.com>
 
         StyleResolver: Have "list of matched rules" API vend internal types instead of CSSOM wrappers.
index 393cc37..b3c2398 100644 (file)
@@ -197,14 +197,17 @@ void QWebFrameAdapter::handleGestureEvent(QGestureEventFacade* gestureEvent)
 
 QVariant QWebFrameAdapter::evaluateJavaScript(const QString &scriptSource)
 {
-    ScriptController* proxy = frame->script();
+    ScriptController* scriptController = frame->script();
     QVariant rc;
-    if (proxy) {
+    if (scriptController) {
         int distance = 0;
-        JSC::JSValue v = frame->script()->executeScript(ScriptSourceCode(scriptSource)).jsValue();
-        JSC::ExecState* exec = proxy->globalObject(mainThreadNormalWorld())->globalExec();
+        ScriptValue value = scriptController->executeScript(ScriptSourceCode(scriptSource));
+        JSC::ExecState* exec = scriptController->globalObject(mainThreadNormalWorld())->globalExec();
         JSValueRef* ignoredException = 0;
-        rc = JSC::Bindings::convertValueToQVariant(toRef(exec), toRef(exec, v), QMetaType::Void, &distance, ignoredException);
+        exec->vm().apiLock().lock();
+        JSValueRef valueRef = toRef(exec, value.jsValue());
+        exec->vm().apiLock().unlock();
+        rc = JSC::Bindings::convertValueToQVariant(toRef(exec), valueRef, QMetaType::Void, &distance, ignoredException);
     }
     return rc;
 }