Commit 7d532721 authored by haraken@chromium.org's avatar haraken@chromium.org

Add an ASSERT about cross-world wrapper leakage into ScriptValue

- This CL adds an ASSERT to ScriptValue to verify that ScriptValue::v8Value() is used in the same world that created the ScriptValue.

- To insert the check, we need to get a current world in ScriptValue::v8Value(). For that goal, this CL makes sure that we're in some context when calling ScriptValue::v8Value().

BUG=341032

Committed: https://src.chromium.org/viewvc/blink?view=rev&revision=175837

Review URL: https://codereview.chromium.org/314953005

git-svn-id: svn://svn.chromium.org/blink/trunk@175944 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent c36751e4
......@@ -513,20 +513,20 @@ bool ScriptController::executeScriptIfJavaScriptURL(const KURL& url)
bool locationChangeBefore = m_frame->navigationScheduler().locationChangePending();
String decodedURL = decodeURLEscapeSequences(url.string());
ScriptValue result = evaluateScriptInMainWorld(ScriptSourceCode(decodedURL.substring(javascriptSchemeLength)), NotSharableCrossOrigin, DoNotExecuteScriptWhenScriptsDisabled);
v8::HandleScope handleScope(m_isolate);
v8::Local<v8::Value> result = evaluateScriptInMainWorld(ScriptSourceCode(decodedURL.substring(javascriptSchemeLength)), NotSharableCrossOrigin, DoNotExecuteScriptWhenScriptsDisabled);
// If executing script caused this frame to be removed from the page, we
// don't want to try to replace its document!
if (!m_frame->page())
return true;
String scriptResult;
if (!result.toString(scriptResult))
if (result.IsEmpty() || !result->IsString())
return true;
String scriptResult = toCoreString(v8::Handle<v8::String>::Cast(result));
// We're still in a frame, so there should be a DocumentLoader.
ASSERT(m_frame->document()->loader());
if (!locationChangeBefore && m_frame->navigationScheduler().locationChangePending())
return true;
......@@ -541,23 +541,25 @@ bool ScriptController::executeScriptIfJavaScriptURL(const KURL& url)
void ScriptController::executeScriptInMainWorld(const String& script, ExecuteScriptPolicy policy)
{
v8::HandleScope handleScope(m_isolate);
evaluateScriptInMainWorld(ScriptSourceCode(script), NotSharableCrossOrigin, policy);
}
void ScriptController::executeScriptInMainWorld(const ScriptSourceCode& sourceCode, AccessControlStatus corsStatus)
{
v8::HandleScope handleScope(m_isolate);
evaluateScriptInMainWorld(sourceCode, corsStatus, DoNotExecuteScriptWhenScriptsDisabled);
}
ScriptValue ScriptController::executeScriptInMainWorldAndReturnValue(const ScriptSourceCode& sourceCode)
v8::Local<v8::Value> ScriptController::executeScriptInMainWorldAndReturnValue(const ScriptSourceCode& sourceCode)
{
return evaluateScriptInMainWorld(sourceCode, NotSharableCrossOrigin, DoNotExecuteScriptWhenScriptsDisabled);
}
ScriptValue ScriptController::evaluateScriptInMainWorld(const ScriptSourceCode& sourceCode, AccessControlStatus corsStatus, ExecuteScriptPolicy policy)
v8::Local<v8::Value> ScriptController::evaluateScriptInMainWorld(const ScriptSourceCode& sourceCode, AccessControlStatus corsStatus, ExecuteScriptPolicy policy)
{
if (policy == DoNotExecuteScriptWhenScriptsDisabled && !canExecuteScripts(AboutToExecuteScript))
return ScriptValue();
return v8::Local<v8::Value>();
String sourceURL = sourceCode.url();
const String* savedSourceURL = m_sourceURL;
......@@ -565,8 +567,9 @@ ScriptValue ScriptController::evaluateScriptInMainWorld(const ScriptSourceCode&
ScriptState* scriptState = ScriptState::forMainWorld(m_frame);
if (scriptState->contextIsEmpty())
return ScriptValue();
return v8::Local<v8::Value>();
v8::EscapableHandleScope handleScope(scriptState->isolate());
ScriptState::Scope scope(scriptState);
RefPtr<LocalFrame> protect(m_frame);
......@@ -580,12 +583,12 @@ ScriptValue ScriptController::evaluateScriptInMainWorld(const ScriptSourceCode&
m_sourceURL = savedSourceURL;
if (object.IsEmpty())
return ScriptValue();
return v8::Local<v8::Value>();
return ScriptValue(scriptState, object);
return handleScope.Escape(object);
}
void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results)
void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<v8::Local<v8::Value> >* results)
{
ASSERT(worldID > 0);
......@@ -595,6 +598,7 @@ void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<Sc
return;
ScriptState* scriptState = isolatedWorldShell->scriptState();
v8::EscapableHandleScope handleScope(scriptState->isolate());
ScriptState::Scope scope(scriptState);
v8::Local<v8::Array> resultArray = v8::Array::New(m_isolate, sources.size());
......@@ -607,7 +611,7 @@ void ScriptController::executeScriptInIsolatedWorld(int worldID, const Vector<Sc
if (results) {
for (size_t i = 0; i < resultArray->Length(); ++i)
results->append(ScriptValue(scriptState, resultArray->Get(i)));
results->append(handleScope.Escape(resultArray->Get(i)));
}
}
......
......@@ -83,7 +83,7 @@ public:
// Evaluate JavaScript in the main world.
void executeScriptInMainWorld(const String&, ExecuteScriptPolicy = DoNotExecuteScriptWhenScriptsDisabled);
void executeScriptInMainWorld(const ScriptSourceCode&, AccessControlStatus = NotSharableCrossOrigin);
ScriptValue executeScriptInMainWorldAndReturnValue(const ScriptSourceCode&);
v8::Local<v8::Value> executeScriptInMainWorldAndReturnValue(const ScriptSourceCode&);
v8::Local<v8::Value> executeScriptAndReturnValue(v8::Handle<v8::Context>, const ScriptSourceCode&, AccessControlStatus = NotSharableCrossOrigin);
// Executes JavaScript in an isolated world. The script gets its own global scope,
......@@ -94,7 +94,7 @@ public:
// Otherwise, a new world is created.
//
// FIXME: Get rid of extensionGroup here.
void executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results);
void executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<v8::Local<v8::Value> >* results);
// Returns true if argument is a JavaScript URL.
bool executeScriptIfJavaScriptURL(const KURL&);
......@@ -154,7 +154,7 @@ private:
typedef HashMap<int, OwnPtr<V8WindowShell> > IsolatedWorldMap;
typedef HashMap<Widget*, NPObject*> PluginObjectMap;
ScriptValue evaluateScriptInMainWorld(const ScriptSourceCode&, AccessControlStatus, ExecuteScriptPolicy);
v8::Local<v8::Value> evaluateScriptInMainWorld(const ScriptSourceCode&, AccessControlStatus, ExecuteScriptPolicy);
LocalFrame* m_frame;
const String* m_sourceURL;
......
......@@ -49,12 +49,13 @@ ScriptPreprocessor::ScriptPreprocessor(const ScriptSourceCode& preprocessorSourc
RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(ScriptPreprocessorIsolatedWorldId, DOMWrapperWorld::mainWorldExtensionGroup);
m_scriptState = ScriptState::from(toV8Context(frame, *world));
v8::HandleScope handleScope(m_scriptState->isolate());
ASSERT(frame);
v8::TryCatch tryCatch;
tryCatch.SetVerbose(true);
Vector<ScriptSourceCode> sources;
sources.append(preprocessorSourceCode);
Vector<ScriptValue> scriptResults;
Vector<v8::Local<v8::Value> > scriptResults;
frame->script().executeScriptInIsolatedWorld(ScriptPreprocessorIsolatedWorldId, sources, DOMWrapperWorld::mainWorldExtensionGroup, &scriptResults);
if (scriptResults.size() != 1) {
......@@ -62,12 +63,12 @@ ScriptPreprocessor::ScriptPreprocessor(const ScriptSourceCode& preprocessorSourc
return;
}
ScriptValue preprocessorFunction = scriptResults[0];
if (!preprocessorFunction.isFunction()) {
v8::Local<v8::Value> preprocessorFunction = scriptResults[0];
if (preprocessorFunction.IsEmpty() || !preprocessorFunction->IsFunction()) {
frame->console().addMessage(JSMessageSource, ErrorMessageLevel, "The preprocessor must compile to a function.");
return;
}
m_preprocessorFunction.set(m_scriptState->isolate(), v8::Handle<v8::Function>::Cast(preprocessorFunction.v8Value()));
m_preprocessorFunction.set(m_scriptState->isolate(), v8::Handle<v8::Function>::Cast(preprocessorFunction));
}
String ScriptPreprocessor::preprocessSourceCode(const String& sourceCode, const String& sourceName)
......
......@@ -94,9 +94,9 @@ ScriptPromise ScriptPromise::then(PassOwnPtr<ScriptFunction> onFulfilled, PassOw
return ScriptPromise(m_scriptState.get(), resultPromise);
}
ScriptPromise ScriptPromise::cast(const ScriptValue& value)
ScriptPromise ScriptPromise::cast(ScriptState* scriptState, const ScriptValue& value)
{
return ScriptPromise::cast(value.scriptState(), value.v8Value());
return ScriptPromise::cast(scriptState, value.v8Value());
}
ScriptPromise ScriptPromise::cast(ScriptState* scriptState, v8::Handle<v8::Value> value)
......@@ -112,9 +112,9 @@ ScriptPromise ScriptPromise::cast(ScriptState* scriptState, v8::Handle<v8::Value
return promise;
}
ScriptPromise ScriptPromise::reject(const ScriptValue& value)
ScriptPromise ScriptPromise::reject(ScriptState* scriptState, const ScriptValue& value)
{
return ScriptPromise::reject(value.scriptState(), value.v8Value());
return ScriptPromise::reject(scriptState, value.v8Value());
}
ScriptPromise ScriptPromise::reject(ScriptState* scriptState, v8::Handle<v8::Value> value)
......
......@@ -97,10 +97,10 @@ public:
// if |value| is not a Promise object, returns a Promise object
// resolved with |value|.
// Returns |value| itself if it is a Promise.
static ScriptPromise cast(const ScriptValue& /*value*/);
static ScriptPromise cast(ScriptState*, const ScriptValue& /*value*/);
static ScriptPromise cast(ScriptState*, v8::Handle<v8::Value> /*value*/);
static ScriptPromise reject(const ScriptValue&);
static ScriptPromise reject(ScriptState*, const ScriptValue&);
static ScriptPromise reject(ScriptState*, v8::Handle<v8::Value>);
static ScriptPromise rejectWithDOMException(ScriptState*, PassRefPtrWillBeRawPtr<DOMException>);
......
......@@ -194,8 +194,8 @@ TEST_F(ScriptPromiseTest, castNonPromise)
String onFulfilled1, onFulfilled2, onRejected1, onRejected2;
ScriptValue value = ScriptValue(scriptState(), v8String(isolate(), "hello"));
ScriptPromise promise1 = ScriptPromise::cast(ScriptValue(value));
ScriptPromise promise2 = ScriptPromise::cast(ScriptValue(value));
ScriptPromise promise1 = ScriptPromise::cast(scriptState(), ScriptValue(value));
ScriptPromise promise2 = ScriptPromise::cast(scriptState(), ScriptValue(value));
promise1.then(Function::create(isolate(), &onFulfilled1), Function::create(isolate(), &onRejected1));
promise2.then(Function::create(isolate(), &onFulfilled2), Function::create(isolate(), &onRejected2));
......@@ -224,7 +224,7 @@ TEST_F(ScriptPromiseTest, reject)
String onFulfilled, onRejected;
ScriptValue value = ScriptValue(scriptState(), v8String(isolate(), "hello"));
ScriptPromise promise = ScriptPromise::reject(ScriptValue(value));
ScriptPromise promise = ScriptPromise::reject(scriptState(), ScriptValue(value));
promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected));
ASSERT_FALSE(promise.isEmpty());
......
......@@ -41,12 +41,29 @@ ScriptValue::~ScriptValue()
{
}
v8::Handle<v8::Value> ScriptValue::v8Value() const
{
if (isEmpty())
return v8::Handle<v8::Value>();
ASSERT(isolate()->InContext());
// This is a check to validate that you don't return a ScriptValue to a world different
// from the world that created the ScriptValue.
// Probably this could be:
// if (&m_scriptState->world() == &DOMWrapperWorld::current(isolate()))
// return v8::Handle<v8::Value>();
// instead of triggering RELEASE_ASSERT.
RELEASE_ASSERT(&m_scriptState->world() == &DOMWrapperWorld::current(isolate()));
return m_value->newLocal(isolate());
}
bool ScriptValue::toString(String& result) const
{
if (isEmpty())
return false;
v8::HandleScope handleScope(isolate());
ScriptState::Scope scope(m_scriptState.get());
v8::Handle<v8::Value> string = v8Value();
if (string.IsEmpty() || !string->IsString())
return false;
......
......@@ -57,6 +57,7 @@ public:
, m_scriptState(scriptState)
, m_value(value.IsEmpty() ? nullptr : SharedPersistent<v8::Value>::create(value, scriptState->isolate()))
{
ASSERT(isEmpty() || m_scriptState);
}
ScriptValue(const ScriptValue& value)
......@@ -64,6 +65,7 @@ public:
, m_scriptState(value.m_scriptState)
, m_value(value.m_value)
{
ASSERT(isEmpty() || m_scriptState);
}
ScriptState* scriptState() const
......@@ -144,10 +146,7 @@ public:
m_value = nullptr;
}
v8::Handle<v8::Value> v8Value() const
{
return m_value.get() ? m_value->newLocal(isolate()) : v8::Handle<v8::Value>();
}
v8::Handle<v8::Value> v8Value() const;
bool toString(String&) const;
PassRefPtr<JSONValue> toJSONValue(ScriptState*) const;
......
......@@ -64,9 +64,9 @@
namespace WebCore {
Node* InjectedScriptHost::scriptValueAsNode(ScriptValue value)
Node* InjectedScriptHost::scriptValueAsNode(ScriptState* scriptState, ScriptValue value)
{
v8::HandleScope scope(value.isolate());
ScriptState::Scope scope(scriptState);
if (!value.isObject() || value.isNull())
return 0;
return V8Node::toNative(v8::Handle<v8::Object>::Cast(value.v8Value()));
......
......@@ -221,7 +221,7 @@ Node* InjectedScript::nodeForObjectId(const String& objectId)
ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException);
ASSERT(!hadException);
return InjectedScriptHost::scriptValueAsNode(resultValue);
return InjectedScriptHost::scriptValueAsNode(scriptState(), resultValue);
}
void InjectedScript::releaseObject(const String& objectId)
......
......@@ -64,6 +64,7 @@ void InjectedScriptBase::initialize(ScriptValue injectedScriptObject, InspectedS
bool InjectedScriptBase::canAccessInspectedWindow() const
{
ASSERT(!isEmpty());
return m_inspectedStateAccessCheck(m_injectedScriptObject.scriptState());
}
......@@ -74,6 +75,7 @@ const ScriptValue& InjectedScriptBase::injectedScriptObject() const
ScriptValue InjectedScriptBase::callFunctionWithEvalEnabled(ScriptFunctionCall& function, bool& hadException) const
{
ASSERT(!isEmpty());
ExecutionContext* executionContext = m_injectedScriptObject.scriptState()->executionContext();
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", InspectorFunctionCallEvent::data(executionContext, 0, name(), 1));
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
......
......@@ -50,7 +50,11 @@ public:
const String& name() const { return m_name; }
bool isEmpty() const { return m_injectedScriptObject.isEmpty(); }
ScriptState* scriptState() const { return m_injectedScriptObject.scriptState(); }
ScriptState* scriptState() const
{
ASSERT(!isEmpty());
return m_injectedScriptObject.scriptState();
}
protected:
typedef bool (*InspectedStateAccessCheck)(ScriptState*);
......
......@@ -67,7 +67,7 @@ public:
m_scriptDebugServer = scriptDebugServer;
}
static Node* scriptValueAsNode(ScriptValue);
static Node* scriptValueAsNode(ScriptState*, ScriptValue);
static ScriptValue nodeAsScriptValue(ScriptState*, Node*);
void disconnect();
......
......@@ -170,6 +170,7 @@ v8::Handle<v8::Object> JavaScriptCallFrame::innerCallFrame()
ScriptValue JavaScriptCallFrame::setVariableValue(ScriptState* scriptState, int scopeNumber, const String& variableName, const ScriptValue& newValue)
{
ScriptState::Scope scriptScope(scriptState);
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> setVariableValueFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "setVariableValue")));
v8::Handle<v8::Value> argv[] = {
......
......@@ -2286,10 +2286,9 @@ private:
virtual ScriptValue call(ScriptValue value) OVERRIDE
{
v8::Local<v8::Value> v8Value = value.v8Value();
v8::Isolate* isolate = value.isolate();
ASSERT(v8Value->IsNumber());
int intValue = v8Value.As<v8::Integer>()->Value();
ScriptValue result = ScriptValue(value.scriptState(), v8::Integer::New(isolate, intValue + 1));
ScriptValue result = ScriptValue(ScriptState::current(isolate()), v8::Integer::New(isolate(), intValue + 1));
return result;
}
};
......
......@@ -26,9 +26,9 @@ Request* FetchEvent::request() const
return m_request.get();
}
void FetchEvent::respondWith(const ScriptValue& value)
void FetchEvent::respondWith(ScriptState* scriptState, const ScriptValue& value)
{
m_observer->respondWith(value);
m_observer->respondWith(scriptState, value);
}
const AtomicString& FetchEvent::interfaceName() const
......
......@@ -26,7 +26,7 @@ public:
Request* request() const;
void respondWith(const ScriptValue&);
void respondWith(ScriptState*, const ScriptValue&);
virtual const AtomicString& interfaceName() const OVERRIDE;
......
......@@ -8,5 +8,5 @@
] interface FetchEvent : Event {
readonly attribute Request request;
void respondWith(any value);
[CallWith=ScriptState] void respondWith(any value);
};
......@@ -50,9 +50,9 @@ InstallPhaseEvent::~InstallPhaseEvent()
{
}
void InstallPhaseEvent::waitUntil(const ScriptValue& value)
void InstallPhaseEvent::waitUntil(ScriptState* scriptState, const ScriptValue& value)
{
m_observer->waitUntil(value);
m_observer->waitUntil(scriptState, value);
}
InstallPhaseEvent::InstallPhaseEvent()
......
......@@ -45,7 +45,7 @@ public:
virtual ~InstallPhaseEvent();
void waitUntil(const ScriptValue&);
void waitUntil(ScriptState*, const ScriptValue&);
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual void trace(Visitor*) OVERRIDE;
......
......@@ -32,5 +32,5 @@
RuntimeEnabled=ServiceWorker,
Exposed=ServiceWorker,
] interface InstallPhaseEvent : Event {
void waitUntil(any value);
[CallWith=ScriptState] void waitUntil(any value);
};
......@@ -77,13 +77,13 @@ void RespondWithObserver::didDispatchEvent()
sendResponse(nullptr);
}
void RespondWithObserver::respondWith(const ScriptValue& value)
void RespondWithObserver::respondWith(ScriptState* scriptState, const ScriptValue& value)
{
if (m_state != Initial)
return;
m_state = Pending;
ScriptPromise::cast(value).then(
ScriptPromise::cast(scriptState, value).then(
ThenFunction::create(this, ThenFunction::Fulfilled),
ThenFunction::create(this, ThenFunction::Rejected));
}
......
......@@ -13,6 +13,7 @@ namespace WebCore {
class ExecutionContext;
class Response;
class ScriptState;
class ScriptValue;
// This class observes the service worker's handling of a FetchEvent and
......@@ -28,7 +29,7 @@ public:
// Observes the promise and delays calling didHandleFetchEvent() until the
// given promise is resolved or rejected.
void respondWith(const ScriptValue&);
void respondWith(ScriptState*, const ScriptValue&);
void responseWasRejected();
void responseWasFulfilled(const ScriptValue&);
......
......@@ -75,10 +75,10 @@ void WaitUntilObserver::didDispatchEvent()
decrementPendingActivity();
}
void WaitUntilObserver::waitUntil(const ScriptValue& value)
void WaitUntilObserver::waitUntil(ScriptState* scriptState, const ScriptValue& value)
{
incrementPendingActivity();
ScriptPromise::cast(value).then(
ScriptPromise::cast(scriptState, value).then(
ThenFunction::create(this, ThenFunction::Fulfilled),
ThenFunction::create(this, ThenFunction::Rejected));
}
......
......@@ -13,6 +13,7 @@
namespace WebCore {
class ExecutionContext;
class ScriptState;
class ScriptValue;
// Created for each InstallPhaseEvent instance.
......@@ -35,7 +36,7 @@ public:
// Observes the promise and delays calling the continuation until
// the given promise is resolved or rejected.
void waitUntil(const ScriptValue&);
void waitUntil(ScriptState*, const ScriptValue&);
private:
class ThenFunction;
......
......@@ -744,6 +744,7 @@ void WebLocalFrameImpl::executeScript(const WebScriptSource& source)
{
ASSERT(frame());
TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
v8::HandleScope handleScope(toIsolate(frame()));
frame()->script().executeScriptInMainWorld(ScriptSourceCode(source.code, source.url, position));
}
......@@ -759,6 +760,7 @@ void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScrip
sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position));
}
v8::HandleScope handleScope(toIsolate(frame()));
frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
}
......@@ -826,7 +828,7 @@ v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValue(const WebSc
UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position)).v8Value();
return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position));
}
void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, WebVector<v8::Local<v8::Value> >* results)
......@@ -843,13 +845,14 @@ void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScrip
}
if (results) {
Vector<ScriptValue> scriptResults;
Vector<v8::Local<v8::Value> > scriptResults;
frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, &scriptResults);
WebVector<v8::Local<v8::Value> > v8Results(scriptResults.size());
for (unsigned i = 0; i < scriptResults.size(); i++)
v8Results[i] = v8::Local<v8::Value>::New(toIsolate(frame()), scriptResults[i].v8Value());
v8Results[i] = v8::Local<v8::Value>::New(toIsolate(frame()), scriptResults[i]);
results->swap(v8Results);
} else {
v8::HandleScope handleScope(toIsolate(frame()));
frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
}
}
......@@ -1882,12 +1885,11 @@ void WebLocalFrameImpl::loadJavaScriptURL(const KURL& url)
String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
ScriptValue result = frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
String scriptResult;
if (!result.toString(scriptResult))
v8::HandleScope handleScope(toIsolate(frame()));
v8::Local<v8::Value> result = frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
if (result.IsEmpty() || !result->IsString())
return;
String scriptResult = toCoreString(v8::Handle<v8::String>::Cast(result));
if (!frame()->navigationScheduler().locationChangePending())
frame()->document()->loader()->replaceDocument(scriptResult, ownerDocument.get());
}
......
......@@ -450,12 +450,13 @@ WebString WebPluginContainerImpl::executeScriptURL(const WebURL& url, bool popup
kurl.string().substring(strlen("javascript:")));
UserGestureIndicator gestureIndicator(popupsAllowed ? DefinitelyProcessingNewUserGesture : PossiblyProcessingUserGesture);
ScriptValue result = frame->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
v8::HandleScope handleScope(toIsolate(frame));
v8::Local<v8::Value> result = frame->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
// Failure is reported as a null string.
String resultString;
result.toString(resultString);
return resultString;
if (result.IsEmpty() || !result->IsString())
return WebString();
return toCoreString(v8::Handle<v8::String>::Cast(result));
}
void WebPluginContainerImpl::loadFrameRequest(const WebURLRequest& request, const WebString& target, bool notifyNeeded, void* notifyData)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment