Example #1
0
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);
}
Example #2
0
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);
  }
}
Example #3
0
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));
}
Example #5
0
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);
}
Example #6
0
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());
}
Example #7
0
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(&registrable->registry(), this);
    DCHECK(isMainThread());

    MediaSource* source = static_cast<MediaSource*>(registrable);
    source->addedToRegistry();
    m_mediaSources.set(url.getString(), source);
}
Example #11
0
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());
}
Example #12
0
// 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();
}
Example #15
0
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);
}
Example #16
0
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();
}
Example #20
0
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();
}