Bug 1283526 part 1 - Revert behavior of allowfullscreen attribute for non-sandboxed iframe. r?smaug
MozReview-Commit-ID: BayA4tQBsfC
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -2551,20 +2551,16 @@ nsDocShell::GetFullscreenAllowed(bool* a
if (!frameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::allowfullscreen)) {
return NS_OK;
}
} else {
// neither iframe nor embed
return NS_OK;
}
- nsIDocument* doc = frameElement->GetUncomposedDoc();
- if (!doc || !doc->FullscreenEnabledInternal()) {
- return NS_OK;
- }
}
// If we have no parent then we're the root docshell; no ancestor of the
// original docshell doesn't have a allowfullscreen attribute, so
// report fullscreen as allowed.
RefPtr<nsDocShell> parent = GetParentDocshell();
if (!parent) {
*aFullscreenAllowed = true;
@@ -3832,23 +3828,16 @@ nsDocShell::IsSandboxedFrom(nsIDocShell*
return false;
}
}
// Otherwise, we are sandboxed from aTargetDocShell.
return true;
}
-void
-nsDocShell::ApplySandboxAndFullscreenFlags(nsIDocument* aDoc)
-{
- aDoc->SetSandboxFlags(mSandboxFlags);
- aDoc->SetFullscreenEnabled(GetFullscreenAllowed());
-}
-
NS_IMETHODIMP
nsDocShell::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner)
{
NS_ENSURE_ARG_POINTER(aTreeOwner);
*aTreeOwner = mTreeOwner;
NS_IF_ADDREF(*aTreeOwner);
return NS_OK;
@@ -8057,19 +8046,19 @@ nsDocShell::CreateAboutBlankContentViewe
getter_AddRefs(blankDoc));
if (blankDoc) {
// Hack: set the base URI manually, since this document never
// got Reset() with a channel.
blankDoc->SetBaseURI(aBaseURI);
blankDoc->SetContainer(this);
- // Apply the sandbox and fullscreen enabled flags to the document.
- // These are immutable after being set here.
- ApplySandboxAndFullscreenFlags(blankDoc);
+ // Copy our sandbox flags to the document. These are immutable
+ // after being set here.
+ blankDoc->SetSandboxFlags(mSandboxFlags);
// create a content viewer for us and the new document
docFactory->CreateInstanceForDocument(
NS_ISUPPORTS_CAST(nsIDocShell*, this), blankDoc, "view",
getter_AddRefs(viewer));
// hook 'em up
if (viewer) {
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -20,17 +20,16 @@ class nsIPresShell;
[ptr] native nsPresContext(nsPresContext);
[ptr] native nsIPresShell(nsIPresShell);
interface nsIURI;
interface nsIChannel;
interface nsIContentViewer;
interface nsIDOMEventTarget;
interface nsIDocShellLoadInfo;
-interface nsIDocument;
interface nsIEditor;
interface nsIEditingSession;
interface nsISimpleEnumerator;
interface nsIInputStream;
interface nsIRequest;
interface nsISHEntry;
interface nsILayoutHistoryState;
interface nsISecureBrowserUI;
@@ -897,21 +896,16 @@ interface nsIDocShell : nsIDocShellTreeI
/**
* Returns true if we are sandboxed from aTargetDocShell.
* aTargetDocShell - the browsing context we are attempting to navigate.
*/
[noscript,notxpcom,nostdcall] bool isSandboxedFrom(in nsIDocShell aTargetDocShell);
/**
- * Apply sandbox flags and fullscreen enabled flag to the given document.
- */
- [noscript,notxpcom] void applySandboxAndFullscreenFlags(in nsIDocument aDoc);
-
- /**
* This member variable determines whether a document has Mixed Active Content that
* was initially blocked from loading, but the user has choosen to override the
* block and allow the content to load. mMixedContentChannel is set to the document's
* channel when the user allows mixed content. The nsMixedContentBlocker content policy
* checks if the document's root channel matches the mMixedContentChannel. If it matches,
* then Mixed Content is loaded. If it does match, mixed content is blocked.
*
* A match implies that there is definitely mixed active content on a page that was
--- a/dom/base/ImportManager.cpp
+++ b/dom/base/ImportManager.cpp
@@ -596,17 +596,16 @@ ImportLoader::OnStartRequest(nsIRequest*
// The imported document must know which master document it belongs to.
mDocument = do_QueryInterface(importDoc);
nsCOMPtr<nsIDocument> master = mImportParent->MasterDocument();
mDocument->SetMasterDocument(master);
// We want to inherit the sandbox flags and fullscreen enabled flag
// from the master document.
mDocument->SetSandboxFlags(master->GetSandboxFlags());
- mDocument->SetFullscreenEnabled(master->FullscreenEnabledInternal());
// We have to connect the blank document we created with the channel we opened,
// and create its own LoadGroup for it.
nsCOMPtr<nsIStreamListener> listener;
nsCOMPtr<nsILoadGroup> loadGroup;
channel->GetLoadGroup(getter_AddRefs(loadGroup));
nsCOMPtr<nsILoadGroup> newLoadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
NS_ENSURE_TRUE(newLoadGroup, NS_ERROR_OUT_OF_MEMORY);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1450,17 +1450,16 @@ nsIDocument::nsIDocument()
// unless we get a window, and in that case the docshell value will get
// &&-ed in, this is safe.
mAllowDNSPrefetch(true),
mIsBeingUsedAsImage(false),
mHasLinksToUpdate(false),
mFontFaceSetDirty(true),
mGetUserFontSetCalled(false),
mPostedFlushUserFontSet(false),
- mFullscreenEnabled(false),
mPartID(0),
mDidFireDOMContentLoaded(true),
mHasScrollLinkedEffect(false),
mUserHasInteracted(false)
{
SetInDocument();
PR_INIT_CLIST(&mDOMMediaQueryLists);
@@ -2589,17 +2588,18 @@ nsDocument::StartDocumentLoad(const char
}
// If this document is being loaded by a docshell, copy its sandbox flags
// to the document, and store the fullscreen enabled flag. These are
// immutable after being set here.
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aContainer);
if (docShell) {
- docShell->ApplySandboxAndFullscreenFlags(this);
+ nsresult rv = docShell->GetSandboxFlags(&mSandboxFlags);
+ NS_ENSURE_SUCCESS(rv, rv);
WarnIfSandboxIneffective(docShell, mSandboxFlags, GetChannel());
}
// The CSP directive upgrade-insecure-requests not only applies to the
// toplevel document, but also to nested documents. Let's propagate that
// flag from the parent to the nested document.
nsCOMPtr<nsIDocShellTreeItem> treeItem = this->GetDocShell();
if (treeItem) {
@@ -11797,17 +11797,21 @@ GetFullscreenError(nsIDocument* aDoc, bo
// in a Runnable, so don't use GetMozFullScreenEnabled() from a
// Runnable!
return nullptr;
}
if (!nsContentUtils::IsFullScreenApiEnabled()) {
return "FullscreenDeniedDisabled";
}
- if (!aDoc->FullscreenEnabledInternal()) {
+
+ // Ensure that all containing elements are <iframe> and have
+ // allowfullscreen attribute set.
+ nsCOMPtr<nsIDocShell> docShell(aDoc->GetDocShell());
+ if (!docShell || !docShell->GetFullscreenAllowed()) {
return "FullscreenDeniedContainerNotAllowed";
}
return nullptr;
}
bool
nsDocument::FullscreenElementReadyCheck(Element* aElement,
bool aWasCallerChrome)
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2588,21 +2588,16 @@ public:
// Not const because all the full-screen goop is not const
virtual bool FullscreenEnabled() = 0;
virtual Element* GetFullscreenElement() = 0;
bool Fullscreen()
{
return !!GetFullscreenElement();
}
void ExitFullscreen();
- bool FullscreenEnabledInternal() const { return mFullscreenEnabled; }
- void SetFullscreenEnabled(bool aEnabled)
- {
- mFullscreenEnabled = aEnabled;
- }
Element* GetMozPointerLockElement();
void MozExitPointerLock()
{
UnlockPointer(this);
}
bool Hidden() const
{
return mVisibilityState != mozilla::dom::VisibilityState::Visible;
@@ -3054,20 +3049,16 @@ protected:
bool mFontFaceSetDirty : 1;
// Has GetUserFontSet() been called?
bool mGetUserFontSetCalled : 1;
// Do we currently have an event posted to call FlushUserFontSet?
bool mPostedFlushUserFontSet : 1;
- // Whether fullscreen is enabled for this document. This corresponds
- // to the "fullscreen enabled flag" in the HTML spec.
- bool mFullscreenEnabled : 1;
-
enum Type {
eUnknown, // should never be used
eHTML,
eXHTML,
eGenericXML,
eSVG,
eXUL
};
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -378,17 +378,16 @@ XULDocument::StartDocumentLoad(const cha
}
}
}
// NOTE: If this ever starts calling nsDocument::StartDocumentLoad
// we'll possibly need to reset our content type afterwards.
mStillWalking = true;
mMayStartLayout = false;
mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
- mFullscreenEnabled = true;
mChannel = aChannel;
// Get the URI. Note that this should match nsDocShell::OnLoadingSite
nsresult rv =
NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));
NS_ENSURE_SUCCESS(rv, rv);
--- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html
@@ -5,95 +5,35 @@
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://html.spec.whatwg.org/multipage/browsers.html#initialise-the-document-object">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#fullscreen-enabled-flag">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
- function test_allowfullscreen(t, setup_iframe) {
+ async_test(function(t) {
var iframe = document.createElement("iframe");
- setup_iframe(iframe);
iframe.src = "support/blank.htm";
var eventWatcher = new EventWatcher(t, iframe, "load");
document.body.appendChild(iframe);
t.add_cleanup(function() {
document.body.removeChild(iframe);
});
assert_true(document.fullscreenEnabled, "Top level document has fullscreen enabled flag set");
- eventWatcher.wait_for("load").then(t.step_func(function() {
+ eventWatcher.wait_for("load").then(t.step_func_done(function() {
assert_false(iframe.contentDocument.fullscreenEnabled, "Document inside iframe without allowfullscreen attribute should not have fullscreen enabled flag set");
iframe.setAttribute("allowfullscreen", true);
- assert_false(iframe.contentDocument.fullscreenEnabled, "Setting allowfullscreen attribute after document load should not affect fullscreen enabled flag");
- iframe.contentWindow.location.reload();
- return eventWatcher.wait_for("load");
- })).then(t.step_func(function() {
- assert_true(iframe.contentDocument.fullscreenEnabled, "Fullscreen enabled flag should be set when a new document is loaded with allowfullscreen attribute present");
+ assert_true(iframe.contentDocument.fullscreenEnabled, "Fullscreen should be allowed when allowfullscreen attribute is set");
iframe.removeAttribute("allowfullscreen");
- assert_true(iframe.contentDocument.fullscreenEnabled, "Removing allowfullscreen attribute should not affect fullscreen enabled flag");
- iframe.contentWindow.location.reload();
- return eventWatcher.wait_for("load");
- })).then(t.step_func_done(function() {
- assert_false(iframe.contentDocument.fullscreenEnabled, "Fullscreen enabled flag should be reset when a new document is loaded with allowfullscreen attribute absent");
+ assert_false(iframe.contentDocument.fullscreenEnabled, "Fullscreen should be denied when allowfullscreen attribute is removed");
}));
- }
-
- async_test(function(t) {
- test_allowfullscreen(t, function(iframe) {});
}, "iframe-allowfullscreen");
- async_test(function(t) {
- test_allowfullscreen(t, function(iframe) {
- iframe.setAttribute("sandbox", "allow-same-origin");
- });
- }, "iframe-sandbox-allowfullscreen");
-
- /* Fullscreen enabled flag with dialog */
-
- function test_allowfullscreen_dialog(t, setup_iframe, check) {
- var iframe = document.createElement("iframe");
- setup_iframe(iframe);
- iframe.src = "support/blank.htm";
- var eventWatcher = new EventWatcher(t, iframe, "load");
- document.body.appendChild(iframe);
- t.add_cleanup(function() {
- document.body.removeChild(iframe);
- });
-
- var newWin;
- assert_true(document.fullscreenEnabled, "Top level document has fullscreen enabled flag set");
- eventWatcher.wait_for("load").then(t.step_func(function() {
- assert_false(iframe.contentDocument.fullscreenEnabled, "Document inside iframe without allowfullscreen attribute should not have fullscreen enabled flag set");
- newWin = iframe.contentWindow.open("support/blank.htm");
- t.add_cleanup(function() {
- newWin.close();
- });
- var newWinEventWatcher = new EventWatcher(t, newWin, "load");
- return newWinEventWatcher.wait_for("load");
- })).then(t.step_func_done(function() {
- check(newWin);
- }));
- }
-
- async_test(function(t) {
- test_allowfullscreen_dialog(t, function() {}, function(newWin) {
- assert_true(newWin.document.fullscreenEnabled, "Document in the new window is a top level document, thus should has fullscreen enabled flag set");
- });
- }, "iframe-allowfullscreen-dialog");
-
- async_test(function(t) {
- test_allowfullscreen_dialog(t, function(iframe) {
- iframe.setAttribute("sandbox", "allow-same-origin allow-popups");
- }, function(newWin) {
- assert_false(newWin.document.fullscreenEnabled, "Document in the new window should inherit the sandboxed fullscreen flag and should not have fullscreen enabled flag set");
- });
- }, "iframe-sandbox-allowfullscreen-dialog");
-
/* Fullscreen enabled flag with about:blank */
function test_allowfullscreen_noload(setup_iframe, check) {
var iframe = document.createElement("iframe");
setup_iframe(iframe);
document.body.appendChild(iframe);
check(iframe.contentDocument);
document.body.removeChild(iframe);