Bug 584785: Restrict sharing based on URI scheme [r=mfinkle]
authorMatt Brubeck <mbrubeck@mozilla.com>
Mon, 23 Aug 2010 17:27:40 -0700
changeset 66465 4e200383acfecd7d7496cb5de17f539e40d467a9
parent 66464 d99901d1331af55002f599d434a868176230685f
child 66466 ca2779db976f198123fa6ea0334cc7b265da323a
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs584785
Bug 584785: Restrict sharing based on URI scheme [r=mfinkle]
mobile/chrome/content/Util.js
mobile/chrome/content/browser-ui.js
mobile/chrome/content/browser.xul
mobile/chrome/content/content.js
--- a/mobile/chrome/content/Util.js
+++ b/mobile/chrome/content/Util.js
@@ -136,16 +136,21 @@ let Util = {
     // Note:  makeURI() will throw if url is not a valid URI
     return this.makeURI(url, null, this.makeURI(base)).spec;
   },
 
   isLocalScheme: function isLocalScheme(aURL) {
     return (aURL.indexOf("about:") == 0 && aURL != "about:blank") || aURL.indexOf("chrome:") == 0;
   },
 
+  isShareableScheme: function isShareableScheme(aProtocol) {
+    let dontShare = /^(chrome|about|file|javascript|resource)$/;
+    return (aProtocol && !dontShare.test(aProtocol));
+  },
+
   clamp: function(num, min, max) {
     return Math.max(min, Math.min(max, num));
   },
 
   /**
    * Determines whether a home page override is needed.
    * Returns:
    *  "new profile" if this is the first run with a new profile.
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -1008,16 +1008,17 @@ var TapHighlightHelper = {
   }
 };
 
 var PageActions = {
   init: function init() {
     this.register("pageaction-reset", this.updatePagePermissions, this);
     this.register("pageaction-password", this.updateForgetPassword, this);
     this.register("pageaction-saveas", this.updatePageSaveAs, this);
+    this.register("pageaction-share", this.updateShare, this);
     this.register("pageaction-search", BrowserSearch.updatePageSearchEngines, BrowserSearch);
   },
 
   /**
    * @param aId id of a pageaction element
    * @param aCallback function that takes an element and returns true if it should be visible
    * @param aThisObj (optional) scope object for aCallback
    */
@@ -1165,16 +1166,20 @@ var PageActions = {
   },
 
   updatePageSaveAs: function updatePageSaveAs(aNode) {
     // Check for local XUL content
     let contentDocument = Browser.selectedBrowser.contentDocument;
     return !(contentDocument && contentDocument instanceof XULDocument);
   },
 
+  updateShare: function updateShare(aNode) {
+    return Util.isShareableScheme(Browser.selectedBrowser.currentURI.scheme);
+  },
+
   hideItem: function hideItem(aNode) {
     aNode.hidden = true;
     this._updateAttributes();
   },
 
   _updateAttributes: function _updateAttributes() {
     let container = document.getElementById("pageactions-container");
     let visibleNodes = container.querySelectorAll("pageaction:not([hidden=true])");
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -528,20 +528,20 @@
         </hbox>
         <richlistbox id="context-commands" onclick="ContextHelper.hide();">
           <richlistitem class="context-command" id="context-openinnewtab" type="link-saveable" onclick="ContextCommands.openInNewTab();">
             <label value="&contextOpenInNewTab.label;"/>
           </richlistitem>
           <richlistitem class="context-command" id="context-saveimage" type="image-loaded" onclick="ContextCommands.saveImage();">
             <label value="&contextSaveImage.label;"/>
           </richlistitem>
-          <richlistitem class="context-command" id="context-share-link" type="link" onclick="ContextCommands.shareLink();">
+          <richlistitem class="context-command" id="context-share-link" type="link-shareable" onclick="ContextCommands.shareLink();">
             <label value="&contextShareLink.label;"/>
           </richlistitem>
-          <richlistitem class="context-command" id="context-share-image" type="image" onclick="ContextCommands.shareMedia();">
+          <richlistitem class="context-command" id="context-share-image" type="image-shareable" onclick="ContextCommands.shareMedia();">
             <label value="&contextShareImage.label;"/>
           </richlistitem>
           <richlistitem class="context-command" id="context-editbookmark" type="edit-bookmark" onclick="ContextCommands.editBookmark();">
             <label value="&contextEditBookmark.label;"/>
           </richlistitem>
           <richlistitem class="context-command" id="context-removebookmark" type="edit-bookmark" onclick="ContextCommands.removeBookmark();">
             <label value="&contextRemoveBookmark.label;"/>
           </richlistitem>
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -843,16 +843,28 @@ ContextHandler.registerType("callto", fu
   return protocol == "tel" || protocol == "callto" || protocol == "sip" || protocol == "voipto";
 });
 
 ContextHandler.registerType("link-saveable", function(aState, aElement) {
   let protocol = aState.linkProtocol;
   return (protocol && protocol != "mailto" && protocol != "javascript" && protocol != "news" && protocol != "snews");
 });
 
+ContextHandler.registerType("link-shareable", function(aState, aElement) {
+  return Util.isShareableScheme(aState.linkProtocol);
+});
+
+ContextHandler.registerType("image-shareable", function(aState, aElement) {
+  if (!aState.mediaURL)
+    return false;
+
+  let protocol = ContextHandler._getProtocol(ContextHandler._getURI(aState.mediaURL));
+  return Util.isShareableScheme(protocol);
+});
+
 ContextHandler.registerType("image-loaded", function(aState, aElement) {
   if (aState.types.indexOf("image") != -1) {
     let request = aElement.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
     if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
       return true;
   }
   return false;
 });