Bug 887773 - Make plugin doorhanger work for data URLs & fixup permission usage. r=gavin, a=bajaj
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Wed, 03 Jul 2013 15:01:06 +0200
changeset 148145 135008e6323fa56ea061c9aeb7c62a0530f77404
parent 148144 64c5cc9bad2e84a9b1d6392b095ad06a75b94a4e
child 148146 44e40c775ff7e00c3c0c8493474d0ffa360db287
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin, bajaj
bugs887773
milestone24.0a2
Bug 887773 - Make plugin doorhanger work for data URLs & fixup permission usage. r=gavin, a=bajaj
browser/base/content/browser-plugins.js
browser/base/content/urlbarBindings.xml
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -340,18 +340,18 @@ var gPluginHandler = {
     // if this isn't a known plugin, we can't activate it
     // (this also guards pluginHost.getPermissionStringForType against
     // unexpected input)
     if (!gPluginHandler.isKnownPlugin(objLoadingContent))
       return false;
 
     let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
     let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
-    let browser = gBrowser.getBrowserForDocument(objLoadingContent.ownerDocument.defaultView.top.document);
-    let pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
+    let principal = objLoadingContent.ownerDocument.defaultView.top.document.nodePrincipal;
+    let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
 
     let isFallbackTypeValid =
       objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
       objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
 
     if (objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) {
       // checking if play preview is subject to CTP rules
       let playPreviewInfo = pluginHost.getPlayPreviewInfo(objLoadingContent.actualType);
@@ -505,17 +505,18 @@ var gPluginHandler = {
     let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
     let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
     let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
     // guard against giving pluginHost.getPermissionStringForType a type
     // not associated with any known plugin
     if (!gPluginHandler.isKnownPlugin(objLoadingContent))
       return;
     let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
-    let pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
+    let principal = doc.defaultView.top.document.nodePrincipal;
+    let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
 
     let overlay = doc.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
 
     if (pluginPermission == Ci.nsIPermissionManager.DENY_ACTION) {
       if (overlay)
         overlay.style.visibility = "hidden";
       return;
     }
@@ -624,23 +625,38 @@ var gPluginHandler = {
     }
     else if (event == "dismissed") {
       // Once the popup is dismissed, clicking the icon should show the full
       // list again
       this.options.primaryPlugin = null;
     }
   },
 
+  // Match the behaviour of nsPermissionManager
+  _getHostFromPrincipal: function PH_getHostFromPrincipal(principal) {
+    if (!principal.URI || principal.URI.schemeIs("moz-nullprincipal")) {
+      return "(null)";
+    }
+
+    try {
+      if (principal.URI.host)
+        return principal.URI.host;
+    } catch (e) {}
+
+    return principal.origin;
+  },
+
   _makeCenterActions: function PH_makeCenterActions(notification) {
-    let browser = notification.browser;
-    let contentWindow = browser.contentWindow;
+    let contentWindow = notification.browser.contentWindow;
     let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
 
-    let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(browser.currentURI);
+    let principal = contentWindow.document.nodePrincipal;
+    // This matches the behavior of nsPermssionManager, used for display purposes only
+    let principalHost = this._getHostFromPrincipal(principal);
 
     let centerActions = [];
     let pluginsFound = new Set();
     for (let plugin of cwu.plugins) {
       plugin.QueryInterface(Ci.nsIObjectLoadingContent);
       if (plugin.getContentTypeForMIMEType(plugin.actualType) != Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
         continue;
       }
@@ -660,17 +676,17 @@ var gPluginHandler = {
       // the tighter loop above.
       let permissionObj = Services.perms.
         getPermissionObject(principal, pluginInfo.permissionString, false);
       if (permissionObj) {
         pluginInfo.pluginPermissionHost = permissionObj.host;
         pluginInfo.pluginPermissionType = permissionObj.expireType;
       }
       else {
-        pluginInfo.pluginPermissionHost = browser.currentURI.host;
+        pluginInfo.pluginPermissionHost = principalHost;
         pluginInfo.pluginPermissionType = undefined;
       }
 
       let url;
       // TODO: allow the blocklist to specify a better link, bug 873093
       if (pluginInfo.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
         url = Services.urlFormatter.formatURLPref("plugins.update.url");
       }
@@ -724,28 +740,29 @@ var gPluginHandler = {
         break;
 
       default:
         Cu.reportError(Error("Unexpected plugin state: " + aNewState));
         return;
     }
 
     let browser = aNotification.browser;
+    let contentWindow = browser.contentWindow;
     if (aNewState != "continue") {
-      Services.perms.add(browser.currentURI, aPluginInfo.permissionString,
-                         permission, expireType, expireTime);
+      let principal = contentWindow.document.nodePrincipal;
+      Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
+                                      permission, expireType, expireTime);
 
       if (aNewState == "block") {
         return;
       }
     }
 
     // Manually activate the plugins that would have been automatically
     // activated.
-    let contentWindow = browser.contentWindow;
     let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
     let plugins = cwu.plugins;
     let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
 
     for (let plugin of plugins) {
       plugin.QueryInterface(Ci.nsIObjectLoadingContent);
       // canActivatePlugin will return false if this isn't a known plugin type,
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1585,17 +1585,18 @@
           var grid = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-center-box");
 
           if (this._states.SINGLE == state) {
             grid.hidden = true;
             this._setupSingleState();
             return;
           }
 
-          this._setupDescription("pluginActivateMultiple.message");
+          let host = gPluginHandler._getHostFromPrincipal(this.notification.browser.contentWindow.document.nodePrincipal);
+          this._setupDescription("pluginActivateMultiple.message", null, host);
 
           var showBox = document.getAnonymousElementByAttribute(this, "anonid", "plugin-notification-showbox");
 
           var dialogStrings = Services.strings.createBundle("chrome://global/locale/dialog.properties");
           this._primaryButton.label = dialogStrings.GetStringFromName("button-accept");
           this._primaryButton.setAttribute("default", "true");
 
           this._secondaryButton.label = dialogStrings.GetStringFromName("button-cancel");
@@ -1748,19 +1749,16 @@
         <parameter name="host" />
         <body><![CDATA[
           var bsn = this._brandShortName;
           var span = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
           while (span.lastChild) {
             span.removeChild(span.lastChild);
           }
 
-          if (!host) {
-            host = this.notification.browser.currentURI.host;
-          }
           var args = ["__host__", this._brandShortName];
           if (pluginName) {
             args.unshift(pluginName);
           }
           var bases = gNavigatorBundle.getFormattedString(baseString, args).
             split("__host__", 2);
 
           span.appendChild(document.createTextNode(bases[0]));