bool HTMLPlugInElement::allowedToLoadObject(const KURL& url, const String& mimeType) { if (url.isEmpty() && mimeType.isEmpty()) return false; LocalFrame* frame = document().frame(); Settings* settings = frame->settings(); if (!settings) return false; if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) return false; if (!document().getSecurityOrigin()->canDisplay(url)) { FrameLoader::reportLocalLoadFailed(frame, url.getString()); return false; } AtomicString declaredMimeType = document().isPluginDocument() && document().localOwner() ? document().localOwner()->fastGetAttribute(HTMLNames::typeAttr) : fastGetAttribute(HTMLNames::typeAttr); if (!document().contentSecurityPolicy()->allowObjectFromSource(url) || !document().contentSecurityPolicy()->allowPluginTypeForDocument(document(), mimeType, declaredMimeType, url)) { layoutEmbeddedItem().setPluginUnavailabilityReason(LayoutEmbeddedObject::PluginBlockedByContentSecurityPolicy); return false; } // If the URL is empty, a plugin could still be instantiated if a MIME-type // is specified. return (!mimeType.isEmpty() && url.isEmpty()) || !MixedContentChecker::shouldBlockFetch(frame, WebURLRequest::RequestContextObject, WebURLRequest::FrameTypeNone, url); }
static void preconnectIfNeeded( const LinkRelAttribute& relAttribute, const KURL& href, Document& document, const CrossOriginAttributeValue crossOrigin, const NetworkHintsInterface& networkHintsInterface, LinkCaller caller) { if (relAttribute.isPreconnect() && href.isValid() && href.protocolIsInHTTPFamily()) { UseCounter::count(document, UseCounter::LinkRelPreconnect); if (caller == LinkCalledFromHeader) UseCounter::count(document, UseCounter::LinkHeaderPreconnect); Settings* settings = document.settings(); if (settings && settings->logDnsPrefetchAndPreconnect()) { document.addConsoleMessage(ConsoleMessage::create( OtherMessageSource, DebugMessageLevel, String("Preconnect triggered for ") + href.getString())); if (crossOrigin != CrossOriginAttributeNotSet) { document.addConsoleMessage(ConsoleMessage::create( OtherMessageSource, DebugMessageLevel, String("Preconnect CORS setting is ") + String((crossOrigin == CrossOriginAttributeAnonymous) ? "anonymous" : "use-credentials"))); } } networkHintsInterface.preconnectHost(href, crossOrigin); } }
void LocalFrame::navigate(Document& originDocument, const KURL& url, bool replaceCurrentItem, UserGestureStatus userGestureStatus) { m_navigationScheduler->scheduleLocationChange( &originDocument, url.getString(), replaceCurrentItem); }
void CustomContextMenuProvider::appendMenuItem(HTMLMenuItemElement* menuItem, ContextMenu& contextMenu) { // Avoid menuitems with no label. String labelString = menuItem->fastGetAttribute(labelAttr); if (labelString.isEmpty()) return; m_menuItems.append(menuItem); bool enabled = !menuItem->fastHasAttribute(disabledAttr); String icon = menuItem->fastGetAttribute(iconAttr); if (!icon.isEmpty()) { // To obtain the absolute URL of the icon when the attribute's value is not // the empty string, the attribute's value must be resolved relative to the // element. KURL iconURL = KURL(menuItem->baseURI(), icon); icon = iconURL.getString(); } ContextMenuAction action = static_cast<ContextMenuAction>( ContextMenuItemBaseCustomTag + m_menuItems.size() - 1); if (equalIgnoringCase(menuItem->fastGetAttribute(typeAttr), "checkbox") || equalIgnoringCase(menuItem->fastGetAttribute(typeAttr), "radio")) contextMenu.appendItem( ContextMenuItem(CheckableActionType, action, labelString, icon, enabled, menuItem->fastHasAttribute(checkedAttr))); else contextMenu.appendItem( ContextMenuItem(ActionType, action, labelString, icon, enabled, false)); }
String BlobURL::getOrigin(const KURL& url) { ASSERT(url.protocolIs(kBlobProtocol)); unsigned startIndex = url.pathStart(); unsigned endIndex = url.pathAfterLastSlash(); return url.getString().substring(startIndex, endIndex - startIndex - 1); }
void KURL::init(const KURL& base, const CHAR* relative, int relativeLength, const WTF::TextEncoding* queryEncoding) { // As a performance optimization, we do not use the charset converter // if encoding is UTF-8 or other Unicode encodings. Note that this is // per HTML5 2.5.3 (resolving URL). The URL canonicalizer will be more // efficient with no charset converter object because it can do UTF-8 // internally with no extra copies. // We feel free to make the charset converter object every time since it's // just a wrapper around a reference. KURLCharsetConverter charsetConverterObject(queryEncoding); KURLCharsetConverter* charsetConverter = (!queryEncoding || isUnicodeEncoding(queryEncoding)) ? 0 : &charsetConverterObject; StringUTF8Adaptor baseUTF8(base.getString()); url::RawCanonOutputT<char> output; m_isValid = url::ResolveRelative(baseUTF8.data(), baseUTF8.length(), base.m_parsed, relative, relativeLength, charsetConverter, &output, &m_parsed); // See FIXME in KURLPrivate in the header. If canonicalization has not // changed the string, we can avoid an extra allocation by using assignment. m_string = AtomicString::fromUTF8(output.data(), output.length()); }
bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireLayoutObject) { if (!allowedToLoadPlugin(url, mimeType)) return false; LocalFrame* frame = document().frame(); if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) return false; LayoutEmbeddedItem layoutItem = layoutEmbeddedItem(); // FIXME: This code should not depend on layoutObject! if ((layoutItem.isNull() && requireLayoutObject) || useFallback) return false; VLOG(1) << this << " Plugin URL: " << m_url; VLOG(1) << "Loaded URL: " << url.getString(); m_loadedUrl = url; if (m_persistedPluginWidget) { setWidget(m_persistedPluginWidget.release()); } else { bool loadManually = document().isPluginDocument() && !document().containsPlugins(); FrameLoaderClient::DetachedPluginPolicy policy = requireLayoutObject ? FrameLoaderClient::FailOnDetachedPlugin : FrameLoaderClient::AllowDetachedPlugin; Widget* widget = frame->loader().client()->createPlugin( this, url, paramNames, paramValues, mimeType, loadManually, policy); if (!widget) { if (!layoutItem.isNull() && !layoutItem.showsUnavailablePluginIndicator()) { m_pluginIsAvailable = false; layoutItem.setPluginAvailability(LayoutEmbeddedObject::PluginMissing); } return false; } if (!layoutItem.isNull()) setWidget(widget); else setPersistedPluginWidget(widget); } document().setContainsPlugins(); // TODO(esprehn): WebPluginContainerImpl::setWebLayer also schedules a // compositing update, do we need both? setNeedsCompositingUpdate(); // Make sure any input event handlers introduced by the plugin are taken into // account. if (Page* page = document().frame()->page()) { if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) scrollingCoordinator->notifyGeometryChanged(); } return true; }
static void saveToOriginMap(SecurityOrigin* origin, const KURL& url) { // If the blob URL contains null origin, as in the context with unique // security origin or file URL, save the mapping between url and origin so // that the origin can be retrived when doing security origin check. if (origin && BlobURL::getOrigin(url) == "null") originMap()->add(url.getString(), origin); }
CSSImageValue::CSSImageValue(const AtomicString& rawValue, const KURL& url, StyleImage* image) : CSSValue(ImageClass) , m_relativeURL(rawValue) , m_absoluteURL(url.getString()) , m_isCachePending(!image) , m_cachedImage(image) { }
void MediaSourceRegistry::registerURL(SecurityOrigin*, const KURL& url, URLRegistrable* registrable) { DCHECK_EQ(®istrable->registry(), this); DCHECK(isMainThread()); MediaSource* source = static_cast<MediaSource*>(registrable); source->addedToRegistry(); m_mediaSources.set(url.getString(), source); }
void KURL::init(const KURL& base, const String& relative, const WTF::TextEncoding* queryEncoding) { // As a performance optimization, we do not use the charset converter // if encoding is UTF-8 or other Unicode encodings. Note that this is // per HTML5 2.5.3 (resolving URL). The URL canonicalizer will be more // efficient with no charset converter object because it can do UTF-8 // internally with no extra copies. StringUTF8Adaptor baseUTF8(base.getString()); // We feel free to make the charset converter object every time since it's // just a wrapper around a reference. KURLCharsetConverter charsetConverterObject(queryEncoding); KURLCharsetConverter* charsetConverter = (!queryEncoding || isUnicodeEncoding(queryEncoding)) ? 0 : &charsetConverterObject; // Clamp to int max to avoid overflow. url::RawCanonOutputT<char> output; if (!relative.isNull() && relative.is8Bit()) { StringUTF8Adaptor relativeUTF8(relative); m_isValid = url::ResolveRelative(baseUTF8.data(), baseUTF8.length(), base.m_parsed, relativeUTF8.data(), clampTo<int>(relativeUTF8.length()), charsetConverter, &output, &m_parsed); } else { m_isValid = url::ResolveRelative(baseUTF8.data(), baseUTF8.length(), base.m_parsed, relative.characters16(), clampTo<int>(relative.length()), charsetConverter, &output, &m_parsed); } // AtomicString::fromUTF8 will re-hash the raw output and check the // AtomicStringTable (addWithTranslator) for the string. This can be very // expensive for large URLs. However, since many URLs are generated from // existing AtomicStrings (which already have their hashes computed), this // fast path is used if the input string is already canonicalized. // // Because this optimization does not apply to non-AtomicStrings, explicitly // check that the input is Atomic before moving forward with it. If we mark // non-Atomic input as Atomic here, we will render the (const) input string // thread unsafe. if (!relative.isNull() && relative.impl()->isAtomic() && StringView(output.data(), static_cast<unsigned>(output.length())) == relative) { m_string = relative; } else { m_string = AtomicString::fromUTF8(output.data(), output.length()); } initProtocolIsInHTTPFamily(); initInnerURL(); DCHECK_EQ(protocol(), protocol().lower()); }
// TODO(schenney): crbug.com/572908 This should be unified with // HTMLEmbedElement::updateWidget and moved down into HTMLPluginElement.cpp void HTMLObjectElement::updateWidgetInternal() { DCHECK(!layoutEmbeddedItem().showsUnavailablePluginIndicator()); DCHECK(needsWidgetUpdate()); setNeedsWidgetUpdate(false); // TODO(schenney): crbug.com/572908 This should ASSERT // isFinishedParsingChildren() instead. if (!isFinishedParsingChildren()) { dispatchErrorEvent(); return; } // TODO(schenney): crbug.com/572908 I'm not sure it's ever possible to get // into updateWidget during a removal, but just in case we should avoid // loading the frame to prevent security bugs. if (!SubframeLoadingDisabler::canLoadFrame(*this)) { dispatchErrorEvent(); return; } String url = this->url(); String serviceType = m_serviceType; // TODO(schenney): crbug.com/572908 These should be joined into a // PluginParameters class. Vector<String> paramNames; Vector<String> paramValues; parametersForPlugin(paramNames, paramValues, url, serviceType); // Note: url is modified above by parametersForPlugin. if (!allowedToLoadFrameURL(url)) { dispatchErrorEvent(); return; } // TODO(schenney): crbug.com/572908 Is it possible to get here without a // layoutObject now that we don't have beforeload events? if (!layoutObject()) return; // Overwrites the URL and MIME type of a Flash embed to use an HTML5 embed. KURL overridenUrl = document().frame()->loader().client()->overrideFlashEmbedWithHTML( document().completeURL(m_url)); if (!overridenUrl.isEmpty()) { url = m_url = overridenUrl.getString(); serviceType = m_serviceType = "text/html"; } if (!hasValidClassId() || !requestObject(url, serviceType, paramNames, paramValues)) { if (!url.isEmpty()) dispatchErrorEvent(); if (hasFallbackContent()) renderFallbackContent(); } }
static std::unique_ptr<TracedValue> loadResourceTraceData(unsigned long identifier, const KURL& url, int priority) { String requestId = IdentifiersFactory::requestId(identifier); std::unique_ptr<TracedValue> value = TracedValue::create(); value->setString("requestId", requestId); value->setString("url", url.getString()); value->setInteger("priority", priority); return value; }
void CSSImageValue::reResolveURL(const Document& document) const { KURL url = document.completeURL(m_relativeURL); AtomicString urlString(url.getString()); if (urlString == m_absoluteURL) return; m_absoluteURL = urlString; m_isCachePending = true; m_cachedImage.clear(); }
void DataTransfer::writeURL(Node* node, const KURL& url, const String& title) { if (!m_dataObject) return; ASSERT(!url.isEmpty()); m_dataObject->setURLAndTitle(url, title); // The URL can also be used as plain text. m_dataObject->setData(mimeTypeTextPlain, url.getString()); // The URL can also be used as an HTML fragment. m_dataObject->setHTMLAndBaseURL( createMarkup(node, IncludeNode, ResolveAllURLs), url); }
void MediaElementAudioSourceHandler::onCurrentSrcChanged( const KURL& currentSrc) { DCHECK(isMainThread()); // Synchronize with process(). Locker<MediaElementAudioSourceHandler> locker(*this); m_passesCurrentSrcCORSAccessCheck = passesCurrentSrcCORSAccessCheck(currentSrc); // Make a note if we need to print a console message and save the |curentSrc| // for use in the message. Need to wait until later to print the message in // case HTMLMediaElement allows access. m_maybePrintCORSMessage = !m_passesCurrentSrcCORSAccessCheck; m_currentSrcString = currentSrc.getString(); }
void HTMLAnchorElement::setURL(const KURL& url) { setHref(AtomicString(url.getString())); }
static void removeFromOriginMap(const KURL& url) { if (BlobURL::getOrigin(url) == "null") originMap()->remove(url.getString()); }
void MediaSourceRegistry::unregisterURL(const KURL& url) { DCHECK(isMainThread()); PersistentHeapHashMap<String, Member<MediaSource>>::iterator iter = m_mediaSources.find(url.getString()); if (iter == m_mediaSources.end()) return; MediaSource* source = iter->value; m_mediaSources.remove(iter); source->removedFromRegistry(); }
void HistoryItem::setURL(const KURL& url) { setURLString(url.getString()); }
DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame) { LocalFrame* activeFrame = callingWindow.frame(); ASSERT(activeFrame); KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString()) : firstFrame.document()->completeURL(urlString); if (!completedURL.isEmpty() && !completedURL.isValid()) { // Don't expose client code to invalid URLs. callingWindow.printErrorMessage("Unable to open a window with invalid URL '" + completedURL.getString() + "'.\n"); return nullptr; } FrameLoadRequest frameRequest(callingWindow.document(), completedURL, frameName); frameRequest.setShouldSetOpener(windowFeatures.noopener ? NeverSetOpener : MaybeSetOpener); frameRequest.resourceRequest().setFrameType(WebURLRequest::FrameTypeAuxiliary); frameRequest.resourceRequest().setRequestorOrigin(SecurityOrigin::create(activeFrame->document()->url())); // Normally, FrameLoader would take care of setting the referrer for a navigation that is // triggered from javascript. However, creating a window goes through sufficient processing // that it eventually enters FrameLoader as an embedder-initiated navigation. FrameLoader // assumes no responsibility for generating an embedder-initiated navigation's referrer, // so we need to ensure the proper referrer is set now. frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateReferrer(activeFrame->document()->getReferrerPolicy(), completedURL, activeFrame->document()->outgoingReferrer())); // Records HasUserGesture before the value is invalidated inside createWindow(LocalFrame& openerFrame, ...). // This value will be set in ResourceRequest loaded in a new LocalFrame. bool hasUserGesture = UserGestureIndicator::processingUserGesture(); // 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. bool created; Frame* newFrame = createWindowHelper(openerFrame, *activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, created); if (!newFrame) return nullptr; if (newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL)) return newFrame->domWindow(); // TODO(dcheng): Special case for window.open("about:blank") to ensure it loads synchronously into // a new window. This is our historical behavior, and it's consistent with the creation of // a new iframe with src="about:blank". Perhaps we could get rid of this if we started reporting // the initial empty document's url as about:blank? See crbug.com/471239. // TODO(japhet): This special case is also necessary for behavior asserted by some extensions tests. // Using NavigationScheduler::scheduleNavigationChange causes the navigation to be flagged as a // client redirect, which is observable via the webNavigation extension api. if (created) { FrameLoadRequest request(callingWindow.document(), completedURL); request.resourceRequest().setHasUserGesture(hasUserGesture); newFrame->navigate(request); } else if (!urlString.isEmpty()) { newFrame->navigate(*callingWindow.document(), completedURL, false, hasUserGesture ? UserGestureStatus::Active : UserGestureStatus::None); } return newFrame->domWindow(); }