Bug 1196283: [webext] Support comments in JSON files. r=aswan
authorKris Maglione <maglione.k@gmail.com>
Tue, 19 Apr 2016 13:18:22 -0700
changeset 331647 036c763dedca215c00853146dc050a766dfd1f04
parent 331646 6741a3b28c55793fc1048afede74a305cc778165
child 331648 f60bd9567a058bf0d4d5b35f0d53a46eba0aa500
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1196283
milestone48.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 1196283: [webext] Support comments in JSON files. r=aswan MozReview-Commit-ID: Ex4ewLH8xQc
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/test/xpcshell/head.js
toolkit/components/extensions/test/xpcshell/test_ext_json_parser.js
toolkit/components/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -99,16 +99,28 @@ var {
   injectAPI,
   instanceOf,
   extend,
   flushJarCache,
 } = ExtensionUtils;
 
 const LOGGER_ID_BASE = "addons.webextension.";
 
+const COMMENT_REGEXP = new RegExp(String.raw`
+    ^
+    (
+      (?:
+        [^"] |
+        " (?:[^"\\] | \\.)* "
+      )*?
+    )
+
+    //.*
+  `.replace(/\s+/g, ""), "gm");
+
 var scriptScope = this;
 
 var ExtensionPage, GlobalManager;
 
 // This object loads the ext-*.js scripts that define the extension API.
 var Management = {
   initialized: null,
   scopes: [],
@@ -657,16 +669,19 @@ ExtensionData.prototype = {
       NetUtil.asyncFetch({uri, loadUsingSystemPrincipal: true}, (inputStream, status) => {
         if (!Components.isSuccessCode(status)) {
           reject(new Error(status));
           return;
         }
         try {
           let text = NetUtil.readInputStreamToString(inputStream, inputStream.available(),
                                                      {charset: "utf-8"});
+
+          text = text.replace(COMMENT_REGEXP, "$1");
+
           resolve(JSON.parse(text));
         } catch (e) {
           reject(e);
         }
       });
     });
   },
 
--- a/toolkit/components/extensions/test/xpcshell/head.js
+++ b/toolkit/components/extensions/test/xpcshell/head.js
@@ -1,10 +1,14 @@
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "Extension",
+                                  "resource://gre/modules/Extension.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ExtensionData",
+                                  "resource://gre/modules/Extension.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_json_parser.js
@@ -0,0 +1,37 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(function* test_json_parser() {
+  const ID = "json@test.web.extension";
+
+  let xpi = Extension.generateXPI(ID, {
+    files: {
+      "manifest.json": String.raw`{
+        // This is a manifest.
+        "applications": {"gecko": {"id": "${ID}"}},
+        "name": "This \" is // not a comment",
+        "version": "0.1\\" // , "description": "This is not a description"
+      }`,
+    },
+  });
+
+  let expectedManifest = {
+    "applications": {"gecko": {"id": ID}},
+    "name": "This \" is // not a comment",
+    "version": "0.1\\",
+  };
+
+  let fileURI = Services.io.newFileURI(xpi);
+  let uri = NetUtil.newURI(`jar:${fileURI.spec}!/`);
+
+  let extension = new ExtensionData(uri);
+
+  yield extension.readManifest();
+
+  Assert.deepEqual(extension.rawManifest, expectedManifest,
+                   "Manifest with correctly-filtered comments");
+
+  Services.obs.notifyObservers(xpi, "flush-cache-entry", null);
+  xpi.remove(false);
+});
--- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini
@@ -2,10 +2,11 @@
 head = head.js
 tail =
 firefox-appdir = browser
 skip-if = toolkit == 'gonk'
 
 [test_locale_data.js]
 [test_locale_converter.js]
 [test_ext_contexts.js]
+[test_ext_json_parser.js]
 [test_ext_schemas.js]
-[test_getAPILevelForWindow.js]
\ No newline at end of file
+[test_getAPILevelForWindow.js]