bool KHTMLSideBar::urlSelected( const QString &url, int button, int state, const QString &_target, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments& browserArgs ) { if (button == Qt::LeftButton ) { if (_target.toLower() == "_self") { openUrl(url); } else if (_target.toLower() == "_blank") { emit openUrlNewWindow(completeURL(url).url(), args); } else { // isEmpty goes here too emit openUrlRequest(completeURL(url).url(), args); } return true; } if (button == Qt::MidButton) { emit openUrlNewWindow(completeURL(url).url(), args); return true; } // A refresh if (button == 0 && _target.toLower() == "_self") { openUrl(completeURL(url)); return true; } return KHTMLPart::urlSelected(url, button, state, _target, args, browserArgs); }
bool DocumentationViewer::urlSelected(const QString &url, int button, int state, const QString &_target, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments & /* browserArgs */) { KUrl cURL = completeURL(url); QString mime = KMimeType::findByUrl(cURL).data()->name(); //load this URL in the embedded viewer if KHTML can handle it, or when mimetype detection failed KService::Ptr service = KService::serviceByDesktopName("khtml"); if(( mime == KMimeType::defaultMimeType() ) || (service && service->hasServiceType(mime))) { KHTMLPart::urlSelected(url, button, state, _target, args); openUrl(cURL); addToHistory(cURL.url()); } //KHTML can't handle it, look for an appropriate application else { KService::List offers = KMimeTypeTrader::self()->query(mime, "Type == 'Application'"); if(offers.isEmpty()) { KMessageBox::error(view(), i18n("No KDE service found for the MIME type \"%1\".", mime)); return false; } KUrl::List lst; lst.append(cURL); KRun::run(*(offers.first()), lst, view()); } return true; }
void JSDOMWindow::setLocation(ExecState* exec, JSValue value) { Frame* lexicalFrame = toLexicalFrame(exec); if (!lexicalFrame) return; #if ENABLE(DASHBOARD_SUPPORT) // To avoid breaking old widgets, make "var location =" in a top-level frame create // a property named "location" instead of performing a navigation (<rdar://problem/5688039>). if (Settings* settings = lexicalFrame->settings()) { if (settings->usesDashboardBackwardCompatibilityMode() && !lexicalFrame->tree()->parent()) { if (allowsAccessFrom(exec)) putDirect(Identifier(exec, "location"), value); return; } } #endif Frame* frame = impl()->frame(); ASSERT(frame); KURL url = completeURL(exec, ustringToString(value.toString(exec))); if (url.isNull()) return; if (!shouldAllowNavigation(exec, frame)) return; if (!protocolIsJavaScript(url) || allowsAccessFrom(exec)) { // We want a new history item if this JS was called via a user gesture frame->redirectScheduler()->scheduleLocationChange(url, lexicalFrame->loader()->outgoingReferrer(), !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, processingUserGesture()); } }
FetchRequest PreloadRequest::resourceRequest(Document* document) { ASSERT(isMainThread()); FetchInitiatorInfo initiatorInfo; initiatorInfo.name = AtomicString(m_initiatorName); initiatorInfo.position = m_initiatorPosition; ResourceRequest resourceRequest(completeURL(document)); resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_referrerPolicy, resourceRequest.url(), document->outgoingReferrer())); FetchRequest request(resourceRequest, initiatorInfo); if (m_resourceType == Resource::ImportResource) { SecurityOrigin* securityOrigin = document->contextDocument()->securityOrigin(); bool sameOrigin = securityOrigin->canRequest(request.url()); request.setCrossOriginAccessControl(securityOrigin, sameOrigin ? AllowStoredCredentials : DoNotAllowStoredCredentials, ClientDidNotRequestCredentials); } if (m_isCORSEnabled) request.setCrossOriginAccessControl(document->securityOrigin(), m_allowCredentials); request.setDefer(m_defer); request.setResourceWidth(m_resourceWidth); request.clientHintsPreferences().updateFrom(m_clientHintsPreferences); return request; }
PassRefPtr<EntrySync> WorkerContext::webkitResolveLocalFileSystemSyncURL(const String& url, ExceptionCode& ec) { ec = 0; KURL completedURL = completeURL(url); if (!AsyncFileSystem::isAvailable() || !securityOrigin()->canAccessFileSystem() || !securityOrigin()->canRequest(completedURL)) { ec = FileException::SECURITY_ERR; return 0; } AsyncFileSystem::Type type; String filePath; if (!completedURL.isValid() || !DOMFileSystemBase::crackFileSystemURL(completedURL, type, filePath)) { ec = FileException::ENCODING_ERR; return 0; } FileSystemSyncCallbackHelper readFileSystemHelper; LocalFileSystem::localFileSystem().readFileSystem(this, type, FileSystemCallbacks::create(readFileSystemHelper.successCallback(), readFileSystemHelper.errorCallback(), this), true); RefPtr<DOMFileSystemSync> fileSystem = readFileSystemHelper.getResult(ec); if (!fileSystem) return 0; RefPtr<EntrySync> entry = fileSystem->root()->getDirectory(filePath, 0, ec); if (ec == FileException::TYPE_MISMATCH_ERR) return fileSystem->root()->getFile(filePath, 0, ec); return entry.release(); }
bool ScriptExecutionContext::dispatchErrorEvent(const String& errorMessage, int lineNumber, const String& sourceURL) { EventTarget* target = errorEventTarget(); if (!target) return false; String message; int line; String sourceName; KURL targetUrl = completeURL(sourceURL); if (securityOrigin()->canRequest(targetUrl)) { message = errorMessage; line = lineNumber; sourceName = sourceURL; } else { message = "Script error."; sourceName = String(); line = 0; } ASSERT(!m_inDispatchErrorEvent); m_inDispatchErrorEvent = true; RefPtr<ErrorEvent> errorEvent = ErrorEvent::create(message, sourceName, line); target->dispatchEvent(errorEvent); m_inDispatchErrorEvent = false; return errorEvent->defaultPrevented(); }
FetchRequest PreloadRequest::resourceRequest(Document* document) { ASSERT(isMainThread()); FetchInitiatorInfo initiatorInfo; initiatorInfo.name = AtomicString(m_initiatorName); initiatorInfo.position = m_initiatorPosition; ResourceRequest resourceRequest(completeURL(document)); resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_referrerPolicy, resourceRequest.url(), document->outgoingReferrer())); ResourceFetcher::determineRequestContext(resourceRequest, m_resourceType, false); FetchRequest request(resourceRequest, initiatorInfo); if (m_resourceType == Resource::ImportResource) { SecurityOrigin* securityOrigin = document->contextDocument()->getSecurityOrigin(); request.setCrossOriginAccessControl(securityOrigin, CrossOriginAttributeAnonymous); } if (m_crossOrigin != CrossOriginAttributeNotSet) request.setCrossOriginAccessControl(document->getSecurityOrigin(), m_crossOrigin); request.setDefer(m_defer); request.setResourceWidth(m_resourceWidth); request.clientHintsPreferences().updateFrom(m_clientHintsPreferences); request.setIntegrityMetadata(m_integrityMetadata); request.setContentSecurityPolicyNonce(m_nonce); if (m_requestType == RequestTypeLinkRelPreload) request.setLinkPreload(true); return request; }
bool ExecutionContext::shouldSanitizeScriptError( const String& sourceURL, AccessControlStatus corsStatus) { if (corsStatus == OpaqueResource) return true; return !(getSecurityOrigin()->canRequestNoSuborigin(completeURL(sourceURL)) || corsStatus == SharableCrossOrigin); }
void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls, ExceptionState& exceptionState) { // Bust the MemoryCache to ensure script requests reach the browser-side // and get added to and retrieved from the ServiceWorker's script cache. // FIXME: Revisit in light of the solution to crbug/388375. for (Vector<String>::const_iterator it = urls.begin(); it != urls.end(); ++it) executionContext()->removeURLFromMemoryCache(completeURL(*it)); WorkerGlobalScope::importScripts(urls, exceptionState); }
bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage, int& lineNumber, String& sourceURL, CachedScript* cachedScript) { KURL targetURL = completeURL(sourceURL); if (securityOrigin()->canRequest(targetURL) || (cachedScript && cachedScript->passesAccessControlCheck(securityOrigin()))) return false; errorMessage = "Script error."; sourceURL = String(); lineNumber = 0; return true; }
bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage, int& lineNumber, String& sourceURL) { KURL targetURL = completeURL(sourceURL); if (securityOrigin()->canRequest(targetURL)) return false; errorMessage = "Script error."; sourceURL = String(); lineNumber = 0; return true; }
CachedResourceRequest PreloadRequest::resourceRequest(Document& document) { ASSERT(isMainThread()); CachedResourceRequest request(ResourceRequest(completeURL(document))); request.setInitiator(m_initiator); // FIXME: It's possible CORS should work for other request types? if (m_resourceType == CachedResource::Script) request.mutableResourceRequest().setAllowCookies(m_crossOriginModeAllowsCookies); return request; }
FetchRequest PreloadRequest::resourceRequest(Document* document) { ASSERT(isMainThread()); FetchInitiatorInfo initiatorInfo; initiatorInfo.name = AtomicString(m_initiatorName); initiatorInfo.position = m_initiatorPosition; FetchRequest request(ResourceRequest(completeURL(document)), initiatorInfo); if (m_isCORSEnabled) request.setCrossOriginAccessControl(document->securityOrigin(), m_allowCredentials); return request; }
// Helper for window.open() and window.showModalDialog() static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicFrame, Frame* openerFrame, const String& url, const String& frameName, const WindowFeatures& windowFeatures, JSValue dialogArgs) { ASSERT(lexicalFrame); ASSERT(dynamicFrame); ResourceRequest request; // For whatever reason, Firefox uses the dynamicGlobalObject to determine // the outgoingReferrer. We replicate that behavior here. String referrer = dynamicFrame->loader()->outgoingReferrer(); request.setHTTPReferrer(referrer); FrameLoader::addHTTPOriginIfNeeded(request, dynamicFrame->loader()->outgoingOrigin()); FrameLoadRequest frameRequest(request, frameName); // FIXME: It's much better for client API if a new window starts with a URL, here where we // know what URL we are going to open. Unfortunately, this code passes the empty string // for the URL, but there's a reason for that. Before loading we have to set up the opener, // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently // do an allowsAccessFrom call using the window we create, which can't be done before creating it. // We'd have to resolve all those issues to pass the URL instead of "". bool created; // We pass the opener frame for the lookupFrame in case the active frame is different from // the opener frame, and the name references a frame relative to the opener frame. Frame* newFrame = createWindow(lexicalFrame, openerFrame, frameRequest, windowFeatures, created); if (!newFrame) return 0; newFrame->loader()->setOpener(openerFrame); newFrame->page()->setOpenedByDOM(); // FIXME: If a window is created from an isolated world, what are the consequences of this? 'dialogArguments' only appears back in the normal world? JSDOMWindow* newWindow = toJSDOMWindow(newFrame, normalWorld(exec->globalData())); if (dialogArgs) newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs); if (!protocolIsJavaScript(url) || newWindow->allowsAccessFrom(exec)) { KURL completedURL = url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(exec, url); bool userGesture = processingUserGesture(); if (created) newFrame->loader()->changeLocation(completedURL, referrer, false, false, userGesture); else if (!url.isEmpty()) newFrame->redirectScheduler()->scheduleLocationChange(completedURL.string(), referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); } return newFrame; }
void JSLocation::setHref(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); KURL url = completeURL(exec, value.toString(exec)); if (url.isNull()) return; if (!shouldAllowNavigation(exec, frame)) return; navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); }
void V8DOMWindowShell::setLocation(DOMWindow* window, const String& relativeURL) { Frame* frame = window->frame(); if (!frame) return; KURL url = completeURL(relativeURL); if (url.isNull()) return; if (!shouldAllowNavigation(frame)) return; navigateIfAllowed(frame, url, false, false); }
StyleCachedShader* WebKitCSSShaderValue::cachedShader(CachedResourceLoader* loader) { ASSERT(loader); if (!m_accessedShader) { m_accessedShader = true; CachedResourceRequest request(ResourceRequest(completeURL(loader))); request.setInitiator(cachedResourceRequestInitiators().css); if (CachedResourceHandle<CachedShader> cachedShader = loader->requestShader(request)) m_shader = StyleCachedShader::create(cachedShader.get()); } return (m_shader && m_shader->isCachedShader()) ? static_cast<StyleCachedShader*>(m_shader.get()) : 0; }
JSValue JSLocation::replace(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); KURL url = completeURL(exec, args.at(0).toString(exec)); if (url.isNull()) return jsUndefined(); if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); navigateIfAllowed(exec, frame, url, true, true); return jsUndefined(); }
void WorkerContext::webkitResolveLocalFileSystemURL(const String& url, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) { KURL completedURL = completeURL(url); if (!AsyncFileSystem::isAvailable() || !securityOrigin()->canAccessFileSystem() || !securityOrigin()->canRequest(completedURL)) { DOMFileSystem::scheduleCallback(this, errorCallback, FileError::create(FileError::SECURITY_ERR)); return; } AsyncFileSystem::Type type; String filePath; if (!completedURL.isValid() || !DOMFileSystemBase::crackFileSystemURL(completedURL, type, filePath)) { DOMFileSystem::scheduleCallback(this, errorCallback, FileError::create(FileError::ENCODING_ERR)); return; } LocalFileSystem::localFileSystem().readFileSystem(this, type, ResolveURICallbacks::create(successCallback, errorCallback, this, filePath)); }
JSValue JSLocation::assign(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); KURL url = completeURL(exec, args.at(0).toString(exec)); if (url.isNull()) return jsUndefined(); if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); // We want a new history item if this JS was called via a user gesture navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); return jsUndefined(); }
bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage, int& lineNumber, int& columnNumber, String& sourceURL, Deprecated::ScriptValue& error, CachedScript* cachedScript) { ASSERT(securityOrigin()); if (cachedScript) { ASSERT(cachedScript->origin()); ASSERT(securityOrigin()->toString() == cachedScript->origin()->toString()); if (cachedScript->isCORSSameOrigin()) return false; } else if (securityOrigin()->canRequest(completeURL(sourceURL))) return false; errorMessage = "Script error."; sourceURL = String(); lineNumber = 0; columnNumber = 0; error = Deprecated::ScriptValue(); return true; }
bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage, int& lineNumber, int& columnNumber, String& sourceURL, JSC::Strong<JSC::Unknown>& error, CachedScript* cachedScript) { ASSERT(securityOrigin()); if (cachedScript) { ASSERT(cachedScript->origin()); ASSERT(securityOrigin()->toString() == cachedScript->origin()->toString()); if (cachedScript->isCORSSameOrigin()) return false; } else if (securityOrigin()->canRequest(completeURL(sourceURL))) return false; errorMessage = ASCIILiteral { "Script error." }; sourceURL = { }; lineNumber = 0; columnNumber = 0; error = { }; return true; }
void V8Location::hrefAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.Location.href._set"); v8::Handle<v8::Object> holder = info.Holder(); Location* imp = V8Location::toNative(holder); Frame* frame = imp->frame(); if (!frame) return; KURL url = completeURL(toWebCoreString(value)); if (url.isNull()) return; if (!shouldAllowNavigation(frame)) return; navigateIfAllowed(frame, url, false, false); }
v8::Handle<v8::Value> V8Location::assignCallback(const v8::Arguments& args) { INC_STATS("DOM.Location.assign"); v8::Handle<v8::Object> holder = args.Holder(); Location* imp = V8Location::toNative(holder); Frame* frame = imp->frame(); if (!frame) return v8::Undefined(); KURL url = completeURL(toWebCoreString(args[0])); if (url.isNull()) return v8::Undefined(); if (!shouldAllowNavigation(frame)) return v8::Undefined(); navigateIfAllowed(frame, url, false, false); return v8::Undefined(); }
KURL WorkerGlobalScope::virtualCompleteURL(const String& url) const { return completeURL(url); }
bool ExecutionContext::shouldSanitizeScriptError(const String& sourceURL, AccessControlStatus corsStatus) { return !(securityOrigin()->canRequest(completeURL(sourceURL)) || corsStatus == SharableCrossOrigin); }
void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header, LocalFrame* contextFrame) { ASSERT((m_executionContext && !contextFrame) || (equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::FrameAncestors) && contextFrame)); // FIXME: Support sending reports from worker. Document* document = contextFrame ? contextFrame->document() : this->document(); if (!document) return; LocalFrame* frame = document->frame(); if (!frame) return; SecurityPolicyViolationEventInit violationData; gatherSecurityPolicyViolationEventData(violationData, document, directiveText, effectiveDirective, blockedURL, header); frame->localDOMWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(EventTypeNames::securitypolicyviolation, violationData)); if (reportEndpoints.isEmpty()) return; // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded // resources should be allowed regardless. We apparently do, however, so // we should at least stop spamming reporting endpoints. See // https://crbug.com/524356 for detail. if (!violationData.sourceFile().isEmpty() && SchemeRegistry::schemeShouldBypassContentSecurityPolicy(KURL(ParsedURLString, violationData.sourceFile()).protocol())) return; // We need to be careful here when deciding what information to send to the // report-uri. Currently, we send only the current document's URL and the // directive that was violated. The document's URL is safe to send because // it's the document itself that's requesting that it be sent. You could // make an argument that we shouldn't send HTTPS document URLs to HTTP // report-uris (for the same reasons that we supress the Referer in that // case), but the Referer is sent implicitly whereas this request is only // sent explicitly. As for which directive was violated, that's pretty // harmless information. RefPtr<JSONObject> cspReport = JSONObject::create(); cspReport->setString("document-uri", violationData.documentURI()); cspReport->setString("referrer", violationData.referrer()); cspReport->setString("violated-directive", violationData.violatedDirective()); cspReport->setString("effective-directive", violationData.effectiveDirective()); cspReport->setString("original-policy", violationData.originalPolicy()); cspReport->setString("blocked-uri", violationData.blockedURI()); if (!violationData.sourceFile().isEmpty() && violationData.lineNumber()) { cspReport->setString("source-file", violationData.sourceFile()); cspReport->setNumber("line-number", violationData.lineNumber()); cspReport->setNumber("column-number", violationData.columnNumber()); } cspReport->setNumber("status-code", violationData.statusCode()); RefPtr<JSONObject> reportObject = JSONObject::create(); reportObject->setObject("csp-report", cspReport.release()); String stringifiedReport = reportObject->toJSONString(); if (!shouldSendViolationReport(stringifiedReport)) return; RefPtr<EncodedFormData> report = EncodedFormData::create(stringifiedReport.utf8()); for (const String& endpoint : reportEndpoints) { // If we have a context frame we're dealing with 'frame-ancestors' and we don't have our // own execution context. Use the frame's document to complete the endpoint URL, overriding // its URL with the blocked document's URL. ASSERT(!contextFrame || !m_executionContext); ASSERT(!contextFrame || equalIgnoringCase(effectiveDirective, FrameAncestors)); KURL url = contextFrame ? frame->document()->completeURLWithOverride(endpoint, blockedURL) : completeURL(endpoint); PingLoader::sendViolationReport(frame, url, report, PingLoader::ContentSecurityPolicyViolationReport); } didSendViolationReport(stringifiedReport); }
JSValue JSDOMWindow::open(ExecState* exec) { String urlString = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)); AtomicString frameName = exec->argument(1).isUndefinedOrNull() ? "_blank" : ustringToAtomicString(exec->argument(1).toString(exec)); WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2))); Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); Frame* lexicalFrame = toLexicalFrame(exec); if (!lexicalFrame) return jsUndefined(); Frame* dynamicFrame = toDynamicFrame(exec); if (!dynamicFrame) return jsUndefined(); Page* page = frame->page(); // Because FrameTree::find() returns true for empty strings, we must check for empty framenames. // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker. if (!domWindowAllowPopUp(dynamicFrame) && (frameName.isEmpty() || !frame->tree()->find(frameName))) return jsUndefined(); // Get the target frame for the special cases of _top and _parent. In those // cases, we can schedule a location change right now and return early. bool topOrParent = false; if (frameName == "_top") { frame = frame->tree()->top(); topOrParent = true; } else if (frameName == "_parent") { if (Frame* parent = frame->tree()->parent()) frame = parent; topOrParent = true; } if (topOrParent) { String completedURL; if (!urlString.isEmpty()) completedURL = completeURL(exec, urlString).string(); if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); const JSDOMWindow* targetedWindow = toJSDOMWindow(frame, currentWorld(exec)); if (!completedURL.isEmpty() && (!protocolIsJavaScript(completedURL) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) { bool userGesture = processingUserGesture(); // For whatever reason, Firefox uses the dynamicGlobalObject to // determine the outgoingReferrer. We replicate that behavior // here. String referrer = dynamicFrame->loader()->outgoingReferrer(); frame->redirectScheduler()->scheduleLocationChange(completedURL, referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); } return toJS(exec, frame->domWindow()); } // In the case of a named frame or a new window, we'll use the createWindow() helper FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0, windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0); DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect); windowFeatures.x = windowRect.x(); windowFeatures.y = windowRect.y(); windowFeatures.height = windowRect.height(); windowFeatures.width = windowRect.width(); frame = createWindow(exec, lexicalFrame, dynamicFrame, frame, urlString, frameName, windowFeatures, JSValue()); if (!frame) return jsUndefined(); return toJS(exec, frame->domWindow()); }
KURL completeURL(const String& relativeURL) { return completeURL(V8BindingState::Only(), relativeURL); }
KURL WorkerContext::virtualCompleteURL(const String& url) const { return completeURL(url); }