bool ScriptController::executeIfJavaScriptURL(const KURL& url, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL) { if (!protocolIsJavaScript(url)) return false; if (!m_frame->page() || !m_frame->page()->javaScriptURLsAreAllowed() || !m_frame->document()->contentSecurityPolicy()->allowJavaScriptURLs() || m_frame->inViewSourceMode()) return true; // We need to hold onto the Frame here because executing script can // destroy the frame. RefPtr<Frame> protector(m_frame); RefPtr<Document> ownerDocument(m_frame->document()); const int javascriptSchemeLength = sizeof("javascript:") - 1; String decodedURL = decodeURLEscapeSequences(url.string()); ScriptValue result = executeScript(decodedURL.substring(javascriptSchemeLength)); // 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 USE(JSC) JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld()); JSC::ExecState* exec = shell->window()->globalExec(); if (!result.getString(exec, scriptResult)) return true; #else if (!result.getString(scriptResult)) return true; #endif // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: // http://bugs.webkit.org/show_bug.cgi?id=16782 if (shouldReplaceDocumentIfJavaScriptURL == ReplaceDocumentIfJavaScriptURL) { // We're still in a frame, so there should be a DocumentLoader. ASSERT(m_frame->document()->loader()); // DocumentWriter::replaceDocument can cause the DocumentLoader to get deref'ed and possible destroyed, // so protect it with a RefPtr. if (RefPtr<DocumentLoader> loader = m_frame->document()->loader()) loader->writer()->replaceDocument(scriptResult, ownerDocument.get()); } return true; }
bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool replaceDocument) { if (!protocolIsJavaScript(url)) return false; if (m_frame->page() && !m_frame->page()->javaScriptURLsAreAllowed()) return true; if (m_frame->inViewSourceMode()) return true; #if PLATFORM(APOLLO) // We should return true even though the script is not going to be executed. // Otherwise the frame will actually try to navigate to "javascript:" // which will eventually fail, but will also stop any other in progress requests in this page // like CSS files, images or JS files if (!m_frame->loader()->client()->canExecuteScriptURL()) return true; #endif const int javascriptSchemeLength = sizeof("javascript:") - 1; String decodedURL = decodeURLEscapeSequences(url.string()); ScriptValue result; if (xssAuditor()->canEvaluateJavaScriptURL(decodedURL)) result = executeScript(decodedURL.substring(javascriptSchemeLength), userGesture, AllowXSS); String scriptResult; #if USE(JSC) JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld()); JSC::ExecState* exec = shell->window()->globalExec(); if (!result.getString(exec, scriptResult)) return true; #else if (!result.getString(scriptResult)) return true; #endif // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: // http://bugs.webkit.org/show_bug.cgi?id=16782 if (replaceDocument) m_frame->loader()->writer()->replaceDocument(scriptResult); return true; }
bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool replaceDocument) { if (!protocolIsJavaScript(url)) return false; if (m_frame->page() && !m_frame->page()->javaScriptURLsAreAllowed()) return true; if (m_frame->inViewSourceMode()) return true; const int javascriptSchemeLength = sizeof("javascript:") - 1; String script = decodeURLEscapeSequences(url.string().substring(javascriptSchemeLength)); ScriptValue result; if (xssAuditor()->canEvaluateJavaScriptURL(script)) result = executeScript(script, userGesture); String scriptResult; #if USE(JSC) JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld()); JSC::ExecState* exec = shell->window()->globalExec(); if (!result.getString(exec, scriptResult)) return true; #else if (!result.getString(scriptResult)) return true; #endif // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: // http://bugs.webkit.org/show_bug.cgi?id=16782 if (replaceDocument) m_frame->loader()->replaceDocument(scriptResult); return true; }
void PluginView::performJavaScriptURLRequest(URLRequest* request) { ASSERT(protocolIsJavaScript(request->request().url())); RefPtr<Frame> frame = m_pluginElement->document()->frame(); if (!frame) return; String jsString = decodeURLEscapeSequences(request->request().url().string().substring(sizeof("javascript:") - 1)); if (!request->target().isNull()) { // For security reasons, only allow JS requests to be made on the frame that contains the plug-in. if (frame->tree()->find(request->target()) != frame) { // Let the plug-in know that its frame load failed. m_plugin->frameDidFail(request->requestID(), false); return; } } // Evaluate the JavaScript code. Note that running JavaScript here could cause the plug-in to be destroyed, so we // grab references to the plug-in here. RefPtr<Plugin> plugin = m_plugin; ScriptValue result = m_pluginElement->document()->frame()->script()->executeScript(jsString); // Check if evaluating the JavaScript destroyed the plug-in. if (!plugin->controller()) return; ScriptState* scriptState = m_pluginElement->document()->frame()->script()->globalObject(pluginWorld())->globalExec(); String resultString; result.getString(scriptState, resultString); if (!request->target().isNull()) { // Just send back whether the frame load succeeded or not. if (resultString.isNull()) m_plugin->frameDidFail(request->requestID(), false); else m_plugin->frameDidFinishLoading(request->requestID()); return; } // Send the result back to the plug-in. plugin->didEvaluateJavaScript(request->requestID(), decodeURLEscapeSequences(request->request().url()), resultString); }
void PluginView::performJavaScriptURLRequest(URLRequest* request) { ASSERT(protocolIsJavaScript(request->request().url())); RefPtr<Frame> frame = m_pluginElement->document()->frame(); if (!frame) return; String jsString = decodeURLEscapeSequences(request->request().url().string().substring(sizeof("javascript:") - 1)); if (!request->target().isNull()) { // For security reasons, only allow JS requests to be made on the frame that contains the plug-in. if (frame->tree()->find(request->target()) != frame) { // Let the plug-in know that its frame load failed. m_plugin->frameDidFail(request->requestID(), false); return; } } // Evaluate the JavaScript code. Note that running JavaScript here could cause the plug-in to be destroyed, so we // grab references to the plug-in here. RefPtr<Plugin> plugin = m_plugin; ScriptValue result = frame->script()->executeScript(jsString, request->allowPopups()); // Check if evaluating the JavaScript destroyed the plug-in. if (!plugin->controller()) return; // Don't notify the plug-in at all about targeted javascript: requests. This matches Mozilla and WebKit1. if (!request->target().isNull()) return; #if USE(JSC) ScriptState* scriptState = frame->script()->globalObject(pluginWorld())->globalExec(); #elif USE(V8) ScriptState* scriptState = ScriptState::forContext(frame->script()->proxy()->context(frame.get())); #endif String resultString; result.getString(scriptState, resultString); // Send the result back to the plug-in. plugin->didEvaluateJavaScript(request->requestID(), resultString); }
WebString WebPluginContainerImpl::executeScriptURL(const WebURL& url, bool popupsAllowed) { Frame* frame = m_element->document()->frame(); if (!frame) return WebString(); const KURL& kurl = url; ASSERT(kurl.protocolIs("javascript")); String script = decodeURLEscapeSequences( kurl.string().substring(strlen("javascript:"))); ScriptValue result = frame->script()->executeScript(script, popupsAllowed); // Failure is reported as a null string. String resultStr; result.getString(resultStr); return resultStr; }