[tbb-commits] [tor-browser/tor-browser-38.6.0esr-6.0-1] fixup! Bug 16620: Clear window.name when no referrer sent
gk at torproject.org
gk at torproject.org
Tue Feb 2 11:34:43 UTC 2016
commit bc8af4dcdafd3de656bbff245eb70a0025829b90
Author: Kathy Brade <brade at pearlcrescent.com>
Date: Fri Jan 29 16:47:26 2016 -0500
fixup! Bug 16620: Clear window.name when no referrer sent
Only clear window.name for the top document, not for frames. This fixes
Bug 18168: iframe-based AJAX call opening in new tab
and more closely matches the behavior of Torbutton's old
JavaScript-based implementation.
---
docshell/base/nsDocShell.cpp | 18 +++--
docshell/test/mochitest.ini | 1 +
docshell/test/test_tor_bug16620.html | 131 ++++++++++++++++++++++++++++-------
docshell/test/tor_bug16620_form.html | 51 ++++++++++++++
4 files changed, 173 insertions(+), 28 deletions(-)
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
index 0c404fa..3f059673 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -8993,8 +8993,9 @@ nsDocShell::CreateContentViewer(const char* aContentType,
}
FirePageHideNotification(!mSavingOldViewer);
- // Tor bug # 16620: Clear window.name if there is no referrer. We make an
- // exception for new windows, e.g., window.open(url, "MyName").
+ // Tor bug 16620: Clear window.name of top-level documents if
+ // there is no referrer. We make an exception for new windows,
+ // e.g., window.open(url, "MyName").
bool isNewWindowTarget = false;
nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(aRequest, &rv));
if (props) {
@@ -9008,6 +9009,13 @@ nsDocShell::CreateContentViewer(const char* aContentType,
if (httpChannel)
httpChannel->GetReferrer(getter_AddRefs(httpReferrer));
+ bool isTopFrame = true;
+ nsCOMPtr<nsIDocShellTreeItem> targetParentTreeItem;
+ rv = GetSameTypeParent(getter_AddRefs(targetParentTreeItem));
+ if (NS_SUCCEEDED(rv) && targetParentTreeItem) {
+ isTopFrame = false;
+ }
+
#ifdef DEBUG_WINDOW_NAME
printf("DOCSHELL %p CreateContentViewer - possibly clearing window.name:\n", this);
printf(" current window.name: \"%s\"\n",
@@ -9020,6 +9028,7 @@ nsDocShell::CreateContentViewer(const char* aContentType,
mLoadingURI->GetSpec(loadingSpec);
printf(" current URI: %s\n", curSpec.get());
printf(" loading URI: %s\n", loadingSpec.get());
+ printf(" is top document: %s\n", isTopFrame ? "Yes" : "No");
if (!httpReferrer) {
printf(" referrer: None\n");
@@ -9030,12 +9039,13 @@ nsDocShell::CreateContentViewer(const char* aContentType,
}
#endif
- if (!httpReferrer)
+ bool clearName = isTopFrame && !httpReferrer;
+ if (clearName)
SetName(NS_LITERAL_STRING(""));
#ifdef DEBUG_WINDOW_NAME
printf(" action taken: %s window.name\n",
- httpReferrer ? "Preserved" : "Cleared");
+ clearName ? "Cleared" : "Preserved");
#endif
}
diff --git a/docshell/test/mochitest.ini b/docshell/test/mochitest.ini
index a1325b9..274a77e 100644
--- a/docshell/test/mochitest.ini
+++ b/docshell/test/mochitest.ini
@@ -35,6 +35,7 @@ support-files =
file_pushState_after_document_open.html
historyframes.html
tor_bug16620.html
+ tor_bug16620_form.html
[test_anchor_scroll_after_document_open.html]
[test_bfcache_plus_hash.html]
diff --git a/docshell/test/test_tor_bug16620.html b/docshell/test/test_tor_bug16620.html
index 0fe9603..d528e17 100644
--- a/docshell/test/test_tor_bug16620.html
+++ b/docshell/test/test_tor_bug16620.html
@@ -17,36 +17,80 @@
// ## Test constants
const kTestPath = "/tests/docshell/test/";
-const kFile = "tor_bug16620.html";
+const kLinkFile = "tor_bug16620.html";
+const kFormFile = "tor_bug16620_form.html";
const kBaseURL1 = "http://example.com";
+const kBaseURL1_https = "https://example.com";
const kBaseURL2 = "http://example.net";
+const kSendReferrerPref = "network.http.sendRefererHeader";
+const kSendReferrerNever = 0;
+const kSendReferrerForUserAction = 1;
+const kSendReferrerAlways = 2;
let gTests = [
- // Test #1: Same domain:
+ // Test #1: Same domain; never send referrer.
{ startURL: kBaseURL1, destURL: kBaseURL1,
+ referrerPref: kSendReferrerNever,
+ expectIsolation: true },
+
+ // Test #2: Same domain; send referrer upon user action.
+ { startURL: kBaseURL1, destURL: kBaseURL1,
+ referrerPref: kSendReferrerForUserAction,
expectIsolation: false },
- // Test #2: Different top-level domains:
+ // Test #3: Same domain; always send referrer.
+ { startURL: kBaseURL1, destURL: kBaseURL1,
+ referrerPref: kSendReferrerAlways,
+ expectIsolation: false },
+
+ // Test #4: Different top-level domains; never send referrer.
+ { startURL: kBaseURL1, destURL: kBaseURL2,
+ referrerPref: kSendReferrerNever,
+ expectIsolation: true },
+
+ // Test #5: Different top-level domains; send referrer upon user action.
{ startURL: kBaseURL1, destURL: kBaseURL2,
+ referrerPref: kSendReferrerForUserAction,
expectIsolation: false },
- // Test #3: Same domain, rel="noreferrer" on link:
+ // Test #6: Different top-level domains; always send referrer.
+ { startURL: kBaseURL1, destURL: kBaseURL2,
+ referrerPref: kSendReferrerAlways,
+ expectIsolation: false },
+
+ // Test #7: https -> http transition.
+ { startURL: kBaseURL1_https, destURL: kBaseURL1,
+ referrerPref: kSendReferrerForUserAction,
+ expectIsolation: true },
+
+ // Test #8: Same domain, rel="noreferrer" on link.
{ startURL: kBaseURL1, destURL: kBaseURL1, noReferrerOnLink: true,
+ referrerPref: kSendReferrerAlways,
expectIsolation: true },
- // Test #4: Same domain, "no-referrer" meta tag in document:
+ // Test #9: Same domain, "no-referrer" meta tag in document.
{ startURL: kBaseURL1, destURL: kBaseURL1, noReferrerInMetaTag: true,
+ referrerPref: kSendReferrerAlways,
expectIsolation: true },
- // Test #5: Like test 4, but reset window.name during unload:
+ // Test #10: Like test #9, but reset window.name during unload.
// (similar to http://www.thomasfrank.se/sessvarsTestPage1.html)
{ startURL: kBaseURL1, destURL: kBaseURL1, noReferrerInMetaTag: true,
resetInUnload: true,
+ referrerPref: kSendReferrerAlways,
expectIsolation: true },
- // Test #6: Data URL as destination (no referrer):
+ // Test #11: Data URL as destination (no referrer).
{ startURL: kBaseURL1,
+ referrerPref: kSendReferrerAlways,
expectIsolation: true },
+
+ // Test #12: Ensure that window.name is preserved when a dynamically loaded
+ // iframe is used to perform a form post (regression test for Tor bug 18168).
+ { startURL: kBaseURL1,
+ isFormTest: true,
+ referrerPref: kSendReferrerAlways,
+ expectIsolation: false },
];
let gCurTest = 0;
@@ -65,9 +109,19 @@ function startNextTest() {
SimpleTest.finish();
} else {
let curTest = gTests[gCurTest - 1];
- let url = curTest.startURL + kTestPath + kFile + "?firstDocLoaded";
+ if ("referrerPref" in curTest)
+ SpecialPowers.setIntPref(kSendReferrerPref, curTest.referrerPref);
+ else
+ SpecialPowers.setIntPref(kSendReferrerPref, kSendReferrerForUserAction);
gCurWinName = generateRandomName();
- gChildWin = window.open(url, gCurWinName);
+ let url = curTest.startURL + kTestPath;
+ if (curTest.isFormTest === true) {
+ url += kFormFile + "?" + gCurWinName;
+ gChildWin = window.open(url, undefined);
+ } else {
+ url += kLinkFile + "?firstDocLoaded";
+ gChildWin = window.open(url, gCurWinName);
+ }
}
}
@@ -78,16 +132,22 @@ window.addEventListener("message", function(aEvent) {
// console.log("parent received message:" + JSON.stringify(aEvent.data));
+ let proceedToNextTest = false;
let curTest = gTests[gCurTest - 1];
let state = aEvent.data.state;
let winName = aEvent.data.winName;
if ("firstDocLoaded" == state) {
- ok(winName === gCurWinName, "Test #" + gCurTest +
+ // Process response from step one of the link-based tests.
+ let step1Passed = (winName === gCurWinName);
+ if (!step1Passed) {
+ ok(step1Passed, "Test #" + gCurTest +
" - first document's name matches window.open parameter");
+ proceedToNextTest = true;
+ }
// Send an "openURL" message to the loaded document.
let url2 = (curTest.destURL)
- ? curTest.destURL + kTestPath + kFile + "?secondDocLoaded"
+ ? curTest.destURL + kTestPath + kLinkFile + "?secondDocLoaded"
: gDataURL;
let noReferrerOnLink = (curTest.noReferrerOnLink === true);
let noReferrerInMetaTag = (curTest.noReferrerInMetaTag === true);
@@ -98,6 +158,7 @@ window.addEventListener("message", function(aEvent) {
resetInUnload: resetInUnload },
aEvent.origin);
} else if ("secondDocLoaded" == state) {
+ // Process response from step two of the link-based tests.
if (curTest.expectIsolation) {
ok(winName === "",
"Test #" + gCurTest + " - second document: name was cleared");
@@ -105,25 +166,47 @@ window.addEventListener("message", function(aEvent) {
ok(winName === gCurWinName,
"Test #" + gCurTest + " - second document: name was preserved");
}
+ proceedToNextTest = true;
+ } else if ("formPostDone" == state) {
+ // Process response from the form post tests.
+ if (curTest.expectIsolation) {
+ ok(winName === "",
+ "Test #" + gCurTest + " - iframe form post: name was cleared");
+ } else {
+ ok(winName === gCurWinName,
+ "Test #" + gCurTest + " - iframe form post: name was preserved");
+ }
+ proceedToNextTest = true;
+
+ }
+ if (proceedToNextTest) {
gChildWin.close();
startNextTest();
}
}, false);
-SimpleTest.waitForExplicitFinish();
-
-// Read file contents, construct a data URL (used by some tests), and
-// then start the first test.
-let url = kTestPath + kFile;
-let xhr = new XMLHttpRequest();
-xhr.open("GET", url);
-xhr.onload = function() {
- gDataURL = "data:text/html;charset=utf-8,"
- + encodeURIComponent(this.responseText);
- startNextTest();
-}
-xhr.send();
+ SimpleTest.waitForExplicitFinish();
+
+ if (SpecialPowers.getBoolPref("security.nocertdb")) {
+ // Mochitests don't simulate https correctly with "security.nocertdb"
+ // enabled. See https://bugs.torproject.org/18087
+ ok(false, "Please disable the pref `security.nocertdb` before running this test.");
+ SimpleTest.finish();
+ } else {
+
+ // Read file contents, construct a data URL (used by some tests), and
+ // then start the first test.
+ let url = kTestPath + kLinkFile;
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", url);
+ xhr.onload = function() {
+ gDataURL = "data:text/html;charset=utf-8,"
+ + encodeURIComponent(this.responseText);
+ startNextTest();
+ }
+ xhr.send();
+ }
</script>
</body>
</html>
diff --git a/docshell/test/tor_bug16620_form.html b/docshell/test/tor_bug16620_form.html
new file mode 100644
index 0000000..3b6e6c7
--- /dev/null
+++ b/docshell/test/tor_bug16620_form.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+ Tor Bug 16620: Clear window.name when no referrer sent.
+ https://trac.torproject.org/projects/tor/ticket/16620
+
+ Regression test for bug 18168: iframe-based AJAX call opening in new tab
+-->
+<head>
+ <meta charset="UTF-8">
+ <title>Supporting Form-based Doc for Tor Bug 16620 Tests</title>
+</head>
+<body>
+
+<script type="application/javascript;version=1.7">
+document.addEventListener("DOMContentLoaded", function () {
+ addPostTarget();
+}, false);
+
+
+function addPostTarget()
+{
+ let frameName = location.search.substr(1);
+ let form = document.getElementById("postform");
+ let iframe = document.createElement("iframe");
+ iframe.style.border = "1px solid red";
+ iframe.src = "about:blank";
+ form.target = iframe.name = iframe.id = frameName;
+ document.body.appendChild(iframe);
+
+ let didSubmit = false;
+ iframe.onload = function() {
+ if (!didSubmit) {
+ didSubmit = true;
+ let submitButton = document.getElementById("submitButton");
+ submitButton.click();
+ } else {
+ // Form submission complete. Report iframe's name to test driver.
+ opener.postMessage({ state: "formPostDone", winName: iframe.name }, "*");
+ }
+ };
+}
+
+</script>
+<form name="postform" id="postform"
+ action="data:text/plain;charset=utf-8,Hello%20world"
+ method="POST" enctype="multipart/form-data">
+ <input type="hidden" name="field1" value="value1"><br>
+ <input id="submitButton" type="submit" value="Post It">
+</body>
+</html>
More information about the tbb-commits
mailing list