Bug 397937 - Handle view-source on malware and error pages more gracefully, r=mconnor
--- 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":