Bug 1270648 part 5 - Setup the sandboxed fullscreen flag and make it work properly. r?smaug
MozReview-Commit-ID: 3EKRbOyXwNi
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -2497,16 +2497,20 @@ nsDocShell::GetFullscreenAllowed(bool* a
if (mFullscreenAllowed != CHECK_ATTRIBUTES) {
*aFullscreenAllowed = (mFullscreenAllowed == PARENT_ALLOWS);
return NS_OK;
}
// Assume false until we determine otherwise...
*aFullscreenAllowed = false;
+ // If it is sandboxed, fullscreen is not allowed.
+ if (mSandboxFlags & SANDBOXED_FULLSCREEN) {
+ return NS_OK;
+ }
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
if (!win) {
return NS_OK;
}
nsCOMPtr<Element> frameElement = win->GetFrameElementInternal();
if (frameElement && !frameElement->IsXULElement()) {
// We do not allow document inside any containing element other
// than iframe to enter fullscreen.
--- a/dom/base/nsSandboxFlags.h
+++ b/dom/base/nsSandboxFlags.h
@@ -77,22 +77,17 @@ const unsigned long SANDBOXED_AUTOMATIC_
* access the origin's data.
*/
// We don't have an explicit representation of this one, apparently?
// const unsigned long SANDBOXED_STORAGE_AREA_URLS = 0x200;
/**
* This flag prevents content from using the requestFullscreen() method.
*/
-// We don't implement this yet. See represent this as a sandbox flag; instead it's an explicit check for
-// the "allowfullscreen" attribute on the <iframe> that includes us.
-// XXXbz This is wrong in two ways: It can change during the life of the
-// document, and it doesn't get correctly propagated to popups. See
-// https://bugzilla.mozilla.org/show_bug.cgi?id=1270648
-// const unsigned long SANDBOXED_FULLSCREEN = 0x400;
+const unsigned long SANDBOXED_FULLSCREEN = 0x400;
/**
* This flag blocks the document from changing document.domain.
*/
const unsigned long SANDBOXED_DOMAIN = 0x800;
/**
* This flag prevents content from using window.alert(), window.confirm(),
--- a/dom/html/HTMLIFrameElement.cpp
+++ b/dom/html/HTMLIFrameElement.cpp
@@ -211,17 +211,22 @@ HTMLIFrameElement::SetAttr(int32_t aName
return NS_OK;
}
nsresult
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue,
bool aNotify)
{
- if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None && mFrameLoader) {
+ if ((aName == nsGkAtoms::sandbox ||
+ // The allowfullscreen attribute affects the sandboxed fullscreen
+ // flag, thus we should also reapply it if that is changed.
+ aName == nsGkAtoms::allowfullscreen ||
+ aName == nsGkAtoms::mozallowfullscreen) &&
+ aNameSpaceID == kNameSpaceID_None && mFrameLoader) {
// If we have an nsFrameLoader, apply the new sandbox flags.
// Since this is called after the setter, the sandbox flags have
// alreay been updated.
mFrameLoader->ApplySandboxFlags(GetSandboxFlags());
}
return nsGenericHTMLFrameElement::AfterSetAttr(aNameSpaceID, aName, aValue,
aNotify);
}
@@ -253,21 +258,25 @@ HTMLIFrameElement::GetSandboxFlags()
}
// Start off by setting all the restriction flags.
uint32_t out = SANDBOX_ALL_FLAGS;
// Macro for updating the flag according to the keywords
#define SANDBOX_KEYWORD(string, atom, flags) \
if (sandboxAttr->Contains(nsGkAtoms::atom, eIgnoreCase)) { out &= ~(flags); }
+#include "IframeSandboxKeywordList.h"
+#undef SANDBOX_KEYWORD
-#include "IframeSandboxKeywordList.h"
+ if (GetParsedAttr(nsGkAtoms::allowfullscreen) ||
+ GetParsedAttr(nsGkAtoms::mozallowfullscreen)) {
+ out &= ~SANDBOXED_FULLSCREEN;
+ }
return out;
-#undef SANDBOX_KEYWORD
}
JSObject*
HTMLIFrameElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return HTMLIFrameElementBinding::Wrap(aCx, this, aGivenProto);
}
--- 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,18 +5,19 @@
<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>
- async_test(function(t) {
+ function test_allowfullscreen(t, setup_iframe) {
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");
@@ -30,20 +31,31 @@
assert_true(iframe.contentDocument.fullscreenEnabled, "Fullscreen enabled flag should be set when a new document is loaded with allowfullscreen attribute present");
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");
}));
+ }
+
+ 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");
+
+ 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;
@@ -52,12 +64,26 @@
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() {
- assert_true(newWin.document.fullscreenEnabled, "Document in the new window is a top level document, thus should has fullscreen enabled flag set");
+ 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");
</script>