mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1148032 - BroadcastChannel API should not bypass private browsing mode, r=ehsan
This commit is contained in:
parent
1a65d1c1e9
commit
621d7068b8
@ -126,11 +126,13 @@ class InitializeRunnable final : public WorkerMainThreadRunnable
|
||||
{
|
||||
public:
|
||||
InitializeRunnable(WorkerPrivate* aWorkerPrivate, nsAString& aOrigin,
|
||||
PrincipalInfo& aPrincipalInfo, ErrorResult& aRv)
|
||||
PrincipalInfo& aPrincipalInfo, bool& aPrivateBrowsing,
|
||||
ErrorResult& aRv)
|
||||
: WorkerMainThreadRunnable(aWorkerPrivate)
|
||||
, mWorkerPrivate(GetCurrentThreadWorkerPrivate())
|
||||
, mOrigin(aOrigin)
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
, mPrivateBrowsing(aPrivateBrowsing)
|
||||
, mRv(aRv)
|
||||
{
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
@ -180,8 +182,10 @@ public:
|
||||
}
|
||||
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
// No bfcache when BroadcastChannel is used.
|
||||
if (doc) {
|
||||
mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(doc);
|
||||
|
||||
// No bfcache when BroadcastChannel is used.
|
||||
doc->DisallowBFCaching();
|
||||
}
|
||||
|
||||
@ -192,6 +196,7 @@ private:
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsAString& mOrigin;
|
||||
PrincipalInfo& mPrincipalInfo;
|
||||
bool& mPrivateBrowsing;
|
||||
ErrorResult& mRv;
|
||||
};
|
||||
|
||||
@ -396,12 +401,14 @@ BroadcastChannel::IsEnabled(JSContext* aCx, JSObject* aGlobal)
|
||||
BroadcastChannel::BroadcastChannel(nsPIDOMWindow* aWindow,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aChannel)
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mWorkerFeature(nullptr)
|
||||
, mPrincipalInfo(new PrincipalInfo(aPrincipalInfo))
|
||||
, mOrigin(aOrigin)
|
||||
, mChannel(aChannel)
|
||||
, mPrivateBrowsing(aPrivateBrowsing)
|
||||
, mIsKeptAlive(false)
|
||||
, mInnerID(0)
|
||||
, mState(StateActive)
|
||||
@ -431,6 +438,7 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
||||
|
||||
nsAutoString origin;
|
||||
PrincipalInfo principalInfo;
|
||||
bool privateBrowsing = false;
|
||||
WorkerPrivate* workerPrivate = nullptr;
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
@ -469,8 +477,10 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
||||
}
|
||||
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
// No bfcache when BroadcastChannel is used.
|
||||
if (doc) {
|
||||
privateBrowsing = nsContentUtils::IsInPrivateBrowsing(doc);
|
||||
|
||||
// No bfcache when BroadcastChannel is used.
|
||||
doc->DisallowBFCaching();
|
||||
}
|
||||
} else {
|
||||
@ -479,7 +489,8 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
nsRefPtr<InitializeRunnable> runnable =
|
||||
new InitializeRunnable(workerPrivate, origin, principalInfo, aRv);
|
||||
new InitializeRunnable(workerPrivate, origin, principalInfo,
|
||||
privateBrowsing, aRv);
|
||||
runnable->Dispatch(cx);
|
||||
}
|
||||
|
||||
@ -488,7 +499,8 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
||||
}
|
||||
|
||||
nsRefPtr<BroadcastChannel> bc =
|
||||
new BroadcastChannel(window, principalInfo, origin, aChannel);
|
||||
new BroadcastChannel(window, principalInfo, origin, aChannel,
|
||||
privateBrowsing);
|
||||
|
||||
// Register this component to PBackground.
|
||||
PBackgroundChild* actor = BackgroundChild::GetForCurrentThread();
|
||||
@ -614,7 +626,8 @@ BroadcastChannel::ActorCreated(PBackgroundChild* aActor)
|
||||
}
|
||||
|
||||
PBroadcastChannelChild* actor =
|
||||
aActor->SendPBroadcastChannelConstructor(*mPrincipalInfo, mOrigin, mChannel);
|
||||
aActor->SendPBroadcastChannelConstructor(*mPrincipalInfo, mOrigin, mChannel,
|
||||
mPrivateBrowsing);
|
||||
|
||||
mActor = static_cast<BroadcastChannelChild*>(actor);
|
||||
MOZ_ASSERT(mActor);
|
||||
|
@ -92,7 +92,8 @@ private:
|
||||
BroadcastChannel(nsPIDOMWindow* aWindow,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aChannel);
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing);
|
||||
|
||||
~BroadcastChannel();
|
||||
|
||||
@ -112,6 +113,7 @@ private:
|
||||
|
||||
nsString mOrigin;
|
||||
nsString mChannel;
|
||||
bool mPrivateBrowsing;
|
||||
|
||||
bool mIsKeptAlive;
|
||||
|
||||
|
@ -25,10 +25,8 @@ namespace dom {
|
||||
|
||||
using namespace workers;
|
||||
|
||||
BroadcastChannelChild::BroadcastChannelChild(const nsAString& aOrigin,
|
||||
const nsAString& aChannel)
|
||||
BroadcastChannelChild::BroadcastChannelChild(const nsAString& aOrigin)
|
||||
: mOrigin(aOrigin)
|
||||
, mChannel(aChannel)
|
||||
, mActorDestroyed(false)
|
||||
{
|
||||
}
|
||||
|
@ -37,9 +37,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BroadcastChannelChild(const nsAString& aOrigin,
|
||||
const nsAString& aChannel);
|
||||
|
||||
explicit BroadcastChannelChild(const nsAString& aOrigin);
|
||||
~BroadcastChannelChild();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
@ -49,7 +47,6 @@ private:
|
||||
BroadcastChannel* mBC;
|
||||
|
||||
nsString mOrigin;
|
||||
nsString mChannel;
|
||||
|
||||
bool mActorDestroyed;
|
||||
};
|
||||
|
@ -18,10 +18,12 @@ namespace dom {
|
||||
|
||||
BroadcastChannelParent::BroadcastChannelParent(
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aChannel)
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
: mService(BroadcastChannelService::GetOrCreate())
|
||||
, mOrigin(aOrigin)
|
||||
, mChannel(aChannel)
|
||||
, mPrivateBrowsing(aPrivateBrowsing)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
mService->RegisterActor(this);
|
||||
@ -41,7 +43,7 @@ BroadcastChannelParent::RecvPostMessage(const ClonedMessageData& aData)
|
||||
return false;
|
||||
}
|
||||
|
||||
mService->PostMessage(this, aData, mOrigin, mChannel);
|
||||
mService->PostMessage(this, aData, mOrigin, mChannel, mPrivateBrowsing);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -77,11 +79,14 @@ BroadcastChannelParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
void
|
||||
BroadcastChannelParent::CheckAndDeliver(const ClonedMessageData& aData,
|
||||
const nsString& aOrigin,
|
||||
const nsString& aChannel)
|
||||
const nsString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (aOrigin == mOrigin && aChannel == mChannel) {
|
||||
if (aOrigin == mOrigin &&
|
||||
aChannel == mChannel &&
|
||||
aPrivateBrowsing == mPrivateBrowsing) {
|
||||
// We need to duplicate data only if we have blobs or if the manager of
|
||||
// them is different than the manager of this parent actor.
|
||||
if (aData.blobsParent().IsEmpty() ||
|
||||
|
@ -24,11 +24,13 @@ class BroadcastChannelParent final : public PBroadcastChannelParent
|
||||
public:
|
||||
void CheckAndDeliver(const ClonedMessageData& aData,
|
||||
const nsString& aOrigin,
|
||||
const nsString& aChannel);
|
||||
const nsString& aChannel,
|
||||
bool aPrivateBrowsing);
|
||||
|
||||
private:
|
||||
BroadcastChannelParent(const nsAString& aOrigin,
|
||||
const nsAString& aChannel);
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing);
|
||||
~BroadcastChannelParent();
|
||||
|
||||
virtual bool
|
||||
@ -41,6 +43,7 @@ private:
|
||||
nsRefPtr<BroadcastChannelService> mService;
|
||||
nsString mOrigin;
|
||||
nsString mChannel;
|
||||
bool mPrivateBrowsing;
|
||||
};
|
||||
|
||||
} // dom namespace
|
||||
|
@ -83,11 +83,13 @@ struct MOZ_STACK_CLASS PostMessageData final
|
||||
PostMessageData(BroadcastChannelParent* aParent,
|
||||
const ClonedMessageData& aData,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aChannel)
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
: mParent(aParent)
|
||||
, mData(aData)
|
||||
, mOrigin(aOrigin)
|
||||
, mChannel(aChannel)
|
||||
, mPrivateBrowsing(aPrivateBrowsing)
|
||||
{
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_COUNT_CTOR(PostMessageData);
|
||||
@ -116,6 +118,7 @@ struct MOZ_STACK_CLASS PostMessageData final
|
||||
nsTArray<nsRefPtr<FileImpl>> mFiles;
|
||||
const nsString mOrigin;
|
||||
const nsString mChannel;
|
||||
bool mPrivateBrowsing;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
@ -128,7 +131,8 @@ PostMessageEnumerator(nsPtrHashKey<BroadcastChannelParent>* aKey, void* aPtr)
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent != data->mParent) {
|
||||
parent->CheckAndDeliver(data->mData, data->mOrigin, data->mChannel);
|
||||
parent->CheckAndDeliver(data->mData, data->mOrigin, data->mChannel,
|
||||
data->mPrivateBrowsing);
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
@ -140,13 +144,14 @@ void
|
||||
BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
|
||||
const ClonedMessageData& aData,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aChannel)
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(mAgents.Contains(aParent));
|
||||
|
||||
PostMessageData data(aParent, aData, aOrigin, aChannel);
|
||||
PostMessageData data(aParent, aData, aOrigin, aChannel, aPrivateBrowsing);
|
||||
mAgents.EnumerateEntries(PostMessageEnumerator, &data);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,8 @@ public:
|
||||
void PostMessage(BroadcastChannelParent* aParent,
|
||||
const ClonedMessageData& aData,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aChannel);
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing);
|
||||
|
||||
private:
|
||||
BroadcastChannelService();
|
||||
|
@ -24,6 +24,7 @@ LOCAL_INCLUDES += [
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
||||
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
|
2
dom/broadcastchannel/tests/blank.html
Normal file
2
dom/broadcastchannel/tests/blank.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html><body></body></html>
|
5
dom/broadcastchannel/tests/chrome.ini
Normal file
5
dom/broadcastchannel/tests/chrome.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
blank.html
|
||||
|
||||
[test_broadcastchannel_private_browsing.html]
|
@ -0,0 +1,118 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Test for BroadcastChannel - Private Browsing</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
var mainWindow;
|
||||
|
||||
var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
prefBranch.setIntPref("browser.startup.page", 0);
|
||||
prefBranch.setCharPref("browser.startup.homepage_override.mstone", "ignore");
|
||||
|
||||
var contentPage = "http://mochi.test:8888/chrome/dom/broadcastchannel/tests/blank.html";
|
||||
|
||||
function testOnWindow(aIsPrivate, aCallback) {
|
||||
var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
win.addEventListener("DOMContentLoaded", function onInnerLoad() {
|
||||
if (win.content.location.href != contentPage) {
|
||||
win.gBrowser.loadURI(contentPage);
|
||||
return;
|
||||
}
|
||||
|
||||
win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
|
||||
SimpleTest.executeSoon(function() { aCallback(win); });
|
||||
}, true);
|
||||
|
||||
if (!aIsPrivate) {
|
||||
win.gBrowser.loadURI(contentPage);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
function setupWindow() {
|
||||
mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
runTest();
|
||||
}
|
||||
|
||||
var gCounter = 0;
|
||||
|
||||
function check(msg, private) {
|
||||
is(msg, private ? "private" : "public", "Correct context!");
|
||||
gCounter++;
|
||||
|
||||
if (gCounter > 1) {
|
||||
runTest();
|
||||
}
|
||||
}
|
||||
|
||||
var wN;
|
||||
var wP;
|
||||
|
||||
function doTests() {
|
||||
testOnWindow(false, function(aWin) {
|
||||
wN = aWin;
|
||||
|
||||
testOnWindow(true, function(aWin) {
|
||||
wP = aWin;
|
||||
|
||||
var bcP = new wP.content.BroadcastChannel('foobar');
|
||||
bcP.onmessage = function(e) { ok(false, "This should not be called!"); }
|
||||
|
||||
var bc = new wP.content.BroadcastChannel('foobar');
|
||||
bc.onmessage = function(e) { check(e.data, true); }
|
||||
|
||||
var bcN = new wN.content.BroadcastChannel('foobar');
|
||||
bcN.onmessage = function(e) { ok(false, "This should not be called!"); }
|
||||
|
||||
var bc = new wN.content.BroadcastChannel('foobar');
|
||||
bc.onmessage = function(e) { check(e.data, false); }
|
||||
|
||||
bcP.postMessage('private');
|
||||
bcN.postMessage('public');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var steps = [
|
||||
setupWindow,
|
||||
doTests
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!steps.length) {
|
||||
wN.close();
|
||||
wP.close();
|
||||
|
||||
prefBranch.clearUserPref("browser.startup.page")
|
||||
prefBranch.clearUserPref("browser.startup.homepage_override.mstone");
|
||||
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var step = steps.shift();
|
||||
step();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.broadcastChannel.enabled", true]]}, runTest);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -220,10 +220,11 @@ BackgroundChildImpl::DeallocPVsyncChild(PVsyncChild* aActor)
|
||||
dom::PBroadcastChannelChild*
|
||||
BackgroundChildImpl::AllocPBroadcastChannelChild(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aOrigin,
|
||||
const nsString& aChannel)
|
||||
const nsString& aChannel,
|
||||
const bool& aPrivateBrowsing)
|
||||
{
|
||||
nsRefPtr<dom::BroadcastChannelChild> agent =
|
||||
new dom::BroadcastChannelChild(aOrigin, aChannel);
|
||||
new dom::BroadcastChannelChild(aOrigin);
|
||||
return agent.forget().take();
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,8 @@ protected:
|
||||
virtual PBroadcastChannelChild*
|
||||
AllocPBroadcastChannelChild(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aOrigin,
|
||||
const nsString& aChannel) override;
|
||||
const nsString& aChannel,
|
||||
const bool& aPrivateBrowsing) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPBroadcastChannelChild(PBroadcastChannelChild* aActor) override;
|
||||
|
@ -255,12 +255,13 @@ mozilla::dom::PBroadcastChannelParent*
|
||||
BackgroundParentImpl::AllocPBroadcastChannelParent(
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aOrigin,
|
||||
const nsString& aChannel)
|
||||
const nsString& aChannel,
|
||||
const bool& aPrivateBrowsing)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
return new BroadcastChannelParent(aOrigin, aChannel);
|
||||
return new BroadcastChannelParent(aOrigin, aChannel, aPrivateBrowsing);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -328,7 +329,8 @@ BackgroundParentImpl::RecvPBroadcastChannelConstructor(
|
||||
PBroadcastChannelParent* actor,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aOrigin,
|
||||
const nsString& aChannel)
|
||||
const nsString& aChannel,
|
||||
const bool& aPrivateBrowsing)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
@ -73,13 +73,15 @@ protected:
|
||||
virtual PBroadcastChannelParent*
|
||||
AllocPBroadcastChannelParent(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aOrigin,
|
||||
const nsString& aChannel) override;
|
||||
const nsString& aChannel,
|
||||
const bool& aPrivateBrowsing) override;
|
||||
|
||||
virtual bool
|
||||
RecvPBroadcastChannelConstructor(PBroadcastChannelParent* actor,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& origin,
|
||||
const nsString& channel) override;
|
||||
const nsString& channel,
|
||||
const bool& aPrivateBrowsing) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPBroadcastChannelParent(PBroadcastChannelParent* aActor) override;
|
||||
|
@ -46,7 +46,8 @@ parent:
|
||||
PVsync();
|
||||
PMedia();
|
||||
|
||||
PBroadcastChannel(PrincipalInfo pInfo, nsString origin, nsString channel);
|
||||
PBroadcastChannel(PrincipalInfo pInfo, nsString origin, nsString channel,
|
||||
bool privateBrowsing);
|
||||
|
||||
RegisterServiceWorker(ServiceWorkerRegistrationData data);
|
||||
UnregisterServiceWorker(PrincipalInfo principalInfo,
|
||||
|
Loading…
Reference in New Issue
Block a user