Bug 1320181 - Storage sanitizer should return an empty object belonging to the correct scope. draft
authorLuca Greco <lgreco@mozilla.com>
Mon, 28 Nov 2016 20:11:06 +0100
changeset 445801 9c9b96b19f87694ea6b80728a25946f943d5dbe6
parent 444674 bc4ed3faa33e589fcc1b86221d837b98af3551b7
child 538614 4d922d17d66cfbe6c6f3ac0072a26a12713e768a
push id37611
push userluca.greco@alcacoop.it
push dateWed, 30 Nov 2016 08:06:44 +0000
bugs1320181
milestone53.0a1
Bug 1320181 - Storage sanitizer should return an empty object belonging to the correct scope. MozReview-Commit-ID: Bx95Cgx0EuH
toolkit/components/extensions/ExtensionStorage.jsm
--- a/toolkit/components/extensions/ExtensionStorage.jsm
+++ b/toolkit/components/extensions/ExtensionStorage.jsm
@@ -13,17 +13,30 @@ const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
                                   "resource://gre/modules/AsyncShutdown.jsm");
 
-function jsonReplacer(key, value) {
+/**
+ * Helper function used to sanitize the objects that have to be saved in the ExtensionStorage.
+ *
+ * @param {BaseContext} context
+ *   The current extension context.
+ * @param {string} key
+ *   The key of the current JSON property.
+ * @param {any} value
+ *   The value of the current JSON property.
+ *
+ * @returns {any}
+ *   The sanitized value of the property.
+ */
+function jsonReplacer(context, key, value) {
   switch (typeof(value)) {
     // Serialize primitive types as-is.
     case "string":
     case "number":
     case "boolean":
       return value;
 
     case "object":
@@ -44,17 +57,17 @@ function jsonReplacer(key, value) {
           return String(value);
       }
       break;
   }
 
   if (!key) {
     // If this is the root object, and we can't serialize it, serialize
     // the value to an empty object.
-    return {};
+    return new context.cloneScope.Object();
   }
 
   // Everything else, omit entirely.
   return undefined;
 }
 
 this.ExtensionStorage = {
   cache: new Map(),
@@ -67,17 +80,17 @@ this.ExtensionStorage = {
    * @param {value} value
    *        The value to sanitize.
    * @param {Context} context
    *        The extension context in which to sanitize the value
    * @returns {value}
    *        The sanitized value.
    */
   sanitize(value, context) {
-    let json = context.jsonStringify(value, jsonReplacer);
+    let json = context.jsonStringify(value, jsonReplacer.bind(null, context));
     return JSON.parse(json);
   },
 
   getExtensionDir(extensionId) {
     return OS.Path.join(this.extensionDir, extensionId);
   },
 
   getStorageFile(extensionId) {