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 |