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 353801 036c763dedca215c00853146dc050a766dfd1f04
parent 353800 6741a3b28c55793fc1048afede74a305cc778165
child 353802 e021755615c6884388a3a67d0107c0563accbbbe
child 353817 f60bd9567a058bf0d4d5b35f0d53a46eba0aa500
child 354431 f13d15883b04827646d1f006891ad00ec660503f
child 355197 115668ec768e71b9f216ad1306165080eb0dd792
child 355483 94721323a4372010941dcce034093d3f0d1ac95c
push id15951
push usernhnt11@gmail.com
push dateTue, 19 Apr 2016 23:28:52 +0000
reviewersaswan
bugs1196283
milestone48.0a1
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]