Bug 1643798 - Fix feature policy check for fullscreen so that it gets reflected properly in document.fullscreenEnabled. r=baku

See bug 1606660 comment 8 as to why checking it only in
Element.requestFullscreen is wrong.

Do you know how to test this? I'm not very familiar with feature-policy.

Differential Revision: https://phabricator.services.mozilla.com/D78567
This commit is contained in:
Emilio Cobos Álvarez 2020-06-25 13:17:04 +00:00
Родитель ab97d62b7d
Коммит e916b18fa8
6 изменённых файлов: 29 добавлений и 21 удалений

Просмотреть файл

@ -13596,7 +13596,7 @@ static bool HasFullscreenSubDocument(Document& aDoc) {
// Returns nullptr if a request for Fullscreen API is currently enabled
// in the given document. Returns a static string indicates the reason
// why it is not enabled otherwise.
static const char* GetFullscreenError(Document* aDoc, CallerType aCallerType) {
const char* Document::GetFullscreenError(CallerType aCallerType) {
if (!StaticPrefs::full_screen_api_enabled()) {
return "FullscreenDeniedDisabled";
}
@ -13607,13 +13607,18 @@ static const char* GetFullscreenError(Document* aDoc, CallerType aCallerType) {
return nullptr;
}
if (!aDoc->IsVisible()) {
if (!IsVisible()) {
return "FullscreenDeniedHidden";
}
if (!FeaturePolicyUtils::IsFeatureAllowed(this,
NS_LITERAL_STRING("fullscreen"))) {
return "FullscreenDeniedFeaturePolicy";
}
// Ensure that all containing elements are <iframe> and have allowfullscreen
// attribute set.
BrowsingContext* bc = aDoc->GetBrowsingContext();
BrowsingContext* bc = GetBrowsingContext();
if (!bc || !bc->FullscreenAllowed()) {
return "FullscreenDeniedContainerNotAllowed";
}
@ -13645,7 +13650,7 @@ bool Document::FullscreenElementReadyCheck(FullscreenRequest& aRequest) {
aRequest.Reject("FullscreenDeniedLostWindow");
return false;
}
if (const char* msg = GetFullscreenError(this, aRequest.mCallerType)) {
if (const char* msg = GetFullscreenError(aRequest.mCallerType)) {
aRequest.Reject(msg);
return false;
}
@ -13938,10 +13943,6 @@ bool Document::ApplyFullscreen(UniquePtr<FullscreenRequest> aRequest) {
return true;
}
bool Document::FullscreenEnabled(CallerType aCallerType) {
return !GetFullscreenError(this, aCallerType);
}
void Document::ClearOrientationPendingPromise() {
mOrientationPendingPromise = nullptr;
}

Просмотреть файл

@ -3331,7 +3331,11 @@ class Document : public nsINode,
void MozSetImageElement(const nsAString& aImageElementId, Element* aElement);
nsIURI* GetDocumentURIObject() const;
// Not const because all the fullscreen goop is not const
bool FullscreenEnabled(CallerType aCallerType);
const char* GetFullscreenError(CallerType);
bool FullscreenEnabled(CallerType aCallerType) {
return !GetFullscreenError(aCallerType);
}
Element* GetTopLayerTop();
// Return the fullscreen element in the top layer
Element* GetUnretargetedFullScreenElement();

Просмотреть файл

@ -3100,10 +3100,8 @@ static const char* GetFullscreenError(CallerType aCallerType,
return nullptr;
}
// Ensure feature policy allows using the fullscreen API
if (!FeaturePolicyUtils::IsFeatureAllowed(aDocument,
NS_LITERAL_STRING("fullscreen"))) {
return "FullscreenDeniedFeaturePolicy";
if (const char* error = aDocument->GetFullscreenError(aCallerType)) {
return error;
}
// Bypass user interaction checks if preference is set

Просмотреть файл

@ -6,22 +6,24 @@
<body onload="doRequestFullscreen()">
<script>
function doRequestFullscreen() {
let isChrome = location.search.includes("chrome");
function handler(evt) {
document.removeEventListener("fullscreenchange", handler);
document.removeEventListener("fullscreenerror", handler);
const enabled = isChrome ? SpecialPowers.wrap(document).fullscreenEnabled
: document.fullscreenEnabled;
if (evt.type == "fullscreenchange") {
document.addEventListener("fullscreenchange", () => parent.continueTest(evt.type), {once: true});
document.addEventListener("fullscreenchange", () => parent.continueTest(evt.type, enabled), {once: true});
document.exitFullscreen();
} else {
parent.continueTest(evt.type);
parent.continueTest(evt.type, enabled);
}
}
parent.ok(document.fullscreenEnabled, "Fullscreen " +
`should be enabled in ${parent.testTargetName}`);
document.addEventListener("fullscreenchange", handler);
document.addEventListener("fullscreenerror", handler);
parent.opener.info("Requesting fullscreen");
if (location.search.includes("chrome")) {
if (isChrome) {
SpecialPowers.wrap(document.documentElement).requestFullscreen();
} else {
document.documentElement.requestFullscreen();

Просмотреть файл

@ -61,23 +61,25 @@ async function nextTest() {
const setupForInnerTest = targetName => {
window.testTargetName = targetName;
return new Promise(resolve => {
window.continueTest = e => {
window.continueTest = (event, enabled) => {
delete window.testTargetName;
delete window.continueTest;
resolve(e);
resolve({ event, enabled });
};
document.body.appendChild(iframe);
});
};
const event = await setupForInnerTest(
const { event, enabled } = await setupForInnerTest(
`an iframe+allowfullscreen+allow:${value}+isChrome:${isChrome}`
);
if (isChrome) {
is(event, "fullscreenchange", "Expected a fullscreenchange event");
ok(enabled, "Should be enabled in chrome");
} else {
is(event, expectedEvent, "Expected a " + expectedEvent + " event");
is(enabled, expectedEvent == "fullscreenchange", "Should be appropriately enabled");
}
iframe.remove();
}

Просмотреть файл

@ -17,6 +17,7 @@
assert_array_equals(
document.featurePolicy.getAllowlistForFeature('fullscreen'),
[]);
assert_false(document.fullscreenEnabled, "fullscreenEnabled should reflect feature policy properly");
}, header_policy + ' -- test allowlist is []');
// Test that fullscreen is disallowed on all subframes.