Bug 741526 - Mozilla central mozapps implementation ignores Content-Type. r=fabrice, a=blocking-basecamp
authorMarco Castelluccio <mar.castelluccio@studenti.unina.it>
Thu, 29 Nov 2012 17:52:02 -0500
changeset 118582 55e7b7ee8d30ff7decfbf1bd5d2849d9baa930cc
parent 118581 21c9aecc314f171b9127499291e3e4845627baed
child 118583 9eae59ffecdd5db3baf1b16b53dd08434f8b8cbc
push idunknown
push userunknown
push dateunknown
reviewersfabrice, blocking-basecamp
bugs741526
milestone19.0a2
Bug 741526 - Mozilla central mozapps implementation ignores Content-Type. r=fabrice, a=blocking-basecamp
dom/apps/src/AppsUtils.jsm
dom/apps/src/Webapps.js
dom/tests/mochitest/webapps/apps/Makefile.in
dom/tests/mochitest/webapps/apps/installs_allowed_from_chrome_mochitests.webapp^headers^
dom/tests/mochitest/webapps/apps/installs_allowed_from_example.com.webapp^headers^
dom/tests/mochitest/webapps/test_install_errors.xul
--- a/dom/apps/src/AppsUtils.jsm
+++ b/dom/apps/src/AppsUtils.jsm
@@ -179,16 +179,25 @@ this.AppsUtils = {
       if (checkAbsoluteEntryPoints(aManifest.locales[localeName].entry_points)) {
         return false;
       }
     }
 
     return true;
   },
 
+  checkManifestContentType: function
+     checkManifestContentType(installOrigin, webappOrigin, contentType) {
+    if (installOrigin != webappOrigin &&
+        contentType != "application/x-web-app-manifest+json") {
+      return false;
+    }
+    return true;
+  },
+
   /**
    * Determines whether the manifest allows installs for the given origin.
    * @param object aManifest
    * @param string aInstallOrigin
    * @return boolean
    **/
   checkInstallAllowed: function checkInstallAllowed(aManifest, aInstallOrigin) {
     if (!aManifest.installs_allowed_from) {
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -100,16 +100,22 @@ WebappsRegistry.prototype = {
     let request = this.createRequest();
     let requestID = this.getRequestId(request);
     let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
     xhr.open("GET", aURL, true);
     xhr.channel.loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS;
 
     xhr.addEventListener("load", (function() {
       if (xhr.status == 200) {
+        if (!AppsUtils.checkManifestContentType(installOrigin, this._getOrigin(aURL),
+                                                xhr.getResponseHeader("content-type"))) {
+          Services.DOMRequest.fireError(request, "INVALID_MANIFEST");
+          return;
+        }
+
         let manifest;
         try {
           manifest = JSON.parse(xhr.responseText, installOrigin);
         } catch (e) {
           Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR");
           Cu.reportError("Error installing app from: " + installOrigin + ": " + "MANIFEST_PARSE_ERROR");
           return;
         }
@@ -209,16 +215,22 @@ WebappsRegistry.prototype = {
     let categories = (aParams && aParams.categories &&
                       Array.isArray(aParams.categories)) ? aParams.categories : [];
     let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
     xhr.open("GET", aURL, true);
     xhr.channel.loadFlags |= Ci.nsIRequest.VALIDATE_ALWAYS;
 
     xhr.addEventListener("load", (function() {
       if (xhr.status == 200) {
+        if (!AppsUtils.checkManifestContentType(installOrigin, this._getOrigin(aURL),
+                                                xhr.getResponseHeader("content-type"))) {
+          Services.DOMRequest.fireError(request, "INVALID_MANIFEST");
+          return;
+        }
+
         let manifest;
         try {
           manifest = JSON.parse(xhr.responseText, installOrigin);
         } catch(e) {
           Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR");
           return;
         }
         if (!(AppsUtils.checkManifest(manifest) &&
--- a/dom/tests/mochitest/webapps/apps/Makefile.in
+++ b/dom/tests/mochitest/webapps/apps/Makefile.in
@@ -18,17 +18,19 @@ MOCHITEST_CHROME_FILES	= \
     json_syntax_error.webapp \
     json_syntax_error.webapp^headers^ \
     no_delegated_install.webapp \
     no_delegated_install.webapp^headers^ \
     bad_content_type.webapp \
     utf8.webapp \
     utf8.webapp^headers^ \
     installs_allowed_from_chrome_mochitests.webapp \
+    installs_allowed_from_chrome_mochitests.webapp^headers^ \
     installs_allowed_from_example.com.webapp \
+    installs_allowed_from_example.com.webapp^headers^ \
     invalid_launch_path.webapp \
     invalid_launch_path.webapp^headers^ \
     invalid_launch_path2.webapp \
     invalid_launch_path2.webapp^headers^ \
     invalid_entry_point.webapp \
     invalid_entry_point.webapp^headers^ \
     invalid_locale_entry_point.webapp \
     invalid_locale_entry_point.webapp^headers^ \
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/webapps/apps/installs_allowed_from_chrome_mochitests.webapp^headers^
@@ -0,0 +1,1 @@
+Content-Type: application/x-web-app-manifest+json
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/webapps/apps/installs_allowed_from_example.com.webapp^headers^
@@ -0,0 +1,1 @@
+Content-Type: application/x-web-app-manifest+json
--- a/dom/tests/mochitest/webapps/test_install_errors.xul
+++ b/dom/tests/mochitest/webapps/test_install_errors.xul
@@ -92,17 +92,17 @@ function invalidContent(next) {
   var request = navigator.mozApps.install(url, null);
 
   request.onerror = function onInstallError() {
     is(this.error.name, "INVALID_MANIFEST", "manifest with bad content type");
     next();
   };
 
   request.onsuccess = function onInstall() {
-    todo(false, "manifest with bad content type fails");
+    ok(false, "manifest with bad content type should fail");
     this.result.uninstall().onsuccess = function onUninstall() {
       next();
     };
   };
 }
 
 function invalidLaunchPath(next) {
   var url = "http://test/chrome/dom/tests/mochitest/webapps/apps/invalid_launch_path.webapp";