Bug 1307501 part B - don't read old versions of pluginreg.dat. Long ago we took great pains to read this backwards-compat because plugin enabled/click-to-play state was recorded here. But that has been recorded in prefs since Firefox 22, so now we can safely just treat this as a disposable cache. r=qdot
authorBenjamin Smedberg <benjamin@smedbergs.us>
Wed, 05 Oct 2016 09:48:57 -0400
changeset 316833 c6752015a180432ee6e6697557d86a6f6e419594
parent 316832 70cbf2ee09eb673d5d108462eac28bb266cbd04f
child 316834 428876d40e6be43618726dc7bd8b903584238b04
push id32932
push userphilringnalda@gmail.com
push dateFri, 07 Oct 2016 03:24:25 +0000
treeherderautoland@7affb66131bb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs1307501
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1307501 part B - don't read old versions of pluginreg.dat. Long ago we took great pains to read this backwards-compat because plugin enabled/click-to-play state was recorded here. But that has been recorded in prefs since Firefox 22, so now we can safely just treat this as a disposable cache. r=qdot MozReview-Commit-ID: 1QBEBuXiesh
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginTags.cpp
dom/plugins/base/nsPluginTags.h
dom/plugins/test/unit/test_persist_in_prefs.js
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -141,38 +141,17 @@ static const char *kPrefLoadInParentPref
 static const char *kPrefDisableFullPage = "plugin.disable_full_page_plugin_for_types";
 static const char *kPrefJavaMIME = "plugin.java.mime";
 
 // How long we wait before unloading an idle plugin process.
 // Defaults to 30 seconds.
 static const char *kPrefUnloadPluginTimeoutSecs = "dom.ipc.plugins.unloadTimeoutSecs";
 static const uint32_t kDefaultPluginUnloadingTimeout = 30;
 
-// Version of cached plugin info
-// 0.01 first implementation
-// 0.02 added caching of CanUnload to fix bug 105935
-// 0.03 changed name, description and mime desc from string to bytes, bug 108246
-// 0.04 added new mime entry point on Mac, bug 113464
-// 0.05 added new entry point check for the default plugin, bug 132430
-// 0.06 strip off suffixes in mime description strings, bug 53895
-// 0.07 changed nsIRegistry to flat file support for caching plugins info
-// 0.08 mime entry point on MachO, bug 137535
-// 0.09 the file encoding is changed to UTF-8, bug 420285
-// 0.10 added plugin versions on appropriate platforms, bug 427743
-// 0.11 file name and full path fields now store expected values on all platforms, bug 488181
-// 0.12 force refresh due to quicktime pdf claim fix, bug 611197
-// 0.13 add architecture and list of invalid plugins, bug 616271
-// 0.14 force refresh due to locale comparison fix, bug 611296
-// 0.15 force refresh due to bug in reading Java plist MIME data, bug 638171
-// 0.16 version bump to avoid importing the plugin flags in newer versions
-// 0.17 added flag on whether plugin is loaded from an XPI
-// The current plugin registry version (and the maximum version we know how to read)
-static const char *kPluginRegistryVersion = "0.17";
-// The minimum registry version we know how to read
-static const char *kMinimumRegistryVersion = "0.9";
+static const char *kPluginRegistryVersion = "0.18";
 
 static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1";
 
 #define kPluginRegistryFilename NS_LITERAL_CSTRING("pluginreg.dat")
 
 #ifdef PLUGIN_LOGGING
 LazyLogModule nsPluginLogging::gNPNLog(NPN_LOG_NAME);
 LazyLogModule nsPluginLogging::gNPPLog(NPP_LOG_NAME);
@@ -2985,20 +2964,16 @@ nsPluginHost::WritePluginInfo()
 nsresult
 nsPluginHost::ReadPluginInfo()
 {
   MOZ_ASSERT(XRE_IsParentProcess());
 
   const long PLUGIN_REG_MIMETYPES_ARRAY_SIZE = 12;
   const long PLUGIN_REG_MAX_MIMETYPES = 1000;
 
-  // we need to import the legacy flags from the plugin registry once
-  const bool pluginStateImported =
-    Preferences::GetDefaultBool("plugin.importedState", false);
-
   nsresult rv;
 
   nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
   if (NS_FAILED(rv))
     return rv;
 
   directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
                         getter_AddRefs(mPluginRegFile));
@@ -3080,138 +3055,78 @@ nsPluginHost::ReadPluginInfo()
   // VersionLiteral, kPluginRegistryVersion
   if (2 != reader.ParseLine(values, 2))
     return rv;
 
   // VersionLiteral
   if (PL_strcmp(values[0], "Version"))
     return rv;
 
-  // kPluginRegistryVersion
-  int32_t vdiff = mozilla::CompareVersions(values[1], kPluginRegistryVersion);
-  mozilla::Version version(values[1]);
-  // If this is a registry from some future version then don't attempt to read it
-  if (vdiff > 0)
+  // If we're reading an old registry, ignore it
+  if (strcmp(values[1], kPluginRegistryVersion) != 0) {
     return rv;
-  // If this is a registry from before the minimum then don't attempt to read it
-  if (version < kMinimumRegistryVersion)
+  }
+
+  char* archValues[6];
+  if (!reader.NextLine()) {
+    return rv;
+  }
+
+  // ArchLiteral, Architecture
+  if (2 != reader.ParseLine(archValues, 2)) {
     return rv;
-
-  // Registry v0.10 and upwards includes the plugin version field
-  bool regHasVersion = (version >= "0.10");
-
-  // Registry v0.13 and upwards includes the architecture
-  if (version >= "0.13") {
-    char* archValues[6];
-
-    if (!reader.NextLine()) {
-      return rv;
-    }
-
-    // ArchLiteral, Architecture
-    if (2 != reader.ParseLine(archValues, 2)) {
-      return rv;
-    }
-
-    // ArchLiteral
-    if (PL_strcmp(archValues[0], "Arch")) {
-      return rv;
-    }
-
-    nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
-    if (!runtime) {
-      return rv;
-    }
-
-    nsAutoCString arch;
-    if (NS_FAILED(runtime->GetXPCOMABI(arch))) {
-      return rv;
-    }
-
-    // If this is a registry from a different architecture then don't attempt to read it
-    if (PL_strcmp(archValues[1], arch.get())) {
-      return rv;
-    }
+  }
+
+  // ArchLiteral
+  if (PL_strcmp(archValues[0], "Arch")) {
+    return rv;
+  }
+
+  nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
+  if (!runtime) {
+    return rv;
   }
 
-  // Registry v0.13 and upwards includes the list of invalid plugins
-  const bool hasInvalidPlugins = (version >= "0.13");
-
-  // Registry v0.16 and upwards always have 0 for their plugin flags, prefs are used instead
-  const bool hasValidFlags = (version < "0.16");
-
-  // Registry v0.17 and upwards store whether the plugin comes from an XPI.
-  const bool hasFromExtension = (version >= "0.17");
-
-#if defined(XP_MACOSX)
-  const bool hasFullPathInFileNameField = false;
-#else
-  const bool hasFullPathInFileNameField = (version < "0.11");
-#endif
+  nsAutoCString arch;
+  if (NS_FAILED(runtime->GetXPCOMABI(arch))) {
+    return rv;
+  }
+
+  // If this is a registry from a different architecture then don't attempt to read it
+  if (PL_strcmp(archValues[1], arch.get())) {
+    return rv;
+  }
 
   if (!ReadSectionHeader(reader, "PLUGINS"))
     return rv;
 
   while (reader.NextLine()) {
-    const char *filename;
-    const char *fullpath;
-    nsAutoCString derivedFileName;
-
-    if (hasInvalidPlugins && *reader.LinePtr() == '[') {
+    if (*reader.LinePtr() == '[') {
       break;
     }
 
-    if (hasFullPathInFileNameField) {
-      fullpath = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-      // try to derive a file name from the full path
-      if (fullpath) {
-        nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
-        file->InitWithNativePath(nsDependentCString(fullpath));
-        file->GetNativeLeafName(derivedFileName);
-        filename = derivedFileName.get();
-      } else {
-        filename = nullptr;
-      }
-
-      // skip the next line, useless in this version
-      if (!reader.NextLine())
-        return rv;
-    } else {
-      filename = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-
-      fullpath = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-    }
+    const char* filename = reader.LinePtr();
+    if (!reader.NextLine())
+      return rv;
+
+    const char* fullpath = reader.LinePtr();
+    if (!reader.NextLine())
+      return rv;
 
     const char *version;
-    if (regHasVersion) {
-      version = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-    } else {
-      version = "0";
-    }
+    version = reader.LinePtr();
+    if (!reader.NextLine())
+      return rv;
 
     // lastModifiedTimeStamp|canUnload|tag.mFlag|fromExtension
-    const int count = hasFromExtension ? 4 : 3;
-    if (reader.ParseLine(values, count) != count)
+    if (4 != reader.ParseLine(values, 4))
       return rv;
 
-    // If this is an old plugin registry mark this plugin tag to be refreshed
-    int64_t lastmod = (vdiff == 0) ? nsCRT::atoll(values[0]) : -1;
-    uint32_t tagflag = atoi(values[2]);
-    bool fromExtension = false;
-    if (hasFromExtension) {
-      fromExtension = atoi(values[3]);
-    }
+    int64_t lastmod = nsCRT::atoll(values[0]);
+    bool fromExtension = atoi(values[3]);
     if (!reader.NextLine())
       return rv;
 
     char *description = reader.LinePtr();
     if (!reader.NextLine())
       return rv;
 
 #if MOZ_WIDGET_ANDROID
@@ -3277,61 +3192,52 @@ nsPluginHost::ReadPluginInfo()
       (const char* const*)mimetypes,
       (const char* const*)mimedescriptions,
       (const char* const*)extensions,
       mimetypecount, lastmod, fromExtension, true);
     if (heapalloced)
       delete [] heapalloced;
 
     // Import flags from registry into prefs for old registry versions
-    if (hasValidFlags && !pluginStateImported) {
-      tag->ImportFlagsToPrefs(tagflag);
-    }
-
     MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
       ("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->FileName().get()));
 
     if (!ShouldAddPlugin(tag)) {
       continue;
     }
 
     tag->mNext = mCachedPlugins;
     mCachedPlugins = tag;
   }
 
 // On Android we always want to try to load a plugin again (Flash). Bug 935676.
 #ifndef MOZ_WIDGET_ANDROID
-  if (hasInvalidPlugins) {
-    if (!ReadSectionHeader(reader, "INVALID")) {
+  if (!ReadSectionHeader(reader, "INVALID")) {
+    return rv;
+  }
+
+  while (reader.NextLine()) {
+    const char *fullpath = reader.LinePtr();
+    if (!reader.NextLine()) {
       return rv;
     }
 
-    while (reader.NextLine()) {
-      const char *fullpath = reader.LinePtr();
-      if (!reader.NextLine()) {
-        return rv;
-      }
-
-      const char *lastModifiedTimeStamp = reader.LinePtr();
-      int64_t lastmod = (vdiff == 0) ? nsCRT::atoll(lastModifiedTimeStamp) : -1;
-
-      RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(fullpath, lastmod);
-
-      invalidTag->mNext = mInvalidPlugins;
-      if (mInvalidPlugins) {
-        mInvalidPlugins->mPrev = invalidTag;
-      }
-      mInvalidPlugins = invalidTag;
+    const char *lastModifiedTimeStamp = reader.LinePtr();
+    int64_t lastmod = nsCRT::atoll(lastModifiedTimeStamp);
+
+    RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(fullpath, lastmod);
+
+    invalidTag->mNext = mInvalidPlugins;
+    if (mInvalidPlugins) {
+      mInvalidPlugins->mPrev = invalidTag;
     }
+    mInvalidPlugins = invalidTag;
   }
 #endif
 
-  // flip the pref so we don't import the legacy flags again
-  Preferences::SetBool("plugin.importedState", true);
-
   return NS_OK;
 }
 
 void
 nsPluginHost::RemoveCachedPluginsInfo(const char *filePath, nsPluginTag **result)
 {
   RefPtr<nsPluginTag> prev;
   RefPtr<nsPluginTag> tag = mCachedPlugins;
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -752,23 +752,16 @@ nsPluginTag::GetNiceFileName()
 
 NS_IMETHODIMP
 nsPluginTag::GetNiceName(nsACString & aResult)
 {
   aResult = GetNiceFileName();
   return NS_OK;
 }
 
-void nsPluginTag::ImportFlagsToPrefs(uint32_t flags)
-{
-  if (!(flags & NS_PLUGIN_FLAG_ENABLED)) {
-    SetPluginState(ePluginState_Disabled);
-  }
-}
-
 NS_IMETHODIMP
 nsPluginTag::GetBlocklistState(uint32_t *aResult)
 {
 #if defined(MOZ_WIDGET_ANDROID)
   *aResult = nsIBlocklistService::STATE_NOT_BLOCKED;
   return NS_OK;
 #else
   if (mCachedBlocklistStateValid) {
--- a/dom/plugins/base/nsPluginTags.h
+++ b/dom/plugins/base/nsPluginTags.h
@@ -146,19 +146,16 @@ public:
   bool IsEnabled() override;
   void SetEnabled(bool enabled);
   bool IsClicktoplay();
   bool IsBlocklisted();
 
   PluginState GetPluginState();
   void SetPluginState(PluginState state);
 
-  // import legacy flags from plugin registry into the preferences
-  void ImportFlagsToPrefs(uint32_t flag);
-
   bool HasSameNameAndMimes(const nsPluginTag *aPluginTag) const;
   const nsCString& GetNiceFileName() override;
 
   bool IsFromExtension() const;
 
   RefPtr<nsPluginTag> mNext;
   uint32_t      mId;
 
--- a/dom/plugins/test/unit/test_persist_in_prefs.js
+++ b/dom/plugins/test/unit/test_persist_in_prefs.js
@@ -5,89 +5,40 @@
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 // Plugin registry uses different field delimeters on different platforms
 var DELIM = mozinfo.os == "win" ? "|" : ":";
 
 var gProfD = do_get_profile_startup();
 
-// Writes out some plugin registry to the profile
-function write_registry(version, info) {
-  let runtime = Cc["@mozilla.org/xre/runtime;1"].getService(Ci.nsIXULRuntime);
-
-  let header = "Generated File. Do not edit.\n\n";
-  header += "[HEADER]\n";
-  header += "Version" + DELIM + version + DELIM + "$\n";
-  header += "Arch" + DELIM + runtime.XPCOMABI + DELIM + "$\n";
-  header += "\n";
-  header += "[PLUGINS]\n";
-
-  let registry = gProfD.clone();
-  registry.append("pluginreg.dat");
-  let foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
-                           .createInstance(Components.interfaces.nsIFileOutputStream);
-  // write, create, truncate
-  foStream.init(registry, 0x02 | 0x08 | 0x20, 0o666, 0);
-
-  let charset = "UTF-8"; // Can be any character encoding name that Mozilla supports
-  let os = Cc["@mozilla.org/intl/converter-output-stream;1"].
-           createInstance(Ci.nsIConverterOutputStream);
-  os.init(foStream, charset, 0, 0x0000);
-
-  os.writeString(header);
-  os.writeString(info);
-  os.close();
-}
-
 function run_test() {
   allow_all_plugins();
 
   do_check_true(gIsWindows || gIsOSX || gIsLinux);
 
   let file = get_test_plugin_no_symlink();
   if (!file)
     do_throw("Plugin library not found");
 
   const pluginDir = file.parent;
   const tempDir = do_get_tempdir();
   const suffix = get_platform_specific_plugin_suffix();
   const pluginName = file.leafName.substring(0, file.leafName.length - suffix.length).toLowerCase();
   const pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
   const statePref = "plugin.state." + pluginName;
 
-  // write plugin registry data
-  let registry = "";
-
-  registry += file.leafName + DELIM + "$\n";
-  registry += file.path + DELIM + "$\n";
-  registry += "1.0.0.0" + DELIM + "$\n";
-  registry += file.lastModifiedTime + DELIM + "0" + DELIM + "0" + DELIM + "$\n";
-  registry += "Plug-in for testing purposes." + DELIM + "$\n";
-  registry += "Test Plug-in" + DELIM + "$\n";
-  registry += "1\n";
-  registry += "0" + DELIM + "application/x-test" + DELIM + "Test mimetype" + DELIM + "tst" + DELIM + "$\n";
-
-  registry += "\n";
-  registry += "[INVALID]\n";
-  registry += "\n";
-  write_registry("0.15", registry);
-
   // Initialise profile folder
   do_get_profile();
 
   let plugin = get_test_plugintag();
   if (!plugin)
     do_throw("Plugin tag not found");
 
-  // check that the expected plugin state was loaded correctly from the registry
-  do_check_true(plugin.disabled);
-  do_check_false(plugin.clicktoplay);
-  // ... and imported into prefs, with 0 being the disabled state
-  do_check_eq(0, Services.prefs.getIntPref(statePref));
+  plugin.enabledState = Ci.nsIPluginTag.STATE_DISABLED;
 
   // prepare a copy of the plugin and backup the original
   file.copyTo(null, "nptestcopy" + suffix);
   let copy = pluginDir.clone();
   copy.append("nptestcopy" + suffix);
   file.moveTo(tempDir, null);
 
   // test that the settings persist through a few variations of test-plugin names