commit 95a62d13e045b950ed2b2f242da7413d33386a47 Author: Kathy Brade brade@pearlcrescent.com Date: Fri Oct 30 14:28:13 2015 -0400
Bug 16620: Clear window.name when no referrer sent
Convert JS implementation (within Torbutton) to a C++ browser patch. --- docshell/base/nsDocShell.cpp | 47 +++++++++++++ docshell/test/mochitest.ini | 2 + docshell/test/test_tor_bug16620.html | 129 ++++++++++++++++++++++++++++++++++ docshell/test/tor_bug16620.html | 51 ++++++++++++++ 4 files changed, 229 insertions(+)
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 03885534..59f184e 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -8992,6 +8992,53 @@ nsDocShell::CreateContentViewer(const char* aContentType, aOpenedChannel->GetURI(getter_AddRefs(mLoadingURI)); } 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"). + bool isNewWindowTarget = false; + nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(aRequest, &rv)); + if (props) { + props->GetPropertyAsBool(NS_LITERAL_STRING("docshell.newWindowTarget"), + &isNewWindowTarget); + } + + if (!isNewWindowTarget) { + nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aOpenedChannel)); + nsCOMPtr<nsIURI> httpReferrer; + if (httpChannel) + httpChannel->GetReferrer(getter_AddRefs(httpReferrer)); + +#ifdef DEBUG_WINDOW_NAME + printf("DOCSHELL %p CreateContentViewer - possibly clearing window.name:\n", this); + printf(" current window.name: "%s"\n", + NS_ConvertUTF16toUTF8(mName).get()); + + nsAutoCString curSpec, loadingSpec; + if (this->mCurrentURI) + mCurrentURI->GetSpec(curSpec); + if (mLoadingURI) + mLoadingURI->GetSpec(loadingSpec); + printf(" current URI: %s\n", curSpec.get()); + printf(" loading URI: %s\n", loadingSpec.get()); + + if (!httpReferrer) { + printf(" referrer: None\n"); + } else { + nsAutoCString refSpec; + httpReferrer->GetSpec(refSpec); + printf(" referrer: %s\n", refSpec.get()); + } +#endif + + if (!httpReferrer) + SetName(NS_LITERAL_STRING("")); + +#ifdef DEBUG_WINDOW_NAME + printf(" action taken: %s window.name\n", + httpReferrer ? "Preserved" : "Cleared"); +#endif + } + mLoadingURI = nullptr;
// Set mFiredUnloadEvent = false so that the unload handler for the diff --git a/docshell/test/mochitest.ini b/docshell/test/mochitest.ini index 3668c58..a1325b9 100644 --- a/docshell/test/mochitest.ini +++ b/docshell/test/mochitest.ini @@ -34,6 +34,7 @@ support-files = file_bug728939.html file_pushState_after_document_open.html historyframes.html + tor_bug16620.html
[test_anchor_scroll_after_document_open.html] [test_bfcache_plus_hash.html] @@ -107,3 +108,4 @@ support-files = file_framedhistoryframes.html skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage [test_bug1121701.html] skip-if = (buildapp == 'b2g' || buildapp == 'mulet') +[test_tor_bug16620.html] diff --git a/docshell/test/test_tor_bug16620.html b/docshell/test/test_tor_bug16620.html new file mode 100644 index 0000000..0fe9603 --- /dev/null +++ b/docshell/test/test_tor_bug16620.html @@ -0,0 +1,129 @@ +<!DOCTYPE HTML> +<html> +<!-- + Tor Bug 16620: Clear window.name when no referrer sent. + https://trac.torproject.org/projects/tor/ticket/16620 +--> +<meta charset="utf-8"> +<head> + <title>Test for Tor Bug 16620 - Clear window.name when no referrer sent</title> + <script type="application/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://trac.torproject.org/projects/tor/ticket/16620">Tor Bug 16620</a> +<script type="application/javascript;version=1.7"> + +// ## Test constants +const kTestPath = "/tests/docshell/test/"; +const kFile = "tor_bug16620.html"; +const kBaseURL1 = "http://example.com"; +const kBaseURL2 = "http://example.net"; + +let gTests = [ + // Test #1: Same domain: + { startURL: kBaseURL1, destURL: kBaseURL1, + expectIsolation: false }, + + // Test #2: Different top-level domains: + { startURL: kBaseURL1, destURL: kBaseURL2, + expectIsolation: false }, + + // Test #3: Same domain, rel="noreferrer" on link: + { startURL: kBaseURL1, destURL: kBaseURL1, noReferrerOnLink: true, + expectIsolation: true }, + + // Test #4: Same domain, "no-referrer" meta tag in document: + { startURL: kBaseURL1, destURL: kBaseURL1, noReferrerInMetaTag: true, + expectIsolation: true }, + + // Test #5: Like test 4, but reset window.name during unload: + // (similar to http://www.thomasfrank.se/sessvarsTestPage1.html) + { startURL: kBaseURL1, destURL: kBaseURL1, noReferrerInMetaTag: true, + resetInUnload: true, + expectIsolation: true }, + + // Test #6: Data URL as destination (no referrer): + { startURL: kBaseURL1, + expectIsolation: true }, +]; + +let gCurTest = 0; +let gCurWinName, gChildWin, gDataURL; + +// ## Utility functions +function generateRandomName() +{ + // Generate a random 6 character string using 0-9 and a-z. + return ((1 + Math.random()).toString(36) + '000000').substr(2, 6); +} + +function startNextTest() { + ++gCurTest; + if (gCurTest > gTests.length) { + SimpleTest.finish(); + } else { + let curTest = gTests[gCurTest - 1]; + let url = curTest.startURL + kTestPath + kFile + "?firstDocLoaded"; + gCurWinName = generateRandomName(); + gChildWin = window.open(url, gCurWinName); + } +} + +// ## Add a message event listener. +window.addEventListener("message", function(aEvent) { + if (aEvent.source !== gChildWin) + return; + +// console.log("parent received message:" + JSON.stringify(aEvent.data)); + + let curTest = gTests[gCurTest - 1]; + let state = aEvent.data.state; + let winName = aEvent.data.winName; + if ("firstDocLoaded" == state) { + ok(winName === gCurWinName, "Test #" + gCurTest + + " - first document's name matches window.open parameter"); + + // Send an "openURL" message to the loaded document. + let url2 = (curTest.destURL) + ? curTest.destURL + kTestPath + kFile + "?secondDocLoaded" + : gDataURL; + let noReferrerOnLink = (curTest.noReferrerOnLink === true); + let noReferrerInMetaTag = (curTest.noReferrerInMetaTag === true); + let resetInUnload = (curTest.resetInUnload === true); + aEvent.source.postMessage({ action: "openURL", url: url2, + noReferrerOnLink: noReferrerOnLink, + noReferrerInMetaTag: noReferrerInMetaTag, + resetInUnload: resetInUnload }, + aEvent.origin); + } else if ("secondDocLoaded" == state) { + if (curTest.expectIsolation) { + ok(winName === "", + "Test #" + gCurTest + " - second document: name was cleared"); + } else { + ok(winName === gCurWinName, + "Test #" + gCurTest + " - second document: name was preserved"); + } + + 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(); +</script> +</body> +</html> diff --git a/docshell/test/tor_bug16620.html b/docshell/test/tor_bug16620.html new file mode 100644 index 0000000..a8e9050 --- /dev/null +++ b/docshell/test/tor_bug16620.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 +--> +<head> + <meta charset="UTF-8"> + <title>Supporting Doc for Tor Bug 16620 Tests</title> +</head> +<body> +<a id="link" href="">secondDoc</a> + +<script type="application/javascript;version=1.7"> +// Extract test state from our query string, defaulting to +// "secondDocLoaded" to support use of this HTML content within +// a data URI (where query strings are not supported). +let state = (location.search.length > 0) ? location.search.substr(1) + : "secondDocLoaded"; + +// Notify the test driver. +opener.postMessage({ state: state, winName: window.name }, "*"); + +// Add a message event listener to process "openURL" actions. +window.addEventListener("message", function(aEvent) { + if (aEvent.data.action == "openURL") { + if (aEvent.data.noReferrerInMetaTag) { + let metaElem = document.createElement("meta"); + metaElem.name = "referrer"; + metaElem.content = "no-referrer"; + document.head.appendChild(metaElem); + } + + let linkElem = document.getElementById("link"); + linkElem.href = aEvent.data.url; + if (aEvent.data.noReferrerOnLink) + linkElem.rel = "noreferrer"; + + if (aEvent.data.resetInUnload) { + let tmpName = window.name; + window.addEventListener("unload", function() { + window.name = tmpName; + }, false); + } + + linkElem.click(); + } +}, false); +</script> +</body> +</html>
tor-commits@lists.torproject.org