Bug 1495364 - FeaturePolicy: geolocation, r=smaug

This commit is contained in:
Andrea Marchesini 2018-10-06 13:10:30 +02:00
Родитель 64d48fca56
Коммит 42109ceb33
6 изменённых файлов: 126 добавлений и 3 удалений

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

@ -9,6 +9,7 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/CycleCollectedJSContext.h" // for nsAutoMicroTask
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/FeaturePolicyUtils.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/PositionError.h"
#include "mozilla/dom/PositionErrorBinding.h"
@ -1161,6 +1162,23 @@ Geolocation::ShouldBlockInsecureRequests() const
return false;
}
bool
Geolocation::FeaturePolicyBlocked() const
{
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryReferent(mOwner);
if (!win) {
return true;
}
nsCOMPtr<nsIDocument> doc = win->GetExtantDoc();
if (!doc) {
return false;
}
return FeaturePolicyUtils::IsFeatureAllowed(doc,
NS_LITERAL_STRING("geolocation"));
}
bool
Geolocation::ClearPendingRequest(nsGeolocationRequest* aRequest)
{
@ -1221,7 +1239,8 @@ Geolocation::GetCurrentPosition(GeoPositionCallback callback,
std::move(options), static_cast<uint8_t>(mProtocolType), target,
false, EventStateManager::IsHandlingUserInput());
if (!sGeoEnabled || ShouldBlockInsecureRequests()) {
if (!sGeoEnabled || ShouldBlockInsecureRequests() ||
!FeaturePolicyBlocked()) {
nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
target->Dispatch(ev.forget());
return NS_OK;
@ -1304,7 +1323,8 @@ Geolocation::WatchPosition(GeoPositionCallback aCallback,
static_cast<uint8_t>(mProtocolType), target, true,
EventStateManager::IsHandlingUserInput(), watchId);
if (!sGeoEnabled || ShouldBlockInsecureRequests()) {
if (!sGeoEnabled || ShouldBlockInsecureRequests() ||
!FeaturePolicyBlocked()) {
nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
target->Dispatch(ev.forget());
return watchId;

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

@ -207,6 +207,10 @@ private:
// within a context that is not secure.
bool ShouldBlockInsecureRequests() const;
// Return whather the Feature 'geolocation' is blocked by FeaturePolicy
// directive.
bool FeaturePolicyBlocked() const;
// Two callback arrays. The first |mPendingCallbacks| holds objects for only
// one callback and then they are released/removed from the array. The second
// |mWatchingCallbacks| holds objects until the object is explictly removed or

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

@ -31,7 +31,6 @@ static FeatureMap sSupportedFeatures[] = {
{ "camera", FeatureMap::eAll },
{ "encrypted-media", FeatureMap::eAll },
{ "fullscreen", FeatureMap::eAll },
// TODO: not supported yet!!!
{ "geolocation", FeatureMap::eAll },
// TODO: not supported yet!!!
{ "microphone", FeatureMap::eAll },

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

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="geolocation_common.js"></script>
</head>
<body>
<script class="testbody" type="text/javascript">
resume_geolocationProvider(function() {
force_prompt(true, test_currentPosition);
});
let tests = [];
function test_currentPosition() {
navigator.geolocation.getCurrentPosition(() => {
tests.push("allowed");
test_watchPosition();
}, () => {
tests.push("denied");
test_watchPosition();
})
}
function test_watchPosition() {
navigator.geolocation.watchPosition(() => {
tests.push("allowed");
send_results();
}, () => {
tests.push("denied");
send_results();
});
}
function send_results() {
if (tests.length != 2 || tests[0] != tests[1]) {
parent.continueTest("error");
return;
}
parent.continueTest(tests[0]);
}
</script>
</body>
</html>

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

@ -29,6 +29,8 @@ support-files = test_geolocation_is_undefined_when_pref_is_off_iframe.html
[test_timerRestartWatch.html]
[test_windowClose.html]
[test_worseAccuracyDoesNotBlockCallback.html]
[test_featurePolicy.html]
support-files = file_featurePolicy.html
# This test REQUIRES to run on HTTP (_NOT_ HTTPS).
[test_geoWatchPositionBlockedInInsecureContext.html]

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

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for geolocation + featurePolicy</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var tests = [
[ "geolocation 'none'", "denied"],
[ "geolocation", "allowed"],
[ "geolocation 'src'", "allowed"],
[ "geolocation 'self'", "allowed"],
[ "geolocation *", "allowed"],
[ "geolocation http://random.net", "denied"],
[ null, "allowed" ],
];
function nextTest() {
if (tests.length == 0) {
SimpleTest.finish();
return;
}
let test = tests.shift();
var iframe = document.createElement("iframe");
if (test[0]) {
iframe.setAttribute("allow", test[0]);
}
window.continueTest = msg => {
delete window.continueTest;
is(msg, test[1], "Expected " + test[1] + " for " + test[0]);
document.body.removeChild(iframe);
SimpleTest.executeSoon(nextTest);
};
iframe.src = "file_featurePolicy.html";
document.body.appendChild(iframe);
}
SpecialPowers.pushPrefEnv({"set": [["dom.security.featurePolicy.enabled", true]]}).then(nextTest);
</script>
</body>
</html>