Bug 397937 - Handle view-source on malware and error pages more gracefully, r=mconnor
authorBlair McBride <bmcbride@mozilla.com>
Wed, 23 Dec 2009 22:03:37 -0500
changeset 36642 454c8ec86b1e6c6fbf5f9b6af69c9c48927fb562
parent 36641 0839d1096d9d4f79cce109afebe4fe02d49a0d41
child 36644 7a68e56bb96a082845105d9a8c3f721b185bbaf5
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmconnor
bugs397937
milestone1.9.3a1pre
Bug 397937 - Handle view-source on malware and error pages more gracefully, r=mconnor
browser/components/safebrowsing/content/blockedSite.xhtml
toolkit/components/viewsource/content/viewSource.js
--- a/browser/components/safebrowsing/content/blockedSite.xhtml
+++ b/browser/components/safebrowsing/content/blockedSite.xhtml
@@ -73,33 +73,42 @@
         var error = url.search(/e\=/);
         var duffUrl = url.search(/\&u\=/);
         return decodeURIComponent(url.slice(error + 2, duffUrl));
       }
 
       function getURL()
       {
         var url = document.documentURI;
-        var index = url.search(/u\=/);
+        var match = url.match(/&u=([^&]+)&/);
 
-        // index == -1 if not found; if so, return an empty string
+        // match == null if not found; if so, return an empty string
         // instead of what would turn out to be portions of the URI
-        if (index == -1)
+        if (!match)
           return "";
 
-        return decodeURIComponent(url.slice(index + 2));
+        url = decodeURIComponent(match[1]);
+
+        // If this is a view-source page, then get then real URI of the page
+        if (/^view-source\:/.test(url))
+          url = url.slice(12);
+        return url;
       }
       
       /**
-       * Attempt to parse the result of getURL and extract a hostname.  Fail back
+       * Attempt to get the hostname via document.location.  Fail back
        * to getURL so that we always return something meaningful.
        */
       function getHostString()
       {
-        return document.location.hostname;
+        try {
+          return document.location.hostname;
+        } catch (e) {
+          return getURL();
+        }
       }
       
       function initPage()
       {
         // Handoff to the appropriate initializer, based on error code
         switch(getErrorCode()) {
           case "malwareBlocked" :
             initPage_malware();
--- a/toolkit/components/viewsource/content/viewSource.js
+++ b/toolkit/components/viewsource/content/viewSource.js
@@ -117,16 +117,17 @@ function viewSource(url)
 {
   if (!url)
     return; // throw Components.results.NS_ERROR_FAILURE;
     
   var viewSrcUrl = "view-source:" + url;
 
   gBrowser.addEventListener("pagehide", onUnloadContent, true);
   gBrowser.addEventListener("pageshow", onLoadContent, true);
+  gBrowser.addEventListener("command", onCommandContent, false);
 
   var loadFromURL = true;
 
   // Parse the 'arguments' supplied with the dialog.
   //    arg[0] - URL string.
   //    arg[1] - Charset value in the form 'charset=xxx'.
   //    arg[2] - Page descriptor used to load content from the cache.
   //    arg[3] - Line number to go to.
@@ -266,16 +267,73 @@ function onUnloadContent()
   // window has gone away.
   if (gSelectionListener.attached) {
     window.content.getSelection().QueryInterface(Ci.nsISelectionPrivate)
           .removeSelectionListener(gSelectionListener);
     gSelectionListener.attached = false;
   }
 }
 
+/**
+ * Handle command events bubbling up from error page content
+ */
+function onCommandContent(event) {
+  // Don't trust synthetic events
+  if (!event.isTrusted)
+    return;
+
+  var target = event.originalTarget;
+  var errorDoc = target.ownerDocument;
+  
+  var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"]
+                    .getService(Ci.nsIURLFormatter);
+
+  if (/^about:blocked/.test(errorDoc.documentURI)) {
+    // The event came from a button on a malware/phishing block page
+    // First check whether it's malware or phishing, so that we can
+    // use the right strings/links
+    var isMalware = /e=malwareBlocked/.test(errorDoc.documentURI);
+    
+    if (target == errorDoc.getElementById('getMeOutButton')) {
+      // Instead of loading some safe page, just close the window
+      window.close();
+    } else if (target == errorDoc.getElementById('reportButton')) {
+      // This is the "Why is this site blocked" button.  For malware,
+      // we can fetch a site-specific report, for phishing, we redirect
+      // to the generic page describing phishing protection.
+
+      if (isMalware) {
+        // Get the stop badware "why is this blocked" report url,
+        // append the current url, and go there.
+        try {
+          let reportURL = formatter.formatURLPref("browser.safebrowsing.malware.reportURL", true);
+          reportURL += errorDoc.location.href.slice(12);
+          openURL(reportURL);
+        } catch (e) {
+          Components.utils.reportError("Couldn't get malware report URL: " + e);
+        }
+      } else { // It's a phishing site, not malware
+        try {
+          var infoURL = formatter.formatURLPref("browser.safebrowsing.warning.infoURL", true);
+          openURL(infoURL);
+        } catch (e) {
+          Components.utils.reportError("Couldn't get phishing info URL: " + e);
+        }
+      }
+    } else if (target == errorDoc.getElementById('ignoreWarningButton')) {
+      // Allow users to override and continue through to the site,
+      // but add a notify bar as a reminder, so that they don't lose
+      // track after, e.g., tab switching.
+      gBrowser.loadURIWithFlags(content.location.href,
+                                Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
+                                null, null, null);
+    }
+  }
+}
+
 function HandleAppCommandEvent(evt)
 {
   evt.stopPropagation();
   switch (evt.command) {
     case "Back":
       BrowserBack();
       break;
     case "Forward":