nsPluginArray.cpp (5319B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "nsPluginArray.h" 8 9 #include "mozilla/StaticPrefs_pdfjs.h" 10 #include "mozilla/dom/PluginArrayBinding.h" 11 #include "mozilla/dom/PluginBinding.h" 12 #include "nsContentUtils.h" 13 #include "nsMimeTypeArray.h" 14 #include "nsPIDOMWindow.h" 15 16 using namespace mozilla; 17 using namespace mozilla::dom; 18 19 // These plugin and mime types are hard-coded by the HTML spec. 20 // The "main" plugin name is used with the only plugin that is 21 // referenced by MIME types (via nsMimeType::GetEnabledPlugin). 22 // The "extra" of the plugin names are associated with MIME types that 23 // reference the main plugin. 24 // This is all defined in the HTML spec, section 8.9.1.6 25 // "PDF Viewing Support". 26 static const nsLiteralString kMainPluginName = u"PDF Viewer"_ns; 27 static const nsLiteralString kExtraPluginNames[] = { 28 u"Chrome PDF Viewer"_ns, u"Chromium PDF Viewer"_ns, 29 u"Microsoft Edge PDF Viewer"_ns, u"WebKit built-in PDF"_ns}; 30 static const nsLiteralString kMimeTypeNames[] = {u"application/pdf"_ns, 31 u"text/pdf"_ns}; 32 33 nsPluginArray::nsPluginArray(nsPIDOMWindowInner* aWindow) : mWindow(aWindow) { 34 // Create the hard-coded PDF plugin types that share MIME type arrays. 35 mPlugins[0] = MakeRefPtr<nsPluginElement>(this, aWindow, kMainPluginName); 36 37 mozilla::Array<RefPtr<nsMimeType>, 2> mimeTypes; 38 for (uint32_t i = 0; i < std::size(kMimeTypeNames); ++i) { 39 mimeTypes[i] = MakeRefPtr<nsMimeType>(mPlugins[0], kMimeTypeNames[i]); 40 } 41 mMimeTypeArray = MakeRefPtr<nsMimeTypeArray>(aWindow, mimeTypes); 42 43 for (uint32_t i = 0; i < std::size(kExtraPluginNames); ++i) { 44 mPlugins[i + 1] = 45 MakeRefPtr<nsPluginElement>(this, aWindow, kExtraPluginNames[i]); 46 } 47 } 48 49 nsPluginArray::~nsPluginArray() = default; 50 51 nsPIDOMWindowInner* nsPluginArray::GetParentObject() const { 52 MOZ_ASSERT(mWindow); 53 return mWindow; 54 } 55 56 JSObject* nsPluginArray::WrapObject(JSContext* aCx, 57 JS::Handle<JSObject*> aGivenProto) { 58 return PluginArray_Binding::Wrap(aCx, this, aGivenProto); 59 } 60 61 nsPluginElement* nsPluginArray::IndexedGetter(uint32_t aIndex, bool& aFound) { 62 if (!ForceNoPlugins() && aIndex < std::size(mPlugins)) { 63 aFound = true; 64 return mPlugins[aIndex]; 65 } 66 67 aFound = false; 68 return nullptr; 69 } 70 71 nsPluginElement* nsPluginArray::NamedGetter(const nsAString& aName, 72 bool& aFound) { 73 if (ForceNoPlugins()) { 74 aFound = false; 75 return nullptr; 76 } 77 78 for (const auto& plugin : mPlugins) { 79 if (plugin->Name().Equals(aName)) { 80 aFound = true; 81 return plugin; 82 } 83 } 84 85 aFound = false; 86 return nullptr; 87 } 88 89 void nsPluginArray::GetSupportedNames(nsTArray<nsString>& aRetval) { 90 if (ForceNoPlugins()) { 91 return; 92 } 93 94 for (auto& plugin : mPlugins) { 95 aRetval.AppendElement(plugin->Name()); 96 } 97 } 98 99 bool nsPluginArray::ForceNoPlugins() { 100 return StaticPrefs::pdfjs_disabled() && 101 !nsContentUtils::ShouldResistFingerprinting( 102 mWindow ? mWindow->GetDocShell() : nullptr, RFPTarget::PdfjsSpoof); 103 } 104 105 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginArray) 106 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginArray) 107 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginArray) 108 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 109 NS_INTERFACE_MAP_ENTRY(nsISupports) 110 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) 111 NS_INTERFACE_MAP_END 112 113 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_WEAK(nsPluginArray, mPlugins[0], 114 mPlugins[1], mPlugins[2], 115 mPlugins[3], mPlugins[4], 116 mMimeTypeArray, mWindow) 117 118 // nsPluginElement implementation. 119 120 nsPluginElement::nsPluginElement(nsPluginArray* aPluginArray, 121 nsPIDOMWindowInner* aWindow, 122 const nsAString& aName) 123 : mPluginArray(aPluginArray), mWindow(aWindow), mName(aName) {} 124 125 nsPluginArray* nsPluginElement::GetParentObject() const { return mPluginArray; } 126 127 JSObject* nsPluginElement::WrapObject(JSContext* aCx, 128 JS::Handle<JSObject*> aGivenProto) { 129 return Plugin_Binding::Wrap(aCx, this, aGivenProto); 130 } 131 132 nsMimeType* nsPluginElement::IndexedGetter(uint32_t aIndex, bool& aFound) { 133 return MimeTypeArray()->IndexedGetter(aIndex, aFound); 134 } 135 136 nsMimeType* nsPluginElement::NamedGetter(const nsAString& aName, bool& aFound) { 137 return MimeTypeArray()->NamedGetter(aName, aFound); 138 } 139 140 void nsPluginElement::GetSupportedNames(nsTArray<nsString>& retval) { 141 return MimeTypeArray()->GetSupportedNames(retval); 142 } 143 144 uint32_t nsPluginElement::Length() { return MimeTypeArray()->Length(); } 145 146 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginElement) 147 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginElement) 148 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginElement) 149 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 150 NS_INTERFACE_MAP_ENTRY(nsISupports) 151 NS_INTERFACE_MAP_END 152 153 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsPluginElement, mWindow, mPluginArray)