| OLD | NEW |
| 1 /** | 1 /** |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de) | 4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de) |
| 5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. | 5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "core/dom/shadow/ShadowRoot.h" | 31 #include "core/dom/shadow/ShadowRoot.h" |
| 32 #include "core/events/Event.h" | 32 #include "core/events/Event.h" |
| 33 #include "core/frame/FrameView.h" | 33 #include "core/frame/FrameView.h" |
| 34 #include "core/frame/LocalFrame.h" | 34 #include "core/frame/LocalFrame.h" |
| 35 #include "core/frame/Settings.h" | 35 #include "core/frame/Settings.h" |
| 36 #include "core/frame/csp/ContentSecurityPolicy.h" | 36 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 37 #include "core/html/HTMLContentElement.h" | 37 #include "core/html/HTMLContentElement.h" |
| 38 #include "core/html/HTMLImageLoader.h" | 38 #include "core/html/HTMLImageLoader.h" |
| 39 #include "core/html/PluginDocument.h" | 39 #include "core/html/PluginDocument.h" |
| 40 #include "core/input/EventHandler.h" | 40 #include "core/input/EventHandler.h" |
| 41 #include "core/inspector/ConsoleMessage.h" |
| 41 #include "core/layout/LayoutBlockFlow.h" | 42 #include "core/layout/LayoutBlockFlow.h" |
| 42 #include "core/layout/LayoutEmbeddedObject.h" | 43 #include "core/layout/LayoutEmbeddedObject.h" |
| 43 #include "core/layout/LayoutImage.h" | 44 #include "core/layout/LayoutImage.h" |
| 44 #include "core/layout/LayoutPart.h" | 45 #include "core/layout/LayoutPart.h" |
| 45 #include "core/loader/FrameLoaderClient.h" | 46 #include "core/loader/FrameLoaderClient.h" |
| 46 #include "core/loader/MixedContentChecker.h" | 47 #include "core/loader/MixedContentChecker.h" |
| 47 #include "core/page/Page.h" | 48 #include "core/page/Page.h" |
| 48 #include "core/page/scrolling/ScrollingCoordinator.h" | 49 #include "core/page/scrolling/ScrollingCoordinator.h" |
| 49 #include "core/plugins/PluginView.h" | 50 #include "core/plugins/PluginView.h" |
| 50 #include "platform/Logging.h" | 51 #include "platform/Logging.h" |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 return; | 199 return; |
| 199 | 200 |
| 200 createPluginWithoutLayoutObject(); | 201 createPluginWithoutLayoutObject(); |
| 201 } | 202 } |
| 202 | 203 |
| 203 void HTMLPlugInElement::createPluginWithoutLayoutObject() | 204 void HTMLPlugInElement::createPluginWithoutLayoutObject() |
| 204 { | 205 { |
| 205 ASSERT(document().frame()->loader().client()->canCreatePluginWithoutRenderer
(m_serviceType)); | 206 ASSERT(document().frame()->loader().client()->canCreatePluginWithoutRenderer
(m_serviceType)); |
| 206 | 207 |
| 207 KURL url; | 208 KURL url; |
| 209 // CSP can block src-less objects. |
| 210 if (!allowedToLoadObject(url, m_serviceType)) |
| 211 return; |
| 212 |
| 208 Vector<String> paramNames; | 213 Vector<String> paramNames; |
| 209 Vector<String> paramValues; | 214 Vector<String> paramValues; |
| 210 | 215 |
| 211 paramNames.append("type"); | 216 paramNames.append("type"); |
| 212 paramValues.append(m_serviceType); | 217 paramValues.append(m_serviceType); |
| 213 | 218 |
| 214 bool useFallback = false; | 219 bool useFallback = false; |
| 215 loadPlugin(url, m_serviceType, paramNames, paramValues, useFallback, false); | 220 loadPlugin(url, m_serviceType, paramNames, paramValues, useFallback, false); |
| 216 } | 221 } |
| 217 | 222 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 | 472 |
| 468 bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
const Vector<String>& paramNames, const Vector<String>& paramValues) | 473 bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
const Vector<String>& paramNames, const Vector<String>& paramValues) |
| 469 { | 474 { |
| 470 if (url.isEmpty() && mimeType.isEmpty()) | 475 if (url.isEmpty() && mimeType.isEmpty()) |
| 471 return false; | 476 return false; |
| 472 | 477 |
| 473 if (protocolIsJavaScript(url)) | 478 if (protocolIsJavaScript(url)) |
| 474 return false; | 479 return false; |
| 475 | 480 |
| 476 KURL completedURL = url.isEmpty() ? KURL() : document().completeURL(url); | 481 KURL completedURL = url.isEmpty() ? KURL() : document().completeURL(url); |
| 477 if (!pluginIsLoadable(completedURL, mimeType)) | 482 if (!allowedToLoadObject(completedURL, mimeType)) |
| 478 return false; | 483 return false; |
| 479 | 484 |
| 480 bool useFallback; | 485 bool useFallback; |
| 481 if (shouldUsePlugin(completedURL, mimeType, hasFallbackContent(), useFallbac
k)) | 486 if (!shouldUsePlugin(completedURL, mimeType, hasFallbackContent(), useFallba
ck)) { |
| 482 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFa
llback, true); | 487 // If the plugin element already contains a subframe, |
| 488 // loadOrRedirectSubframe will re-use it. Otherwise, it will create a |
| 489 // new frame and set it as the LayoutPart's widget, causing what was |
| 490 // previously in the widget to be torn down. |
| 491 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true); |
| 492 } |
| 483 | 493 |
| 484 // If the plugin element already contains a subframe, | 494 return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFallba
ck, true); |
| 485 // loadOrRedirectSubframe will re-use it. Otherwise, it will create a new | |
| 486 // frame and set it as the LayoutPart's widget, causing what was previously | |
| 487 // in the widget to be torn down. | |
| 488 return loadOrRedirectSubframe(completedURL, getNameAttribute(), true); | |
| 489 } | 495 } |
| 490 | 496 |
| 491 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons
t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac
k, bool requireLayoutObject) | 497 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, cons
t Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallbac
k, bool requireLayoutObject) |
| 492 { | 498 { |
| 499 if (!allowedToLoadPlugin(url, mimeType)) |
| 500 return false; |
| 501 |
| 493 LocalFrame* frame = document().frame(); | 502 LocalFrame* frame = document().frame(); |
| 494 | |
| 495 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) | 503 if (!frame->loader().allowPlugins(AboutToInstantiatePlugin)) |
| 496 return false; | 504 return false; |
| 497 | 505 |
| 498 LayoutEmbeddedObject* layoutObject = layoutEmbeddedObject(); | 506 LayoutEmbeddedObject* layoutObject = layoutEmbeddedObject(); |
| 499 // FIXME: This code should not depend on layoutObject! | 507 // FIXME: This code should not depend on layoutObject! |
| 500 if ((!layoutObject && requireLayoutObject) || useFallback) | 508 if ((!layoutObject && requireLayoutObject) || useFallback) |
| 501 return false; | 509 return false; |
| 502 | 510 |
| 503 WTF_LOG(Plugins, "%p Plugin URL: %s", this, m_url.utf8().data()); | 511 WTF_LOG(Plugins, "%p Plugin URL: %s", this, m_url.utf8().data()); |
| 504 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); | 512 WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 534 } | 542 } |
| 535 | 543 |
| 536 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
bool hasFallback, bool& useFallback) | 544 bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
bool hasFallback, bool& useFallback) |
| 537 { | 545 { |
| 538 // Allow other plugins to win over QuickTime because if the user has | 546 // Allow other plugins to win over QuickTime because if the user has |
| 539 // installed a plugin that can handle TIFF (which QuickTime can also | 547 // installed a plugin that can handle TIFF (which QuickTime can also |
| 540 // handle) they probably intended to override QT. | 548 // handle) they probably intended to override QT. |
| 541 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == "
image/tif" || mimeType == "image/x-tiff")) { | 549 if (document().frame()->page() && (mimeType == "image/tiff" || mimeType == "
image/tif" || mimeType == "image/x-tiff")) { |
| 542 const PluginData* pluginData = document().frame()->page()->pluginData(); | 550 const PluginData* pluginData = document().frame()->page()->pluginData(); |
| 543 String pluginName = pluginData ? pluginData->pluginNameForMimeType(mimeT
ype) : String(); | 551 String pluginName = pluginData ? pluginData->pluginNameForMimeType(mimeT
ype) : String(); |
| 544 if (!pluginName.isEmpty() && !pluginName.contains("QuickTime", TextCaseI
nsensitive)) | 552 if (!pluginName.isEmpty() && !pluginName.contains("QuickTime", TextCaseI
nsensitive)) { |
| 553 useFallback = false; |
| 545 return true; | 554 return true; |
| 555 } |
| 546 } | 556 } |
| 547 | 557 |
| 548 ObjectContentType objectType = document().frame()->loader().client()->object
ContentType(url, mimeType, shouldPreferPlugInsForImages()); | 558 ObjectContentType objectType = document().frame()->loader().client()->object
ContentType(url, mimeType, shouldPreferPlugInsForImages()); |
| 549 // If an object's content can't be handled and it has no fallback, let | 559 // If an object's content can't be handled and it has no fallback, let |
| 550 // it be handled as a plugin to show the broken plugin icon. | 560 // it be handled as a plugin to show the broken plugin icon. |
| 551 useFallback = objectType == ObjectContentNone && hasFallback; | 561 useFallback = objectType == ObjectContentNone && hasFallback; |
| 552 return objectType == ObjectContentNone || objectType == ObjectContentNetscap
ePlugin || objectType == ObjectContentOtherPlugin; | 562 return objectType == ObjectContentNone || objectType == ObjectContentNetscap
ePlugin || objectType == ObjectContentOtherPlugin; |
| 553 | 563 |
| 554 } | 564 } |
| 555 | 565 |
| 556 void HTMLPlugInElement::dispatchErrorEvent() | 566 void HTMLPlugInElement::dispatchErrorEvent() |
| 557 { | 567 { |
| 558 if (document().isPluginDocument() && document().ownerElement()) | 568 if (document().isPluginDocument() && document().ownerElement()) |
| 559 document().ownerElement()->dispatchEvent(Event::create(EventTypeNames::e
rror)); | 569 document().ownerElement()->dispatchEvent(Event::create(EventTypeNames::e
rror)); |
| 560 else | 570 else |
| 561 dispatchEvent(Event::create(EventTypeNames::error)); | 571 dispatchEvent(Event::create(EventTypeNames::error)); |
| 562 } | 572 } |
| 563 | 573 |
| 564 bool HTMLPlugInElement::pluginIsLoadable(const KURL& url, const String& mimeType
) | 574 bool HTMLPlugInElement::allowedToLoadObject(const KURL& url, const String& mimeT
ype) |
| 565 { | 575 { |
| 566 if (url.isEmpty() && mimeType.isEmpty()) | 576 if (url.isEmpty() && mimeType.isEmpty()) |
| 567 return false; | 577 return false; |
| 568 | 578 |
| 569 LocalFrame* frame = document().frame(); | 579 LocalFrame* frame = document().frame(); |
| 570 Settings* settings = frame->settings(); | 580 Settings* settings = frame->settings(); |
| 571 if (!settings) | 581 if (!settings) |
| 572 return false; | 582 return false; |
| 573 | 583 |
| 574 if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) | 584 if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) |
| 575 return false; | 585 return false; |
| 576 | 586 |
| 577 if (document().isSandboxed(SandboxPlugins)) | |
| 578 return false; | |
| 579 | |
| 580 if (!document().securityOrigin()->canDisplay(url)) { | 587 if (!document().securityOrigin()->canDisplay(url)) { |
| 581 FrameLoader::reportLocalLoadFailed(frame, url.string()); | 588 FrameLoader::reportLocalLoadFailed(frame, url.string()); |
| 582 return false; | 589 return false; |
| 583 } | 590 } |
| 584 | 591 |
| 585 AtomicString declaredMimeType = document().isPluginDocument() && document().
ownerElement() ? | 592 AtomicString declaredMimeType = document().isPluginDocument() && document().
ownerElement() ? |
| 586 document().ownerElement()->fastGetAttribute(HTMLNames::typeAttr) : | 593 document().ownerElement()->fastGetAttribute(HTMLNames::typeAttr) : |
| 587 fastGetAttribute(HTMLNames::typeAttr); | 594 fastGetAttribute(HTMLNames::typeAttr); |
| 588 if (!document().contentSecurityPolicy()->allowObjectFromSource(url) | 595 if (!document().contentSecurityPolicy()->allowObjectFromSource(url) |
| 589 || !document().contentSecurityPolicy()->allowPluginTypeForDocument(docum
ent(), mimeType, declaredMimeType, url)) { | 596 || !document().contentSecurityPolicy()->allowPluginTypeForDocument(docum
ent(), mimeType, declaredMimeType, url)) { |
| 590 layoutEmbeddedObject()->setPluginUnavailabilityReason(LayoutEmbeddedObje
ct::PluginBlockedByContentSecurityPolicy); | 597 layoutEmbeddedObject()->setPluginUnavailabilityReason(LayoutEmbeddedObje
ct::PluginBlockedByContentSecurityPolicy); |
| 591 return false; | 598 return false; |
| 592 } | 599 } |
| 600 // If the URL is empty, a plugin could still be instantiated if a MIME-type |
| 601 // is specified. |
| 602 return (!mimeType.isEmpty() && url.isEmpty()) || !MixedContentChecker::shoul
dBlockFetch(frame, WebURLRequest::RequestContextObject, WebURLRequest::FrameType
None, url); |
| 603 } |
| 593 | 604 |
| 594 return (!mimeType.isEmpty() && url.isEmpty()) || !MixedContentChecker::shoul
dBlockFetch(frame, WebURLRequest::RequestContextObject, WebURLRequest::FrameType
None, url); | 605 bool HTMLPlugInElement::allowedToLoadPlugin(const KURL& url, const String& mimeT
ype) |
| 606 { |
| 607 if (document().isSandboxed(SandboxPlugins)) { |
| 608 document().addConsoleMessage(ConsoleMessage::create(SecurityMessageSourc
e, ErrorMessageLevel, |
| 609 "Failed to load '" + url.elidedString() + "' as a plugin, because th
e frame into which the plugin is loading is sandboxed.")); |
| 610 return false; |
| 611 } |
| 612 return true; |
| 595 } | 613 } |
| 596 | 614 |
| 597 void HTMLPlugInElement::didAddUserAgentShadowRoot(ShadowRoot&) | 615 void HTMLPlugInElement::didAddUserAgentShadowRoot(ShadowRoot&) |
| 598 { | 616 { |
| 599 userAgentShadowRoot()->appendChild(HTMLContentElement::create(document())); | 617 userAgentShadowRoot()->appendChild(HTMLContentElement::create(document())); |
| 600 } | 618 } |
| 601 | 619 |
| 602 void HTMLPlugInElement::willAddFirstAuthorShadowRoot() | 620 void HTMLPlugInElement::willAddFirstAuthorShadowRoot() |
| 603 { | 621 { |
| 604 lazyReattachIfAttached(); | 622 lazyReattachIfAttached(); |
| 605 } | 623 } |
| 606 | 624 |
| 607 bool HTMLPlugInElement::hasFallbackContent() const | 625 bool HTMLPlugInElement::hasFallbackContent() const |
| 608 { | 626 { |
| 609 return false; | 627 return false; |
| 610 } | 628 } |
| 611 | 629 |
| 612 bool HTMLPlugInElement::useFallbackContent() const | 630 bool HTMLPlugInElement::useFallbackContent() const |
| 613 { | 631 { |
| 614 return openShadowRoot(); | 632 return openShadowRoot(); |
| 615 } | 633 } |
| 616 | 634 |
| 617 void HTMLPlugInElement::lazyReattachIfNeeded() | 635 void HTMLPlugInElement::lazyReattachIfNeeded() |
| 618 { | 636 { |
| 619 if (!useFallbackContent() && needsWidgetUpdate() && layoutObject() && !isIma
geType()) | 637 if (!useFallbackContent() && needsWidgetUpdate() && layoutObject() && !isIma
geType()) |
| 620 lazyReattachIfAttached(); | 638 lazyReattachIfAttached(); |
| 621 } | 639 } |
| 622 | 640 |
| 623 } // namespace blink | 641 } // namespace blink |
| OLD | NEW |