Bug 633433: Limit plugin loading to Flash when we're trying to clear private data, but also clear anything else that happens to be open already. r=dwitte r=bsmedberg a=blocking2.0final+
authorJosh Aas <joshmoz@gmail.com>
Fri, 18 Feb 2011 20:05:23 -0500
changeset 62849 328483e1b820019df619c0f22f570ae3901d1fe5
parent 62848 b5fdead607d4f54b8de872e6cbbbc9fb53249444
child 62850 49c49bcf67bd99cc11dde62246c9154f83d6d17b
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewersdwitte, bsmedberg, blocking2
bugs633433
milestone2.0b12pre
Bug 633433: Limit plugin loading to Flash when we're trying to clear private data, but also clear anything else that happens to be open already. r=dwitte r=bsmedberg a=blocking2.0final+
modules/plugin/base/src/nsPluginHost.cpp
modules/plugin/base/src/nsPluginHost.h
modules/plugin/base/src/nsPluginTags.cpp
modules/plugin/base/src/nsPluginTags.h
--- a/modules/plugin/base/src/nsPluginHost.cpp
+++ b/modules/plugin/base/src/nsPluginHost.cpp
@@ -1794,16 +1794,29 @@ static nsresult CreateNPAPIPlugin(nsPlug
   else if (pluginRefNum > 0)
     ::CloseResFile(pluginRefNum);
   ::UseResFile(appRefNum);
 #endif
 
   return rv;
 }
 
+nsresult nsPluginHost::EnsurePluginLoaded(nsPluginTag* plugin)
+{
+  nsRefPtr<nsNPAPIPlugin> entrypoint = plugin->mEntryPoint;
+  if (!entrypoint) {
+    nsresult rv = CreateNPAPIPlugin(plugin, getter_AddRefs(entrypoint));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    plugin->mEntryPoint = entrypoint;
+  }
+  return NS_OK;
+}
+
 NS_IMETHODIMP nsPluginHost::GetPlugin(const char *aMimeType, nsIPlugin** aPlugin)
 {
   nsresult rv = NS_ERROR_FAILURE;
   *aPlugin = NULL;
 
   if (!aMimeType)
     return NS_ERROR_ILLEGAL_VALUE;
 
@@ -1817,26 +1830,22 @@ NS_IMETHODIMP nsPluginHost::GetPlugin(co
     ("nsPluginHost::GetPlugin Begin mime=%s, plugin=%s\n",
     aMimeType, pluginTag->mFileName.get()));
 
 #ifdef NS_DEBUG
     if (aMimeType && !pluginTag->mFileName.IsEmpty())
       printf("For %s found plugin %s\n", aMimeType, pluginTag->mFileName.get());
 #endif
 
-    // Create a plugin object if necessary
-    nsRefPtr<nsNPAPIPlugin> plugin = pluginTag->mEntryPoint;
-    if (!plugin) {
-      rv = CreateNPAPIPlugin(pluginTag, getter_AddRefs(plugin));
-      if (NS_FAILED(rv))
-        return rv;
-      pluginTag->mEntryPoint = plugin;
+    rv = EnsurePluginLoaded(pluginTag);
+    if (NS_FAILED(rv)) {
+      return rv;
     }
 
-    NS_ADDREF(*aPlugin = plugin);
+    NS_ADDREF(*aPlugin = pluginTag->mEntryPoint);
     return NS_OK;
   }
 
   PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   ("nsPluginHost::GetPlugin End mime=%s, rv=%d, plugin=%p name=%s\n",
   aMimeType, rv, *aPlugin,
   (pluginTag ? pluginTag->mFileName.get() : "(not found)")));
 
@@ -1933,64 +1942,53 @@ nsPluginHost::EnumerateSiteData(const ns
     if (firstMatchOnly) {
       break;
     }
   }
 
   return NS_OK;
 }
 
-// Ensure that 'plugin' is still a live, valid tag, and that it's loaded.
-nsPluginTag*
-nsPluginHost::EnsurePlugin(nsIPluginTag* plugin)
-{
-  LoadPlugins();
-
-  // Make sure the nsIPluginTag we're given is still live.
-  nsPluginTag* tag;
-  for (tag = mPlugins; tag && tag != plugin; tag = tag->mNext);
-  if (!tag) {
-    return NULL;
-  }
-
-  nsRefPtr<nsNPAPIPlugin> entrypoint = tag->mEntryPoint;
-  if (!entrypoint) {
-    nsresult rv = CreateNPAPIPlugin(tag, getter_AddRefs(entrypoint));
-    if (NS_FAILED(rv)) {
-      return NULL;
-    }
-
-    tag->mEntryPoint = entrypoint;
-  }
-
-  return tag;
-}
-
 NS_IMETHODIMP
 nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain,
                             PRUint64 flags, PRInt64 maxAge)
 {
   // maxAge must be either a nonnegative integer or -1.
   NS_ENSURE_ARG(maxAge >= 0 || maxAge == -1);
 
-  nsPluginTag* tag = EnsurePlugin(plugin);
-  if (!tag) {
+  // Caller may give us a tag object that is no longer live.
+  if (!IsLiveTag(plugin)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  nsPluginTag* tag = static_cast<nsPluginTag*>(plugin);
+
+  // We only ensure support for clearing Flash site data for now.
+  // We will also attempt to clear data for any plugin that happens
+  // to be loaded already.
+  if (!tag->mIsFlashPlugin && !tag->mEntryPoint) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // Make sure the plugin is loaded.
+  nsresult rv = EnsurePluginLoaded(tag);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   PluginLibrary* library = tag->mEntryPoint->GetLibrary();
 
   // If 'domain' is the null string, clear everything.
   if (domain.IsVoid()) {
     return library->NPP_ClearSiteData(NULL, flags, maxAge);
   }
 
   // Get the list of sites from the plugin.
   InfallibleTArray<nsCString> sites;
-  nsresult rv = library->NPP_GetSitesWithData(sites);
+  rv = library->NPP_GetSitesWithData(sites);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Enumerate the sites and build a list of matches.
   InfallibleTArray<nsCString> matches;
   rv = EnumerateSiteData(domain, sites, matches, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Clear the matches.
@@ -2002,26 +2000,41 @@ nsPluginHost::ClearSiteData(nsIPluginTag
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPluginHost::SiteHasData(nsIPluginTag* plugin, const nsACString& domain,
                           PRBool* result)
 {
-  nsPluginTag* tag = EnsurePlugin(plugin);
-  if (!tag) {
+  // Caller may give us a tag object that is no longer live.
+  if (!IsLiveTag(plugin)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  nsPluginTag* tag = static_cast<nsPluginTag*>(plugin);
+
+  // We only ensure support for clearing Flash site data for now.
+  // We will also attempt to clear data for any plugin that happens
+  // to be loaded already.
+  if (!tag->mIsFlashPlugin && !tag->mEntryPoint) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // Make sure the plugin is loaded.
+  nsresult rv = EnsurePluginLoaded(tag);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   PluginLibrary* library = tag->mEntryPoint->GetLibrary();
 
   // Get the list of sites from the plugin.
   InfallibleTArray<nsCString> sites;
-  nsresult rv = library->NPP_GetSitesWithData(sites);
+  rv = library->NPP_GetSitesWithData(sites);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // If there's no data, we're done.
   if (sites.IsEmpty()) {
     *result = false;
     return NS_OK;
   }
 
@@ -2048,17 +2061,17 @@ static PRBool isUnwantedPlugin(nsPluginT
 {
   if (tag->mFileName.IsEmpty())
     return PR_TRUE;
 
   for (PRInt32 i = 0; i < tag->mVariants; ++i) {
     if (!PL_strcasecmp(tag->mMimeTypeArray[i], "application/pdf"))
       return PR_FALSE;
 
-    if (!PL_strcasecmp(tag->mMimeTypeArray[i], "application/x-shockwave-flash"))
+    if (tag->mIsFlashPlugin)
       return PR_FALSE;
 
     if (!PL_strcasecmp(tag->mMimeTypeArray[i], "application/x-director"))
       return PR_FALSE;
   }
 
   // On Windows, we also want to include the Quicktime plugin from the 4.x directory
   // But because it spans several DLL's, the best check for now is by filename
@@ -2074,16 +2087,29 @@ PRBool nsPluginHost::IsJavaMIMEType(cons
     ((0 == PL_strncasecmp(aType, "application/x-java-vm",
                           sizeof("application/x-java-vm") - 1)) ||
      (0 == PL_strncasecmp(aType, "application/x-java-applet",
                           sizeof("application/x-java-applet") - 1)) ||
      (0 == PL_strncasecmp(aType, "application/x-java-bean",
                           sizeof("application/x-java-bean") - 1)));
 }
 
+// Check whether or not a tag is a live, valid tag, and that it's loaded.
+PRBool
+nsPluginHost::IsLiveTag(nsIPluginTag* aPluginTag)
+{
+  nsPluginTag* tag;
+  for (tag = mPlugins; tag; tag = tag->mNext) {
+    if (tag == aPluginTag) {
+      return PR_TRUE;
+    }
+  }
+  return PR_FALSE;
+}
+
 nsPluginTag * nsPluginHost::HaveSamePlugin(nsPluginTag * aPluginTag)
 {
   for (nsPluginTag* tag = mPlugins; tag; tag = tag->mNext) {
     if (tag->Equals(aPluginTag))
       return tag;
   }
   return nsnull;
 }
--- a/modules/plugin/base/src/nsPluginHost.h
+++ b/modules/plugin/base/src/nsPluginHost.h
@@ -244,30 +244,35 @@ private:
                        
   nsresult
   ScanPluginsDirectoryList(nsISimpleEnumerator * dirEnum,
                            nsIComponentManager * compManager, 
                            PRBool aCreatePluginList,
                            PRBool * aPluginsChanged,
                            PRBool checkForUnwantedPlugins = PR_FALSE);
 
+  nsresult EnsurePluginLoaded(nsPluginTag* plugin);
+
   PRBool IsRunningPlugin(nsPluginTag * plugin);
 
   // Stores all plugins info into the registry
   nsresult WritePluginInfo();
 
   // Loads all cached plugins info into mCachedPlugins
   nsresult ReadPluginInfo();
 
   // Given a file path, returns the plugins info from our cache
   // and removes it from the cache.
   void RemoveCachedPluginsInfo(const char *filePath,
                                nsPluginTag **result);
 
-  //checks if the list already have the same plugin as given
+  // Checks to see if a tag object is in our list of live tags.
+  PRBool IsLiveTag(nsIPluginTag* tag);
+
+  // Checks our list of live tags for an equivalent tag.
   nsPluginTag* HaveSamePlugin(nsPluginTag * aPluginTag);
 
   // checks if given plugin is a duplicate of what we already have
   // in the plugin list but found in some different place
   PRBool IsDuplicatePlugin(nsPluginTag * aPluginTag);
 
   nsresult EnsurePrivateDirServiceProvider();
 
@@ -300,17 +305,16 @@ private:
   nsCOMPtr<nsIIDNService> mIDNService;
 
   // Helpers for ClearSiteData and SiteHasData.
   nsresult NormalizeHostname(nsCString& host);
   nsresult EnumerateSiteData(const nsACString& domain,
                              const nsTArray<nsCString>& sites,
                              InfallibleTArray<nsCString>& result,
                              bool firstMatchOnly);
-  nsPluginTag* EnsurePlugin(nsIPluginTag* plugin);
 
   nsWeakPtr mCurrentDocument; // weak reference, we use it to id document only
 
   static nsIFile *sPluginTempDir;
 
   // We need to hold a global ptr to ourselves because we register for
   // two different CIDs for some reason...
   static nsPluginHost* sInst;
--- a/modules/plugin/base/src/nsPluginTags.cpp
+++ b/modules/plugin/base/src/nsPluginTags.cpp
@@ -79,16 +79,17 @@ mDescription(aPluginTag->mDescription),
 mVariants(aPluginTag->mVariants),
 mMimeTypeArray(nsnull),
 mMimeDescriptionArray(aPluginTag->mMimeDescriptionArray),
 mExtensionsArray(nsnull),
 mLibrary(nsnull),
 mCanUnloadLibrary(PR_TRUE),
 mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
 mIsNPRuntimeEnabledJavaPlugin(aPluginTag->mIsNPRuntimeEnabledJavaPlugin),
+mIsFlashPlugin(aPluginTag->mIsFlashPlugin),
 mFileName(aPluginTag->mFileName),
 mFullPath(aPluginTag->mFullPath),
 mVersion(aPluginTag->mVersion),
 mLastModifiedTime(0),
 mFlags(NS_PLUGIN_FLAG_ENABLED)
 {
   if (aPluginTag->mMimeTypeArray != nsnull) {
     mMimeTypeArray = new char*[mVariants];
@@ -113,44 +114,53 @@ mExtensionsArray(nsnull),
 mLibrary(nsnull),
 #ifdef XP_MACOSX
 mCanUnloadLibrary(!aPluginInfo->fBundle),
 #else
 mCanUnloadLibrary(PR_TRUE),
 #endif
 mIsJavaPlugin(PR_FALSE),
 mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
+mIsFlashPlugin(PR_FALSE),
 mFileName(aPluginInfo->fFileName),
 mFullPath(aPluginInfo->fFullPath),
 mVersion(aPluginInfo->fVersion),
 mLastModifiedTime(0),
 mFlags(NS_PLUGIN_FLAG_ENABLED)
 {
-  if (aPluginInfo->fMimeTypeArray != nsnull) {
+  if (aPluginInfo->fMimeTypeArray) {
     mMimeTypeArray = new char*[mVariants];
     for (int i = 0; i < mVariants; i++) {
-      if (mIsJavaPlugin && aPluginInfo->fMimeTypeArray[i] &&
-          strcmp(aPluginInfo->fMimeTypeArray[i],
-                 "application/x-java-vm-npruntime") == 0) {
-            mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
-            
-            // Stop processing here, any mimetypes after the magic "I'm a
-            // NPRuntime enabled Java plugin" mimetype will be ignored.
-            mVariants = i;
-            
-            break;
-          }
-      
-      mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
-      if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
+      char* currentMIMEType = aPluginInfo->fMimeTypeArray[i];
+      if (!currentMIMEType) {
+        continue;
+      }
+
+      if (mIsJavaPlugin) {
+        if (strcmp(currentMIMEType, "application/x-java-vm-npruntime") == 0) {
+          // Stop processing here, any mimetypes after the magic "I'm a
+          // NPRuntime enabled Java plugin" mimetype will be ignored.
+          mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
+          mVariants = i;
+          break;
+        }
+      }
+
+      mMimeTypeArray[i] = new_str(currentMIMEType);
+
+      if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i])) {
         mIsJavaPlugin = PR_TRUE;
+      }
+      else if (strcmp(currentMIMEType, "application/x-shockwave-flash") == 0) {
+        mIsFlashPlugin = PR_TRUE;
+      }
     }
   }
-  
-  if (aPluginInfo->fMimeDescriptionArray != nsnull) {
+
+  if (aPluginInfo->fMimeDescriptionArray) {
     for (int i = 0; i < mVariants; i++) {
       // we should cut off the list of suffixes which the mime
       // description string may have, see bug 53895
       // it is usually in form "some description (*.sf1, *.sf2)"
       // so we can search for the opening round bracket
       char cur = '\0';
       char pre = '\0';
       char * p = PL_strrchr(aPluginInfo->fMimeDescriptionArray[i], '(');
--- a/modules/plugin/base/src/nsPluginTags.h
+++ b/modules/plugin/base/src/nsPluginTags.h
@@ -109,16 +109,17 @@ public:
   char          **mMimeTypeArray;
   nsTArray<nsCString> mMimeDescriptionArray; // UTF-8
   char          **mExtensionsArray;
   PRLibrary     *mLibrary;
   nsRefPtr<nsNPAPIPlugin> mEntryPoint;
   PRPackedBool  mCanUnloadLibrary;
   PRPackedBool  mIsJavaPlugin;
   PRPackedBool  mIsNPRuntimeEnabledJavaPlugin;
+  PRPackedBool  mIsFlashPlugin;
   nsCString     mFileName; // UTF-8
   nsCString     mFullPath; // UTF-8
   nsCString     mVersion;  // UTF-8
   PRInt64       mLastModifiedTime;
 private:
   PRUint32      mFlags;
   
   nsresult EnsureMembersAreUTF8();