From 96ff9fb9aeed8e3fd426f63df7e6a7c83e9dc875 Mon Sep 17 00:00:00 2001 From: Kershaw Chang Date: Tue, 28 Jun 2016 17:05:53 +0800 Subject: [PATCH 1/2] Bug 1268810 - Set SANDBOXED_AUXILIARY_NAVIGATION flag to receiver page, r=smaug --- dom/base/nsContentUtils.cpp | 3 +++ dom/base/nsFrameLoader.cpp | 29 ++++++++++++++++++++--------- dom/ipc/TabChild.cpp | 6 ++++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index c4fe2ca2268dc..2308c42d6f9af 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -8888,6 +8888,9 @@ nsContentUtils::GetPresentationURL(nsIDocShell* aDocShell, nsAString& aPresentat nsCOMPtr loadContext(do_QueryInterface(aDocShell)); nsCOMPtr topFrameElement; loadContext->GetTopFrameElement(getter_AddRefs(topFrameElement)); + if (!topFrameElement) { + return; + } topFrameElement->GetAttribute(NS_LITERAL_STRING("mozpresentation"), aPresentationUrl); } diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 5ce0d9fbefbcf..8d086e7730c54 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -1880,15 +1880,6 @@ nsFrameLoader::MaybeCreateDocShell() NS_ENSURE_SUCCESS(rv,rv); } - // Apply sandbox flags even if our owner is not an iframe, as this copies - // flags from our owning content's owning document. - uint32_t sandboxFlags = 0; - HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent); - if (iframe) { - sandboxFlags = iframe->GetSandboxFlags(); - } - ApplySandboxFlags(sandboxFlags); - if (!mNetworkCreated) { if (mDocShell) { mDocShell->SetCreatedDynamically(true); @@ -2024,6 +2015,17 @@ nsFrameLoader::MaybeCreateDocShell() mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER); } + // Apply sandbox flags even if our owner is not an iframe, as this copies + // flags from our owning content's owning document. + // Note: ApplySandboxFlags should be called after mDocShell->SetFrameType + // because we need to get the correct presentation URL in ApplySandboxFlags. + uint32_t sandboxFlags = 0; + HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent); + if (iframe) { + sandboxFlags = iframe->GetSandboxFlags(); + } + ApplySandboxFlags(sandboxFlags); + // Grab the userContextId from owner if XUL nsAutoString userContextIdStr; if ((namespaceID == kNameSpaceID_XUL) && @@ -2858,6 +2860,15 @@ nsFrameLoader::ApplySandboxFlags(uint32_t sandboxFlags) // The child can only add restrictions, never remove them. sandboxFlags |= parentSandboxFlags; + + // If this frame is a receiving browsing context, we should add + // sandboxed auxiliary navigation flag to sandboxFlags. See + // https://w3c.github.io/presentation-api/#creating-a-receiving-browsing-context + nsAutoString presentationURL; + nsContentUtils::GetPresentationURL(mDocShell, presentationURL); + if (!presentationURL.IsEmpty()) { + sandboxFlags |= SANDBOXED_AUXILIARY_NAVIGATION; + } mDocShell->SetSandboxFlags(sandboxFlags); } } diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 7c74a82c311b4..2927254853cc9 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -109,6 +109,7 @@ #include "nsIScriptError.h" #include "mozilla/EventForwards.h" #include "nsDeviceContext.h" +#include "nsSandboxFlags.h" #include "FrameLayerBuilder.h" #define BROWSER_ELEMENT_CHILD_SCRIPT \ @@ -876,6 +877,11 @@ TabChild::NotifyTabContextUpdated() nsIDocShell::FRAME_TYPE_APP : nsIDocShell::FRAME_TYPE_REGULAR); nsDocShell::Cast(docShell)->SetOriginAttributes(OriginAttributesRef()); + + // Set SANDBOXED_AUXILIARY_NAVIGATION flag if this is a receiver page. + if (!PresentationURL().IsEmpty()) { + docShell->SetSandboxFlags(SANDBOXED_AUXILIARY_NAVIGATION); + } } NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild) From ae9c15c527dcf98a52f37b0a89cc5530c88d0646 Mon Sep 17 00:00:00 2001 From: Kershaw Chang Date: Tue, 28 Jun 2016 17:06:00 +0800 Subject: [PATCH 2/2] Bug 1268810 - Test case, r=smaug --- ...ntation_receiver_auxiliary_navigation.html | 60 +++++++++++++++ .../tests/mochitest/mochitest.ini | 6 ++ ...sentation_receiver_auxiliary_navigation.js | 75 +++++++++++++++++++ ..._receiver_auxiliary_navigation_inproc.html | 18 +++++ ...ion_receiver_auxiliary_navigation_oop.html | 18 +++++ 5 files changed, 177 insertions(+) create mode 100644 dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html create mode 100644 dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js create mode 100644 dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html create mode 100644 dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html diff --git a/dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html b/dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html new file mode 100644 index 0000000000000..3a60603101bc5 --- /dev/null +++ b/dom/presentation/tests/mochitest/file_presentation_receiver_auxiliary_navigation.html @@ -0,0 +1,60 @@ + + + + + Test for sandboxed auxiliary navigation flag in receiver page + + +
+ + + diff --git a/dom/presentation/tests/mochitest/mochitest.ini b/dom/presentation/tests/mochitest/mochitest.ini index 6fe7eede5cfdc..01ecc506a847f 100644 --- a/dom/presentation/tests/mochitest/mochitest.ini +++ b/dom/presentation/tests/mochitest/mochitest.ini @@ -12,6 +12,8 @@ support-files = file_presentation_receiver_inner_iframe.html file_presentation_1ua_wentaway.html test_presentation_1ua_connection_wentaway.js + file_presentation_receiver_auxiliary_navigation.html + test_presentation_receiver_auxiliary_navigation.js [test_presentation_dc_sender.html] [test_presentation_dc_receiver.html] @@ -46,3 +48,7 @@ skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785 skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785 [test_presentation_tcp_receiver_oop.html] skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785 +[test_presentation_receiver_auxiliary_navigation_inproc.html] +skip-if = (e10s || toolkit == 'gonk') +[test_presentation_receiver_auxiliary_navigation_oop.html] +skip-if = (e10s || toolkit == 'gonk') diff --git a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js new file mode 100644 index 0000000000000..746886e13e4ee --- /dev/null +++ b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation.js @@ -0,0 +1,75 @@ +"use strict"; + +var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL("PresentationSessionChromeScript.js")); +var receiverUrl = SimpleTest.getTestFileURL("file_presentation_receiver_auxiliary_navigation.html"); + +var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +function setup() { + return new Promise(function(aResolve, aReject) { + gScript.sendAsyncMessage("trigger-device-add"); + + var iframe = document.createElement("iframe"); + iframe.setAttribute("mozbrowser", "true"); + iframe.setAttribute("mozpresentation", receiverUrl); + var oop = location.pathname.indexOf('_inproc') == -1; + iframe.setAttribute("remote", oop); + iframe.setAttribute("src", receiverUrl); + + // This event is triggered when the iframe calls "postMessage". + iframe.addEventListener("mozbrowsershowmodalprompt", function listener(aEvent) { + var message = aEvent.detail.message; + if (/^OK /.exec(message)) { + ok(true, "Message from iframe: " + message); + } else if (/^KO /.exec(message)) { + ok(false, "Message from iframe: " + message); + } else if (/^INFO /.exec(message)) { + info("Message from iframe: " + message); + } else if (/^COMMAND /.exec(message)) { + var command = JSON.parse(message.replace(/^COMMAND /, "")); + gScript.sendAsyncMessage(command.name, command.data); + } else if (/^DONE$/.exec(message)) { + ok(true, "Messaging from iframe complete."); + iframe.removeEventListener("mozbrowsershowmodalprompt", listener); + + teardown(); + } + }, false); + + var promise = new Promise(function(aResolve, aReject) { + document.body.appendChild(iframe); + + aResolve(iframe); + }); + obs.notifyObservers(promise, "setup-request-promise", null); + + aResolve(); + }); +} + +function teardown() { + gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() { + gScript.removeMessageListener("teardown-complete", teardownCompleteHandler); + gScript.destroy(); + SimpleTest.finish(); + }); + + gScript.sendAsyncMessage("teardown"); +} + +function runTests() { + setup().then(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPermissions([ + {type: "presentation-device-manage", allow: false, context: document}, + {type: "presentation", allow: true, context: document}, + {type: "browser", allow: true, context: document}, +], function() { + SpecialPowers.pushPrefEnv({ "set": [["dom.presentation.enabled", true], + ["dom.mozBrowserFramesEnabled", true], + ["dom.presentation.session_transport.data_channel.enable", false]]}, + runTests); +}); diff --git a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html new file mode 100644 index 0000000000000..f873fa3da425f --- /dev/null +++ b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_inproc.html @@ -0,0 +1,18 @@ + + + + + + + Test for B2G Presentation API when sender and receiver at the same side + + + + + + Test for receiver page with sandboxed auxiliary navigation browsing context flag. + + + diff --git a/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html new file mode 100644 index 0000000000000..f873fa3da425f --- /dev/null +++ b/dom/presentation/tests/mochitest/test_presentation_receiver_auxiliary_navigation_oop.html @@ -0,0 +1,18 @@ + + + + + + + Test for B2G Presentation API when sender and receiver at the same side + + + + + + Test for receiver page with sandboxed auxiliary navigation browsing context flag. + + +