Bug 724161: simplify some javascript:/data: drop checks, r=dao, a=akeybl
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3527,22 +3527,24 @@
this.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
// We need to select the tab after we've done
// swapBrowsersAndCloseOther, so that the updateCurrentBrowser
// it triggers will correctly update our URL bar.
this.tabbrowser.selectedTab = newTab;
} else {
- let url = browserDragAndDrop.drop(event, { });
+ // Pass true to disallow dropping javascript: or data: urls
+ let url;
+ try {
+ url = browserDragAndDrop.drop(event, { }, true);
+ } catch (ex) {}
// valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
- // Also disallow dropping javascript: or data: urls--bail out
- if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
- /^\s*(javascript|data):/.test(url))
+ if (!url || url.indexOf(" ") != -1)
return;
let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
if (event.shiftKey)
bgLoad = !bgLoad;
let tab = this._getDragTargetTab(event);
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -252,16 +252,17 @@ endif
test_bug628179.html \
browser_wyciwyg_urlbarCopying.js \
test_wyciwyg_copying.html \
authenticate.sjs \
browser_minimize.js \
browser_aboutSyncProgress.js \
browser_middleMouse_inherit.js \
redirect_bug623155.sjs \
+ browser_tabDrop.js \
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
_BROWSER_FILES += \
browser_bug462289.js \
$(NULL)
else
_BROWSER_FILES += \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_tabDrop.js
@@ -0,0 +1,71 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+ waitForExplicitFinish();
+
+ let newTab = gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
+ registerCleanupFunction(function () {
+ gBrowser.removeTab(newTab);
+ });
+
+ let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+ let chromeUtils = {};
+ scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", chromeUtils);
+
+ let tabContainer = gBrowser.tabContainer;
+ var receivedDropCount = 0;
+ function dropListener() {
+ receivedDropCount++;
+ if (receivedDropCount == triggeredDropCount) {
+ is(openedTabs, validDropCount, "correct number of tabs were opened");
+ executeSoon(finish);
+ }
+ }
+ tabContainer.addEventListener("drop", dropListener, false);
+ registerCleanupFunction(function () {
+ tabContainer.removeEventListener("drop", dropListener, false);
+ });
+
+ var openedTabs = 0;
+ function tabOpenListener(e) {
+ openedTabs++;
+ let tab = e.target;
+ executeSoon(function () {
+ gBrowser.removeTab(tab);
+ });
+ }
+
+ tabContainer.addEventListener("TabOpen", tabOpenListener, false);
+ registerCleanupFunction(function () {
+ tabContainer.removeEventListener("TabOpen", tabOpenListener, false);
+ });
+
+ var triggeredDropCount = 0;
+ var validDropCount = 0;
+ function drop(text, valid) {
+ triggeredDropCount++;
+ if (valid)
+ validDropCount++;
+ executeSoon(function () {
+ // A drop type of "link" onto an existing tab would normally trigger a
+ // load in that same tab, but tabbrowser code in _getDragTargetTab treats
+ // drops on the outer edges of a tab differently (loading a new tab
+ // instead). The events created by synthesizeDrop have all of their
+ // coordinates set to 0 (screenX/screenY), so they're treated as drops
+ // on the outer edge of the tab, thus they open new tabs.
+ chromeUtils.synthesizeDrop(newTab, newTab, [[{type: "text/plain", data: text}]], "link", window, EventUtils);
+ });
+ }
+
+ // Begin and end with valid drops to make sure we wait for all drops before
+ // ending the test
+ drop("mochi.test/first", true);
+ drop("javascript:'bad'");
+ drop("jAvascript:'bad'");
+ drop("space bad");
+ drop("mochi.test/second", true);
+ drop("data:text/html,bad");
+ drop("mochi.test/third", true);
+}
--- a/toolkit/content/tests/browser/Makefile.in
+++ b/toolkit/content/tests/browser/Makefile.in
@@ -51,13 +51,14 @@ DIRS = \
include $(topsrcdir)/config/rules.mk
_BROWSER_TEST_FILES = \
browser_keyevents_during_autoscrolling.js \
browser_bug295977_autoscroll_overflow.js \
browser_bug594509.js \
browser_Geometry.js \
browser_save_resend_postdata.js \
+ browser_browserDrop.js \
browser_Services.js \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/browser_browserDrop.js
@@ -0,0 +1,61 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+ waitForExplicitFinish();
+
+ let newTab = gBrowser.selectedTab = gBrowser.addTab();
+ registerCleanupFunction(function () {
+ gBrowser.removeTab(newTab);
+ });
+
+ let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+ let chromeUtils = {};
+ scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", chromeUtils);
+
+ let browser = gBrowser.selectedBrowser;
+
+ var linkHandlerActivated = 0;
+ // Don't worry about clobbering the droppedLinkHandler, since we're closing
+ // this tab after the test anyways
+ browser.droppedLinkHandler = function dlh(e, url, name) {
+ linkHandlerActivated++;
+ ok(!/(javascript|data)/i.test(url), "javascript link should not be dropped");
+ }
+
+ var receivedDropCount = 0;
+ function dropListener() {
+ receivedDropCount++;
+ if (receivedDropCount == triggeredDropCount) {
+ // Wait for the browser's system-phase event handler to run.
+ executeSoon(function () {
+ is(linkHandlerActivated, validDropCount,
+ "link handler was called correct number of times");
+ finish();
+ })
+ }
+ }
+ browser.addEventListener("drop", dropListener, false);
+ registerCleanupFunction(function () {
+ browser.removeEventListener("drop", dropListener, false);
+ });
+
+ var triggeredDropCount = 0;
+ var validDropCount = 0;
+ function drop(text, valid) {
+ triggeredDropCount++;
+ if (valid)
+ validDropCount++;
+ executeSoon(function () {
+ chromeUtils.synthesizeDrop(browser, browser, [[{type: "text/plain", data: text}]], "copy", window, EventUtils);
+ });
+ }
+
+ drop("mochi.test/first", true);
+ drop("javascript:'bad'");
+ drop("jAvascript:'also bad'");
+ drop("mochi.test/second", true);
+ drop("data:text/html,bad");
+ drop("mochi.test/third", true);
+}
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -1298,25 +1298,22 @@
<![CDATA[
if (!this.droppedLinkHandler || event.defaultPrevented)
return;
let name = { };
let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
getService(Components.interfaces.nsIDroppedLinkHandler);
try {
- var uri = linkHandler.dropLink(event, name);
+ // Pass true to prevent the dropping of javascript:/data: URIs
+ var uri = linkHandler.dropLink(event, name, true);
} catch (ex) {
return;
}
- // don't allow dropping javascript or data urls
- if (/^\s*(javascript|data):/.test(uri))
- return;
-
if (uri) {
this.droppedLinkHandler(event, uri, name.value);
}
]]>
</handler>
</handlers>
</binding>