Bug 1251729 - Don't use eval for distribution.js; r=mixedpuppy
authorMichael Kaply <mozilla@kaply.com>
Mon, 29 Feb 2016 10:47:01 -0600
changeset 286216 2f7cae37286ec8aa65e5d90802e2dfe6b93d8742
parent 286215 6af962bff65de440a88387256ce311c5e5e2e440
child 286217 5496f32b7b5a78ee24039fa4cae5e6f34f14dd2d
push id72696
push usercbook@mozilla.com
push dateTue, 01 Mar 2016 14:25:42 +0000
treeherdermozilla-inbound@0f47155c48a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmixedpuppy
bugs1251729
milestone47.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 1251729 - Don't use eval for distribution.js; r=mixedpuppy
browser/components/distribution.js
browser/components/tests/unit/test_distribution.js
--- a/browser/components/distribution.js
+++ b/browser/components/distribution.js
@@ -346,17 +346,17 @@ DistributionCustomizer.prototype = {
     } catch (e) {
       /* ignore bad prefs due to bug 895473 and move on */
       Cu.reportError(e);
     }
 
     if (sections["Preferences"]) {
       for (let key of enumerate(this._ini.getKeys("Preferences"))) {
         try {
-          let value = eval(this._ini.getString("Preferences", key));
+          let value = parseValue(this._ini.getString("Preferences", key));
           switch (typeof value) {
           case "boolean":
             defaults.setBoolPref(key, value);
             break;
           case "number":
             defaults.setIntPref(key, value);
             break;
           case "string":
@@ -377,49 +377,49 @@ DistributionCustomizer.prototype = {
     let localizedStr = Cc["@mozilla.org/pref-localizedstring;1"].
       createInstance(Ci.nsIPrefLocalizedString);
 
     var usedLocalizablePreferences = [];
 
     if (sections["LocalizablePreferences-" + this._locale]) {
       for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
         try {
-          let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
+          let value = parseValue(this._ini.getString("LocalizablePreferences-" + this._locale, key));
           if (value !== undefined) {
             localizedStr.data = "data:text/plain," + key + "=" + value;
             defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
           }
           usedLocalizablePreferences.push(key);
         } catch (e) { /* ignore bad prefs and move on */ }
       }
     }
 
     if (sections["LocalizablePreferences-" + this._language]) {
       for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._language))) {
         if (usedLocalizablePreferences.indexOf(key) > -1) {
           continue;
         }
         try {
-          let value = eval(this._ini.getString("LocalizablePreferences-" + this._language, key));
+          let value = parseValue(this._ini.getString("LocalizablePreferences-" + this._language, key));
           if (value !== undefined) {
             localizedStr.data = "data:text/plain," + key + "=" + value;
             defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
           }
           usedLocalizablePreferences.push(key);
         } catch (e) { /* ignore bad prefs and move on */ }
       }
     }
 
     if (sections["LocalizablePreferences"]) {
       for (let key of enumerate(this._ini.getKeys("LocalizablePreferences"))) {
         if (usedLocalizablePreferences.indexOf(key) > -1) {
           continue;
         }
         try {
-          let value = eval(this._ini.getString("LocalizablePreferences", key));
+          let value = parseValue(this._ini.getString("LocalizablePreferences", key));
           if (value !== undefined) {
             value = value.replace(/%LOCALE%/g, this._locale);
             value = value.replace(/%LANGUAGE%/g, this._language);
             localizedStr.data = "data:text/plain," + key + "=" + value;
             defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
           }
         } catch (e) { /* ignore bad prefs and move on */ }
       }
@@ -453,16 +453,29 @@ DistributionCustomizer.prototype = {
         prefDefaultsApplied) {
       let os = Cc["@mozilla.org/observer-service;1"].
                getService(Ci.nsIObserverService);
       os.notifyObservers(null, DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC, null);
     }
   }
 };
 
+function parseValue(value) {
+  try {
+    value = JSON.parse(value);
+  } catch (e) {
+    // JSON.parse catches numbers and booleans.
+    // Anything else, we assume is a string.
+    // Remove the quotes that aren't needed anymore.
+    value = value.replace(/^"/, "");
+    value = value.replace(/"$/, "");
+  }
+  return value;
+}
+
 function* enumerate(UTF8Enumerator) {
   while (UTF8Enumerator.hasMore())
     yield UTF8Enumerator.getNext();
 }
 
 function enumToObject(UTF8Enumerator) {
   let ret = {};
   for (let i of enumerate(UTF8Enumerator))
--- a/browser/components/tests/unit/test_distribution.js
+++ b/browser/components/tests/unit/test_distribution.js
@@ -58,17 +58,17 @@ do_register_cleanup(function () {
 });
 
 add_task(function* () {
   // Force distribution.
   let glue = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver)
   glue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_DISTRIBUTION_CUSTOMIZATION);
 
   Assert.equal(Services.prefs.getCharPref("distribution.test.string"), "Test String");
-  Assert.throws(() => Services.prefs.getCharPref("distribution.test.string.noquotes"));
+  Assert.equal(Services.prefs.getCharPref("distribution.test.string.noquotes"), "Test String");
   Assert.equal(Services.prefs.getIntPref("distribution.test.int"), 777);
   Assert.equal(Services.prefs.getBoolPref("distribution.test.bool.true"), true);
   Assert.equal(Services.prefs.getBoolPref("distribution.test.bool.false"), false);
   Assert.equal(Services.prefs.getComplexValue("distribution.test.locale", Ci.nsIPrefLocalizedString).data, "en-US");
   Assert.equal(Services.prefs.getComplexValue("distribution.test.language.en", Ci.nsIPrefLocalizedString).data, "en");
   Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.en-US", Ci.nsIPrefLocalizedString).data, "en-US");
   Assert.throws(() => Services.prefs.getComplexValue("distribution.test.locale.de", Ci.nsIPrefLocalizedString));
   // This value was never set because of the empty language specific pref