Bug 1217586 - fix modifier click / enter on SVG links by passing node principal, r=felipe
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Thu, 12 Nov 2015 17:27:38 +0000
changeset 308800 bece86c18efcf855e81cf10f9417b10f1b0a1d5d
parent 308799 1aa4c60fbfdbf868dc9f6775053b686889fb379a
child 308801 186e5680b95a38845fe8fa7fa59656a6de0b496e
push id7526
push usermleibovic@mozilla.com
push dateFri, 13 Nov 2015 20:37:49 +0000
reviewersfelipe
bugs1217586
milestone45.0a1
Bug 1217586 - fix modifier click / enter on SVG links by passing node principal, r=felipe
browser/base/content/content.js
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -375,17 +375,17 @@ var ClickEventHandler = {
     } else if (ownerDoc.documentURI.startsWith("about:blocked")) {
       this.onAboutBlocked(originalTarget, ownerDoc);
       return;
     } else if (ownerDoc.documentURI.startsWith("about:neterror")) {
       this.onAboutNetError(event, ownerDoc.documentURI);
       return;
     }
 
-    let [href, node] = this._hrefAndLinkNodeForClickEvent(event);
+    let [href, node, principal] = this._hrefAndLinkNodeForClickEvent(event);
 
     // get referrer attribute from clicked link and parse it
     // if per element referrer is enabled, the element referrer overrules
     // the document wide referrer
     let referrerPolicy = ownerDoc.referrerPolicy;
     if (Services.prefs.getBoolPref("network.http.enablePerElementReferrer") &&
         node) {
       let referrerAttrValue = Services.netUtils.parseAttributePolicyString(node.
@@ -397,17 +397,17 @@ var ClickEventHandler = {
 
     let json = { button: event.button, shiftKey: event.shiftKey,
                  ctrlKey: event.ctrlKey, metaKey: event.metaKey,
                  altKey: event.altKey, href: null, title: null,
                  bookmark: false, referrerPolicy: referrerPolicy };
 
     if (href) {
       try {
-        BrowserUtils.urlSecurityCheck(href, node.ownerDocument.nodePrincipal);
+        BrowserUtils.urlSecurityCheck(href, principal);
       } catch (e) {
         return;
       }
 
       json.href = href;
       if (node) {
         json.title = node.getAttribute("title");
         if (event.button == 0 && !event.ctrlKey && !event.shiftKey &&
@@ -483,53 +483,56 @@ var ClickEventHandler = {
     }
   },
 
   /**
    * Extracts linkNode and href for the current click target.
    *
    * @param event
    *        The click event.
-   * @return [href, linkNode].
+   * @return [href, linkNode, linkPrincipal].
    *
    * @note linkNode will be null if the click wasn't on an anchor
-   *       element (or XLink).
+   *       element. This includes SVG links, because callers expect |node|
+   *       to behave like an <a> element, which SVG links (XLink) don't.
    */
   _hrefAndLinkNodeForClickEvent: function(event) {
     function isHTMLLink(aNode) {
       // Be consistent with what nsContextMenu.js does.
       return ((aNode instanceof content.HTMLAnchorElement && aNode.href) ||
               (aNode instanceof content.HTMLAreaElement && aNode.href) ||
               aNode instanceof content.HTMLLinkElement);
     }
 
     let node = event.target;
     while (node && !isHTMLLink(node)) {
       node = node.parentNode;
     }
 
     if (node)
-      return [node.href, node];
+      return [node.href, node, node.ownerDocument.nodePrincipal];
 
     // If there is no linkNode, try simple XLink.
     let href, baseURI;
     node = event.target;
     while (node && !href) {
       if (node.nodeType == content.Node.ELEMENT_NODE) {
         href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href");
         if (href)
           baseURI = node.ownerDocument.baseURIObject;
+        break;
       }
       node = node.parentNode;
     }
 
     // In case of XLink, we don't return the node we got href from since
     // callers expect <a>-like elements.
     // Note: makeURI() will throw if aUri is not a valid URI.
-    return [href ? BrowserUtils.makeURI(href, null, baseURI).spec : null, null];
+    return [href ? BrowserUtils.makeURI(href, null, baseURI).spec : null, null,
+            node && node.ownerDocument.nodePrincipal];
   }
 };
 ClickEventHandler.init();
 
 ContentLinkHandler.init(this);
 
 // TODO: Load this lazily so the JSM is run only if a relevant event/message fires.
 var pluginContent = new PluginContent(global);