Bug 887773 - Make plugin doorhanger work for data URLs & fixup permission usage. r=gavin
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Wed, 03 Jul 2013 15:01:06 +0200
changeset 151728 43e5b71e1680a88b7b346e6c429feb44908a4d0f
parent 151727 3f9a172ccaf4730874c3e41fbecae08a075259f2
child 151729 0a1a5b7f6f8d79c728980dfb687598779c16305a
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs887773
milestone25.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 887773 - Make plugin doorhanger work for data URLs & fixup permission usage. r=gavin
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);
@@ -506,17 +506,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;
     }
@@ -625,23 +626,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;
       }
@@ -661,17 +677,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 = {
       case "continue":
         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
@@ -1595,17 +1595,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");
@@ -1758,19 +1759,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]));