dom/base/nsPluginArray.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsPluginArray.h"
     8 #include "mozilla/Preferences.h"
     9 #include "mozilla/dom/PluginArrayBinding.h"
    10 #include "mozilla/dom/PluginBinding.h"
    12 #include "nsCharSeparatedTokenizer.h"
    13 #include "nsMimeTypeArray.h"
    14 #include "Navigator.h"
    15 #include "nsIDocShell.h"
    16 #include "nsIWebNavigation.h"
    17 #include "nsPluginHost.h"
    18 #include "nsPluginTags.h"
    19 #include "nsIObserverService.h"
    20 #include "nsIWeakReference.h"
    21 #include "mozilla/Services.h"
    22 #include "nsIInterfaceRequestorUtils.h"
    24 using namespace mozilla;
    25 using namespace mozilla::dom;
    27 nsPluginArray::nsPluginArray(nsPIDOMWindow* aWindow)
    28   : mWindow(aWindow)
    29 {
    30   SetIsDOMBinding();
    31 }
    33 void
    34 nsPluginArray::Init()
    35 {
    36   nsCOMPtr<nsIObserverService> obsService =
    37     mozilla::services::GetObserverService();
    38   if (obsService) {
    39     obsService->AddObserver(this, "plugin-info-updated", true);
    40   }
    41 }
    43 nsPluginArray::~nsPluginArray()
    44 {
    45 }
    47 nsPIDOMWindow*
    48 nsPluginArray::GetParentObject() const
    49 {
    50   MOZ_ASSERT(mWindow);
    51   return mWindow;
    52 }
    54 JSObject*
    55 nsPluginArray::WrapObject(JSContext* aCx)
    56 {
    57   return PluginArrayBinding::Wrap(aCx, this);
    58 }
    60 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginArray)
    61 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginArray)
    62 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginArray)
    63   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    64   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
    65   NS_INTERFACE_MAP_ENTRY(nsIObserver)
    66   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    67 NS_INTERFACE_MAP_END
    69 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(nsPluginArray,
    70                                         mWindow,
    71                                         mPlugins,
    72                                         mHiddenPlugins)
    74 static void
    75 GetPluginMimeTypes(const nsTArray<nsRefPtr<nsPluginElement> >& aPlugins,
    76                    nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes)
    77 {
    78   for (uint32_t i = 0; i < aPlugins.Length(); ++i) {
    79     nsPluginElement *plugin = aPlugins[i];
    80     aMimeTypes.AppendElements(plugin->MimeTypes());
    81   }
    82 }
    84 void
    85 nsPluginArray::GetMimeTypes(nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes,
    86                             nsTArray<nsRefPtr<nsMimeType> >& aHiddenMimeTypes)
    87 {
    88   aMimeTypes.Clear();
    89   aHiddenMimeTypes.Clear();
    91   if (!AllowPlugins()) {
    92     return;
    93   }
    95   EnsurePlugins();
    97   GetPluginMimeTypes(mPlugins, aMimeTypes);
    98   GetPluginMimeTypes(mHiddenPlugins, aHiddenMimeTypes);
    99 }
   101 nsPluginElement*
   102 nsPluginArray::Item(uint32_t aIndex)
   103 {
   104   bool unused;
   105   return IndexedGetter(aIndex, unused);
   106 }
   108 nsPluginElement*
   109 nsPluginArray::NamedItem(const nsAString& aName)
   110 {
   111   bool unused;
   112   return NamedGetter(aName, unused);
   113 }
   115 void
   116 nsPluginArray::Refresh(bool aReloadDocuments)
   117 {
   118   nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
   120   if(!AllowPlugins() || !pluginHost) {
   121     return;
   122   }
   124   // NS_ERROR_PLUGINS_PLUGINSNOTCHANGED on reloading plugins indicates
   125   // that plugins did not change and was not reloaded
   126   if (pluginHost->ReloadPlugins() ==
   127       NS_ERROR_PLUGINS_PLUGINSNOTCHANGED) {
   128     nsTArray<nsRefPtr<nsPluginTag> > newPluginTags;
   129     pluginHost->GetPlugins(newPluginTags);
   131     // Check if the number of plugins we know about are different from
   132     // the number of plugin tags the plugin host knows about. If the
   133     // lengths are different, we refresh. This is safe because we're
   134     // notified for every plugin enabling/disabling event that
   135     // happens, and therefore the lengths will be in sync only when
   136     // the both arrays contain the same plugin tags (though as
   137     // different types).
   138     uint32_t pluginCount = mPlugins.Length() + mHiddenPlugins.Length();
   139     if (newPluginTags.Length() == pluginCount) {
   140       return;
   141     }
   142   }
   144   mPlugins.Clear();
   145   mHiddenPlugins.Clear();
   147   nsCOMPtr<nsIDOMNavigator> navigator;
   148   mWindow->GetNavigator(getter_AddRefs(navigator));
   150   if (!navigator) {
   151     return;
   152   }
   154   static_cast<mozilla::dom::Navigator*>(navigator.get())->RefreshMIMEArray();
   156   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(mWindow);
   157   if (aReloadDocuments && webNav) {
   158     webNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
   159   }
   160 }
   162 nsPluginElement*
   163 nsPluginArray::IndexedGetter(uint32_t aIndex, bool &aFound)
   164 {
   165   aFound = false;
   167   if (!AllowPlugins()) {
   168     return nullptr;
   169   }
   171   EnsurePlugins();
   173   aFound = aIndex < mPlugins.Length();
   175   return aFound ? mPlugins[aIndex] : nullptr;
   176 }
   178 void
   179 nsPluginArray::Invalidate()
   180 {
   181   nsCOMPtr<nsIObserverService> obsService =
   182     mozilla::services::GetObserverService();
   183   if (obsService) {
   184     obsService->RemoveObserver(this, "plugin-info-updated");
   185   }
   186 }
   188 static nsPluginElement*
   189 FindPlugin(const nsTArray<nsRefPtr<nsPluginElement> >& aPlugins,
   190            const nsAString& aName)
   191 {
   192   for (uint32_t i = 0; i < aPlugins.Length(); ++i) {
   193     nsAutoString pluginName;
   194     nsPluginElement* plugin = aPlugins[i];
   195     plugin->GetName(pluginName);
   197     if (pluginName.Equals(aName)) {
   198       return plugin;
   199     }
   200   }
   202   return nullptr;
   203 }
   205 nsPluginElement*
   206 nsPluginArray::NamedGetter(const nsAString& aName, bool &aFound)
   207 {
   208   aFound = false;
   210   if (!AllowPlugins()) {
   211     return nullptr;
   212   }
   214   EnsurePlugins();
   216   nsPluginElement* plugin = FindPlugin(mPlugins, aName);
   217   if (!plugin) {
   218     plugin = FindPlugin(mHiddenPlugins, aName);
   219   }
   221   aFound = (plugin != nullptr);
   222   return plugin;
   223 }
   225 bool
   226 nsPluginArray::NameIsEnumerable(const nsAString& aName)
   227 {
   228   return true;
   229 }
   231 uint32_t
   232 nsPluginArray::Length()
   233 {
   234   if (!AllowPlugins()) {
   235     return 0;
   236   }
   238   EnsurePlugins();
   240   return mPlugins.Length();
   241 }
   243 void
   244 nsPluginArray::GetSupportedNames(unsigned, nsTArray<nsString>& aRetval)
   245 {
   246   aRetval.Clear();
   248   if (!AllowPlugins()) {
   249     return;
   250   }
   252   for (uint32_t i = 0; i < mPlugins.Length(); ++i) {
   253     nsAutoString pluginName;
   254     mPlugins[i]->GetName(pluginName);
   256     aRetval.AppendElement(pluginName);
   257   }
   258 }
   260 NS_IMETHODIMP
   261 nsPluginArray::Observe(nsISupports *aSubject, const char *aTopic,
   262                        const char16_t *aData) {
   263   if (!nsCRT::strcmp(aTopic, "plugin-info-updated")) {
   264     Refresh(false);
   265   }
   267   return NS_OK;
   268 }
   270 bool
   271 nsPluginArray::AllowPlugins() const
   272 {
   273   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWindow);
   275   return docShell && docShell->PluginsAllowedInCurrentDoc();
   276 }
   278 static bool
   279 HasStringPrefix(const nsCString& str, const nsACString& prefix) {
   280   return str.Compare(prefix.BeginReading(), false, prefix.Length()) == 0;
   281 }
   283 static bool
   284 IsPluginEnumerable(const nsTArray<nsCString>& enumerableNames,
   285                    const nsPluginTag* pluginTag)
   286 {
   287   const nsCString& pluginName = pluginTag->mName;
   289   const uint32_t length = enumerableNames.Length();
   290   for (uint32_t i = 0; i < length; i++) {
   291     const nsCString& name = enumerableNames[i];
   292     if (HasStringPrefix(pluginName, name)) {
   293       return true; // don't hide plugin
   294     }
   295   }
   297   return false; // hide plugin!
   298 }
   300 void
   301 nsPluginArray::EnsurePlugins()
   302 {
   303   if (!mPlugins.IsEmpty() || !mHiddenPlugins.IsEmpty()) {
   304     // We already have an array of plugin elements.
   305     return;
   306   }
   308   nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
   309   if (!pluginHost) {
   310     // We have no plugin host.
   311     return;
   312   }
   314   nsTArray<nsRefPtr<nsPluginTag> > pluginTags;
   315   pluginHost->GetPlugins(pluginTags);
   317   nsTArray<nsCString> enumerableNames;
   319   const nsAdoptingCString& enumerableNamesPref =
   320       Preferences::GetCString("plugins.enumerable_names");
   322   bool disablePluginHiding = !enumerableNamesPref ||
   323                              enumerableNamesPref.EqualsLiteral("*");
   325   if (!disablePluginHiding) {
   326     nsCCharSeparatedTokenizer tokens(enumerableNamesPref, ',');
   327     while (tokens.hasMoreTokens()) {
   328       const nsCSubstring& token = tokens.nextToken();
   329       if (!token.IsEmpty()) {
   330         enumerableNames.AppendElement(token);
   331       }
   332     }
   333   }
   335   // need to wrap each of these with a nsPluginElement, which is
   336   // scriptable.
   337   for (uint32_t i = 0; i < pluginTags.Length(); ++i) {
   338     nsPluginTag* pluginTag = pluginTags[i];
   340     // Add the plugin to the list of hidden plugins or non-hidden plugins?
   341     nsTArray<nsRefPtr<nsPluginElement> >& pluginArray =
   342         (disablePluginHiding || IsPluginEnumerable(enumerableNames, pluginTag))
   343         ? mPlugins
   344         : mHiddenPlugins;
   346     pluginArray.AppendElement(new nsPluginElement(mWindow, pluginTag));
   347   }
   348 }
   350 // nsPluginElement implementation.
   352 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginElement)
   353 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginElement)
   354 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginElement)
   355   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   356   NS_INTERFACE_MAP_ENTRY(nsISupports)
   357 NS_INTERFACE_MAP_END
   359 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsPluginElement, mWindow, mMimeTypes)
   361 nsPluginElement::nsPluginElement(nsPIDOMWindow* aWindow,
   362                                  nsPluginTag* aPluginTag)
   363   : mWindow(aWindow),
   364     mPluginTag(aPluginTag)
   365 {
   366   SetIsDOMBinding();
   367 }
   369 nsPIDOMWindow*
   370 nsPluginElement::GetParentObject() const
   371 {
   372   MOZ_ASSERT(mWindow);
   373   return mWindow;
   374 }
   376 JSObject*
   377 nsPluginElement::WrapObject(JSContext* aCx)
   378 {
   379   return PluginBinding::Wrap(aCx, this);
   380 }
   382 void
   383 nsPluginElement::GetDescription(nsString& retval) const
   384 {
   385   CopyUTF8toUTF16(mPluginTag->mDescription, retval);
   386 }
   388 void
   389 nsPluginElement::GetFilename(nsString& retval) const
   390 {
   391   CopyUTF8toUTF16(mPluginTag->mFileName, retval);
   392 }
   394 void
   395 nsPluginElement::GetVersion(nsString& retval) const
   396 {
   397   CopyUTF8toUTF16(mPluginTag->mVersion, retval);
   398 }
   400 void
   401 nsPluginElement::GetName(nsString& retval) const
   402 {
   403   CopyUTF8toUTF16(mPluginTag->mName, retval);
   404 }
   406 nsMimeType*
   407 nsPluginElement::Item(uint32_t aIndex)
   408 {
   409   EnsurePluginMimeTypes();
   411   return mMimeTypes.SafeElementAt(aIndex);
   412 }
   414 nsMimeType*
   415 nsPluginElement::NamedItem(const nsAString& aName)
   416 {
   417   bool unused;
   418   return NamedGetter(aName, unused);
   419 }
   421 nsMimeType*
   422 nsPluginElement::IndexedGetter(uint32_t aIndex, bool &aFound)
   423 {
   424   EnsurePluginMimeTypes();
   426   aFound = aIndex < mMimeTypes.Length();
   428   return aFound ? mMimeTypes[aIndex] : nullptr;
   429 }
   431 nsMimeType*
   432 nsPluginElement::NamedGetter(const nsAString& aName, bool &aFound)
   433 {
   434   EnsurePluginMimeTypes();
   436   aFound = false;
   438   for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) {
   439     if (mMimeTypes[i]->Type().Equals(aName)) {
   440       aFound = true;
   442       return mMimeTypes[i];
   443     }
   444   }
   446   return nullptr;
   447 }
   449 bool
   450 nsPluginElement::NameIsEnumerable(const nsAString& aName)
   451 {
   452   return true;
   453 }
   455 uint32_t
   456 nsPluginElement::Length()
   457 {
   458   EnsurePluginMimeTypes();
   460   return mMimeTypes.Length();
   461 }
   463 void
   464 nsPluginElement::GetSupportedNames(unsigned, nsTArray<nsString>& retval)
   465 {
   466   EnsurePluginMimeTypes();
   468   for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) {
   469     retval.AppendElement(mMimeTypes[i]->Type());
   470   }
   471 }
   473 nsTArray<nsRefPtr<nsMimeType> >&
   474 nsPluginElement::MimeTypes()
   475 {
   476   EnsurePluginMimeTypes();
   478   return mMimeTypes;
   479 }
   481 void
   482 nsPluginElement::EnsurePluginMimeTypes()
   483 {
   484   if (!mMimeTypes.IsEmpty()) {
   485     return;
   486   }
   488   for (uint32_t i = 0; i < mPluginTag->mMimeTypes.Length(); ++i) {
   489     NS_ConvertUTF8toUTF16 type(mPluginTag->mMimeTypes[i]);
   490     mMimeTypes.AppendElement(new nsMimeType(mWindow, this, i, type));
   491   }
   492 }

mercurial