Bug 813245 - Sanity-check for mimetype count from pluginreg.dat. r=bsmedberg,a=akeybl
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Fri, 21 Dec 2012 16:12:46 +0100
changeset 127268 4c3bea6e07ab2132b202ce4893ec00d81cc2794c
parent 127267 6be57140550d74d512752b7a594aa98257b8c2dd
child 127269 7363224d47998f512b70aa49c60d589b5392ec56
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, akeybl
bugs813245
milestone20.0a2
Bug 813245 - Sanity-check for mimetype count from pluginreg.dat. r=bsmedberg,a=akeybl
dom/plugins/base/nsPluginHost.cpp
dom/plugins/test/unit/head_plugins.js
dom/plugins/test/unit/test_bug455213.js
dom/plugins/test/unit/test_bug471245.js
dom/plugins/test/unit/test_bug813245.js
dom/plugins/test/unit/xpcshell.ini
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2577,20 +2577,22 @@ nsPluginHost::WritePluginInfo()
   PR_Close(fd);
   nsCOMPtr<nsIFile> parent;
   rv = pluginReg->GetParent(getter_AddRefs(parent));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = pluginReg->MoveToNative(parent, kPluginRegistryFilename);
   return rv;
 }
 
-#define PLUGIN_REG_MIMETYPES_ARRAY_SIZE 12
 nsresult
 nsPluginHost::ReadPluginInfo()
 {
+  const long PLUGIN_REG_MIMETYPES_ARRAY_SIZE = 12;
+  const long PLUGIN_REG_MAX_MIMETYPES = 1000;
+
   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));
@@ -2788,17 +2790,21 @@ nsPluginHost::ReadPluginInfo()
       version = &description[16];
     }
 #endif
 
     const char *name = reader.LinePtr();
     if (!reader.NextLine())
       return rv;
 
-    int mimetypecount = atoi(reader.LinePtr());
+    long mimetypecount = std::strtol(reader.LinePtr(), nullptr, 10);
+    if (mimetypecount == LONG_MAX || mimetypecount == LONG_MIN ||
+        mimetypecount >= PLUGIN_REG_MAX_MIMETYPES || mimetypecount < 0) {
+      return NS_ERROR_FAILURE;
+    }
 
     char *stackalloced[PLUGIN_REG_MIMETYPES_ARRAY_SIZE * 3];
     char **mimetypes;
     char **mimedescriptions;
     char **extensions;
     char **heapalloced = 0;
     if (mimetypecount > PLUGIN_REG_MIMETYPES_ARRAY_SIZE - 1) {
       heapalloced = new char *[mimetypecount * 3];
--- a/dom/plugins/test/unit/head_plugins.js
+++ b/dom/plugins/test/unit/head_plugins.js
@@ -27,8 +27,56 @@ function get_test_plugin() {
     plugin.append("nptest.dll");
     if (plugin.exists()) {
       plugin.normalize();
       return plugin;
     }
   }
   return null;
 }
+
+// Finds the test nsIPluginTag
+function get_test_plugintag() {
+  const Cc = Components.classes;
+  const Ci = Components.interfaces;
+
+  var host = Cc["@mozilla.org/plugin/host;1"].
+             getService(Ci.nsIPluginHost);
+  var tags = host.getPluginTags();
+  for (var i = 0; i < tags.length; i++) {
+    if (tags[i].name == "Test Plug-in")
+      return tags[i];
+  }
+  return null;
+}
+
+// Creates a fake ProfDS directory key, copied from do_get_profile
+function do_get_profile_startup() {
+  let env = Components.classes["@mozilla.org/process/environment;1"]
+                      .getService(Components.interfaces.nsIEnvironment);
+  // the python harness sets this in the environment for us
+  let profd = env.get("XPCSHELL_TEST_PROFILE_DIR");
+  let file = Components.classes["@mozilla.org/file/local;1"]
+                       .createInstance(Components.interfaces.nsILocalFile);
+  file.initWithPath(profd);
+
+  let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
+                         .getService(Components.interfaces.nsIProperties);
+  let provider = {
+    getFile: function(prop, persistent) {
+      persistent.value = true;
+      if (prop == "ProfDS") {
+        return file.clone();
+      }
+      throw Components.results.NS_ERROR_FAILURE;
+    },
+    QueryInterface: function(iid) {
+      if (iid.equals(Components.interfaces.nsIDirectoryServiceProvider) ||
+          iid.equals(Components.interfaces.nsISupports)) {
+        return this;
+      }
+      throw Components.results.NS_ERROR_NO_INTERFACE;
+    }
+  };
+  dirSvc.QueryInterface(Components.interfaces.nsIDirectoryService)
+        .registerProvider(provider);
+  return file.clone();
+}
--- a/dom/plugins/test/unit/test_bug455213.js
+++ b/dom/plugins/test/unit/test_bug455213.js
@@ -43,28 +43,16 @@ function write_registry(version, info) {
            createInstance(Ci.nsIConverterOutputStream);
   os.init(foStream, charset, 0, 0x0000);
 
   os.writeString(header);
   os.writeString(info);
   os.close();
 }
 
-// Finds the test nsIPluginTag
-function get_test_plugintag() {
-  var host = Cc["@mozilla.org/plugin/host;1"].
-             getService(Ci.nsIPluginHost);
-  var tags = host.getPluginTags();
-  for (var i = 0; i < tags.length; i++) {
-    if (tags[i].name == "Test Plug-in")
-      return tags[i];
-  }
-  return null;
-}
-
 function run_test() {
   var file = get_test_plugin();
   if (!file)
     do_throw("Plugin library not found");
 
   // Write out a 0.9 version registry that marks the test plugin as disabled
   var registry = "";
   if (isMac) {
--- a/dom/plugins/test/unit/test_bug471245.js
+++ b/dom/plugins/test/unit/test_bug471245.js
@@ -1,61 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
-// Creates a fake ProfDS directory key, copied from do_get_profile
-function do_get_profile_startup() {
-  let env = Components.classes["@mozilla.org/process/environment;1"]
-                      .getService(Components.interfaces.nsIEnvironment);
-  // the python harness sets this in the environment for us
-  let profd = env.get("XPCSHELL_TEST_PROFILE_DIR");
-  let file = Components.classes["@mozilla.org/file/local;1"]
-                       .createInstance(Components.interfaces.nsILocalFile);
-  file.initWithPath(profd);
-
-  let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
-                         .getService(Components.interfaces.nsIProperties);
-  let provider = {
-    getFile: function(prop, persistent) {
-      persistent.value = true;
-      if (prop == "ProfDS") {
-        return file.clone();
-      }
-      throw Components.results.NS_ERROR_FAILURE;
-    },
-    QueryInterface: function(iid) {
-      if (iid.equals(Components.interfaces.nsIDirectoryServiceProvider) ||
-          iid.equals(Components.interfaces.nsISupports)) {
-        return this;
-      }
-      throw Components.results.NS_ERROR_NO_INTERFACE;
-    }
-  };
-  dirSvc.QueryInterface(Components.interfaces.nsIDirectoryService)
-        .registerProvider(provider);
-  return file.clone();
-}
-
-// Finds the test nsIPluginTag
-function get_test_plugintag() {
-  var host = Cc["@mozilla.org/plugin/host;1"].
-             getService(Ci.nsIPluginHost);
-  var tags = host.getPluginTags();
-  for (var i = 0; i < tags.length; i++) {
-    if (tags[i].name == "Test Plug-in")
-      return tags[i];
-  }
-  return null;
-}
-
 function run_test() {
   do_get_profile_startup();
 
   var plugin = get_test_plugintag();
   do_check_true(plugin == null);
 
   // Initialises a profile folder
   do_get_profile();
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/unit/test_bug813245.js
@@ -0,0 +1,97 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+// v0.9+ registry field meanings are different on Mac OS X
+const CWD = do_get_cwd();
+function checkOS(os) {
+  const nsILocalFile_ = "nsILocalFile" + os;
+  return nsILocalFile_ in Components.interfaces &&
+         CWD instanceof Components.interfaces[nsILocalFile_];
+}
+const isMac = checkOS("Mac");
+
+// Plugin registry uses different field delimeters on different platforms
+var DELIM = ":";
+if ("@mozilla.org/windows-registry-key;1" in Components.classes)
+  DELIM = "|";
+
+var gProfD = do_get_profile_startup();
+var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
+             getService(Ci.nsIProperties);
+
+// Writes out some plugin registry to the profile
+function write_registry(version, info) {
+  let runtime = Cc["@mozilla.org/xre/runtime;1"].getService(Ci.nsIXULRuntime);
+
+  var 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";
+
+  var registry = gProfD.clone();
+  registry.append("pluginreg.dat");
+  var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
+                           .createInstance(Components.interfaces.nsIFileOutputStream);
+  // write, create, truncate
+  foStream.init(registry, 0x02 | 0x08 | 0x20, 0666, 0);
+
+  var charset = "UTF-8"; // Can be any character encoding name that Mozilla supports
+  var 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() {
+  var plugin = get_test_plugintag();
+  do_check_true(plugin == null);
+
+  var file = get_test_plugin();
+  if (!file) {
+    do_throw("Plugin library not found");
+  }
+
+  // write plugin registry data
+  let registry = "";
+
+  if (isMac) {
+    registry += file.leafName + DELIM + "$\n";
+    registry += file.path + DELIM + "$\n";
+  } else {
+    registry += file.path + DELIM + "$\n";
+    registry += DELIM + "$\n";
+  }
+  registry += "0.0.0.0" + DELIM + "$\n";
+  registry += "16725225600" + DELIM + "0" + DELIM + "5" + DELIM + "$\n";
+  registry += "Plug-in for testing purposes." + DELIM + "$\n";
+  registry += "Test Plug-in" + DELIM + "$\n";
+  registry += "999999999999999999999999999999999999999999999999|0|5|$\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();
+
+  var plugin = get_test_plugintag();
+  if (!plugin)
+    do_throw("Plugin tag not found");
+
+  // The plugin registry should have been rejected.
+  // If not, the test plugin version would be 0.0.0.0
+  do_check_eq(plugin.version, "1.0.0.0");
+}
--- a/dom/plugins/test/unit/xpcshell.ini
+++ b/dom/plugins/test/unit/xpcshell.ini
@@ -3,8 +3,11 @@ head = head_plugins.js
 tail = 
 
 [test_bug455213.js]
 # Bug 676953: test fails consistently on Android
 fail-if = os == "android"
 [test_bug471245.js]
 # Bug 676953: test fails consistently on Android
 fail-if = os == "android"
+[test_bug813245.js]
+# Bug 676953: test fails consistently on Android
+fail-if = os == "android"