Backed out 8 changesets (bug 1805860, bug 1733556) for causing bp-nu bustages in StorageAccessAPIHelper.cpp.

Backed out changeset fa21a55ce837 (bug 1733556)
Backed out changeset 6c09379cdb5a (bug 1733556)
Backed out changeset d8c19265b981 (bug 1733556)
Backed out changeset d48d415fca83 (bug 1805860)
Backed out changeset 3acd0ba1dba6 (bug 1805860)
Backed out changeset d2a6174bbb14 (bug 1805860)
Backed out changeset 48558ba49efe (bug 1805860)
Backed out changeset c8693b9449d3 (bug 1805860)
This commit is contained in:
Stanca Serban 2023-07-18 23:39:08 +03:00
parent 659f59074c
commit 9e82c693d0
36 changed files with 306 additions and 759 deletions

View File

@ -64,6 +64,28 @@
});
});
},
revokePermissions() {
const promisesToRevoke = PERMISSIONS.map(({ name }) => {
return aWindow.navigator.permissions
.revoke({ name })
.then(
({ state }) => is(state, "prompt", `correct state for '${name}'`),
() => ok(false, `revoke should not have rejected for '${name}'`)
);
});
return Promise.all(promisesToRevoke);
},
revokeUnsupportedPermissions() {
const promisesToRevoke = UNSUPPORTED_PERMISSIONS.map(({ name }) => {
return aWindow.navigator.permissions
.revoke({ name })
.then(
() => ok(false, `revoke should not have resolved for '${name}'`),
error => is(error.name, "TypeError", `revoke should have thrown TypeError for '${name}'`)
);
});
return Promise.all(promisesToRevoke);
},
checkPermissions(state) {
const promisesToQuery = PERMISSIONS.map(({ name }) => {
return aWindow.navigator.permissions
@ -125,12 +147,21 @@
() => ok(true, "invalid query should have rejected")
);
},
testInvalidRevoke() {
return aWindow.navigator.permissions
.revoke({ name: "invalid" })
.then(
() => ok(false, "invalid revoke should not have resolved"),
() => ok(true, "invalid revoke should have rejected")
);
},
};
}
function enablePrefs() {
const ops = {
"set": [
["dom.permissions.revoke.enable", true],
["privacy.firstparty.isolate", true],
],
};
@ -163,6 +194,10 @@
.then(() => tester.checkPermissions("denied"))
.then(() => tester.testStatusOnChange())
.then(() => tester.testInvalidQuery())
.then(() => tester.revokeUnsupportedPermissions())
.then(() => tester.revokePermissions())
.then(() => tester.checkPermissions("prompt"))
.then(() => tester.testInvalidRevoke());
})
.then(SimpleTest.finish)
.catch((e) => {

View File

@ -1433,6 +1433,20 @@ bool ContentParent::ValidatePrincipal(
return remoteTypeSiteOriginNoSuffix.Equals(siteOriginNoSuffix);
}
mozilla::ipc::IPCResult ContentParent::RecvRemovePermission(
nsIPrincipal* aPrincipal, const nsACString& aPermissionType,
nsresult* aRv) {
if (!aPrincipal) {
return IPC_FAIL(this, "No principal");
}
if (!ValidatePrincipal(aPrincipal)) {
LogAndAssertFailedPrincipalValidationInfo(aPrincipal, __func__);
}
*aRv = Permissions::RemovePermission(aPrincipal, aPermissionType);
return IPC_OK();
}
/*static*/
already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
const TabContext& aContext, Element* aFrameElement,

View File

@ -322,6 +322,10 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvCreateGMPService();
mozilla::ipc::IPCResult RecvRemovePermission(
nsIPrincipal* aPrincipal, const nsACString& aPermissionType,
nsresult* aRv);
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ContentParent, nsIObserver)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS

View File

@ -1583,6 +1583,8 @@ parent:
nullable nsIReferrerInfo aReferrerInfo,
OriginAttributes aOriginAttributes);
sync RemovePermission(nullable nsIPrincipal principal, nsCString permissionType) returns (nsresult rv);
/**
* Tell the parent that a decoder's' benchmark has been completed.
* The result can then be stored in permanent storage.

View File

@ -209,11 +209,6 @@ parent:
// purpose built UI.
async DiscoverIdentityCredentialFromExternalSource(IdentityCredentialRequestOptions aOptions)
returns (IPCIdentityCredential? identityCredential);
async HasStorageAccessPermission() returns(bool granted);
child:
async NotifyPermissionChange(nsCString type);
};
} // namespace dom

View File

@ -547,18 +547,6 @@ IPCResult WindowGlobalChild::RecvRawMessage(
return IPC_OK();
}
IPCResult WindowGlobalChild::RecvNotifyPermissionChange(
const nsCString& aType) {
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
NS_ENSURE_TRUE(observerService,
IPC_FAIL(this, "Failed to get observer service"));
nsPIDOMWindowInner* notifyTarget =
static_cast<nsPIDOMWindowInner*>(this->GetWindowGlobal());
observerService->NotifyObservers(notifyTarget, "perm-changed-notify-only",
NS_ConvertUTF8toUTF16(aType).get());
return IPC_OK();
}
void WindowGlobalChild::SetDocumentURI(nsIURI* aDocumentURI) {
// Registers a DOM Window with the profiler. It re-registers the same Inner
// Window ID with different URIs because when a Browsing context is first

View File

@ -201,8 +201,6 @@ class WindowGlobalChild final : public WindowGlobalActor,
dom::SessionStoreRestoreData* aData,
RestoreTabContentResolver&& aResolve);
mozilla::ipc::IPCResult RecvNotifyPermissionChange(const nsCString& aType);
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
private:

View File

@ -8,7 +8,6 @@
#include <algorithm>
#include "mozilla/AntiTrackingUtils.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ContentBlockingAllowList.h"
@ -1418,68 +1417,6 @@ IPCResult WindowGlobalParent::RecvDiscoverIdentityCredentialFromExternalSource(
return IPC_OK();
}
IPCResult WindowGlobalParent::RecvHasStorageAccessPermission(
HasStorageAccessPermissionResolver&& aResolve) {
WindowGlobalParent* top = TopWindowContext();
if (!top) {
return IPC_FAIL_NO_REASON(this);
}
nsIPrincipal* topPrincipal = top->DocumentPrincipal();
nsIPrincipal* principal = DocumentPrincipal();
nsCOMPtr<nsIPermissionManager> permMgr =
components::PermissionManager::Service();
if (!permMgr) {
return IPC_FAIL(
this,
"Storage Access Permission: Failed to get Permission Manager service");
}
// Build the permission keys
nsAutoCString requestPermissionKey;
bool success = AntiTrackingUtils::CreateStoragePermissionKey(
principal, requestPermissionKey);
if (!success) {
return IPC_FAIL(
this,
"Storage Access Permission: Failed to create top level permission key");
}
nsAutoCString requestFramePermissionKey;
success = AntiTrackingUtils::CreateStorageFramePermissionKey(
principal, requestFramePermissionKey);
if (!success) {
return IPC_FAIL(
this,
"Storage Access Permission: Failed to create frame permission key");
}
// Test the permission
uint32_t access = nsIPermissionManager::UNKNOWN_ACTION;
nsresult rv = permMgr->TestPermissionFromPrincipal(
topPrincipal, requestPermissionKey, &access);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL(this,
"Storage Access Permission: Permission Manager failed to "
"test permission");
}
if (access == nsIPermissionManager::ALLOW_ACTION) {
aResolve(true);
return IPC_OK();
}
uint32_t frameAccess = nsIPermissionManager::UNKNOWN_ACTION;
rv = permMgr->TestPermissionFromPrincipal(
topPrincipal, requestFramePermissionKey, &frameAccess);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL(this,
"Storage Access Permission: Permission Manager failed to "
"test permission");
}
aResolve(frameAccess == nsIPermissionManager::ALLOW_ACTION);
return IPC_OK();
}
void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
if (GetBrowsingContext()->IsTopContent()) {
Telemetry::Accumulate(Telemetry::ORB_DID_EVER_BLOCK_RESPONSE,

View File

@ -317,9 +317,6 @@ class WindowGlobalParent final : public WindowContext,
const IdentityCredentialRequestOptions& aOptions,
const DiscoverIdentityCredentialFromExternalSourceResolver& aResolver);
mozilla::ipc::IPCResult RecvHasStorageAccessPermission(
HasStorageAccessPermissionResolver&& aResolve);
private:
WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext,
uint64_t aInnerWindowId, uint64_t aOuterWindowId,

View File

@ -413,8 +413,6 @@ RequestStorageAccessSandboxed=document.requestStorageAccess() may not be called
RequestStorageAccessNested=document.requestStorageAccess() may not be called in a nested iframe.
# LOCALIZATION NOTE: Do not translate document.requestStorageAccess(). In some locales it may be preferable to not translate "event handler", either.
RequestStorageAccessUserGesture=document.requestStorageAccess() may only be requested from inside a short running user-generated event handler.
# LOCALIZATION NOTE: Do not translate document.requestStorageAccess(), Permissions Policy and storage-access.
RequestStorageAccessPermissionsPolicy=document.requestStorageAccess() may not be called where the storage-access feature is blocked by the Permissions Policy.
# LOCALIZATION NOTE: Do not translate "Location" and "History".
LocChangeFloodingPrevented=Too many calls to Location or History APIs within a short timeframe.
FolderUploadPrompt.title = Confirm Upload

View File

@ -12,21 +12,15 @@
namespace mozilla::dom {
/* static */
RefPtr<PermissionStatus::CreatePromise> MidiPermissionStatus::Create(
nsPIDOMWindowInner* aWindow, bool aSysex) {
already_AddRefed<PermissionStatus> MidiPermissionStatus::Create(
nsPIDOMWindowInner* aWindow, bool aSysex, ErrorResult& aRv) {
RefPtr<PermissionStatus> status = new MidiPermissionStatus(aWindow, aSysex);
return status->Init()->Then(
GetMainThreadSerialEventTarget(), __func__,
[status](nsresult aOk) {
MOZ_ASSERT(NS_SUCCEEDED(aOk));
return MozPromise<RefPtr<PermissionStatus>, nsresult,
true>::CreateAndResolve(status, __func__);
},
[](nsresult aError) {
MOZ_ASSERT(NS_FAILED(aError));
return MozPromise<RefPtr<PermissionStatus>, nsresult,
true>::CreateAndReject(aError, __func__);
});
aRv = status->Init();
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return status.forget();
}
MidiPermissionStatus::MidiPermissionStatus(nsPIDOMWindowInner* aWindow,

View File

@ -13,14 +13,16 @@ namespace mozilla::dom {
class MidiPermissionStatus final : public PermissionStatus {
public:
static RefPtr<CreatePromise> Create(nsPIDOMWindowInner* aWindow, bool aSysex);
static already_AddRefed<PermissionStatus> Create(nsPIDOMWindowInner* aWindow,
bool aSysex,
ErrorResult& aRv);
private:
~MidiPermissionStatus() {}
MidiPermissionStatus(nsPIDOMWindowInner* aWindow, bool aSysex);
nsLiteralCString GetPermissionType() override;
virtual nsLiteralCString GetPermissionType() override;
bool mSysex;
};

View File

@ -7,10 +7,8 @@
#include "PermissionObserver.h"
#include "mozilla/dom/PermissionStatus.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/Services.h"
#include "mozilla/UniquePtr.h"
#include "nsGlobalWindowInner.h"
#include "nsIObserverService.h"
#include "nsIPermission.h"
#include "PermissionUtils.h"
@ -48,11 +46,6 @@ already_AddRefed<PermissionObserver> PermissionObserver::GetInstance() {
return nullptr;
}
rv = obs->AddObserver(instance, "perm-changed-notify-only", true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
gInstance = instance;
}
@ -73,57 +66,47 @@ void PermissionObserver::RemoveSink(PermissionStatus* aSink) {
mSinks.RemoveElement(aSink);
}
void PermissionObserver::Notify(PermissionName aName,
nsIPrincipal& aPrincipal) {
for (auto* sink : mSinks) {
if (sink->mName != aName) {
continue;
}
nsCOMPtr<nsIPrincipal> sinkPrincipal = sink->GetPrincipal();
if (NS_WARN_IF(!sinkPrincipal) || !aPrincipal.Equals(sinkPrincipal)) {
continue;
}
sink->PermissionChanged();
}
}
NS_IMETHODIMP
PermissionObserver::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
MOZ_ASSERT(!strcmp(aTopic, "perm-changed") ||
!strcmp(aTopic, "perm-changed-notify-only"));
MOZ_ASSERT(!strcmp(aTopic, "perm-changed"));
if (mSinks.IsEmpty()) {
return NS_OK;
}
nsCOMPtr<nsIPermission> perm = nullptr;
nsCOMPtr<nsPIDOMWindowInner> innerWindow = nullptr;
nsAutoCString type;
if (!strcmp(aTopic, "perm-changed")) {
perm = do_QueryInterface(aSubject);
if (!perm) {
return NS_OK;
}
perm->GetType(type);
} else if (!strcmp(aTopic, "perm-changed-notify-only")) {
innerWindow = do_QueryInterface(aSubject);
if (!innerWindow) {
return NS_OK;
}
type = NS_ConvertUTF16toUTF8(aData);
nsCOMPtr<nsIPermission> perm = do_QueryInterface(aSubject);
if (!perm) {
return NS_OK;
}
nsCOMPtr<nsIPrincipal> principal;
perm->GetPrincipal(getter_AddRefs(principal));
if (!principal) {
return NS_OK;
}
nsAutoCString type;
perm->GetType(type);
Maybe<PermissionName> permission = TypeToPermissionName(type);
if (permission) {
for (auto* sink : mSinks) {
if (sink->mName != permission.value()) {
continue;
}
// Check for permissions that are changed for this sink's principal
// via the "perm-changed" notification. These permissions affect
// the window the sink (PermissionStatus) is held in directly.
if (perm && sink->MaybeUpdatedBy(perm)) {
sink->PermissionChanged();
}
// Check for permissions that are changed for this sink's principal
// via the "perm-changed-notify-only" notification. These permissions
// affect the window the sink (PermissionStatus) is held in indirectly- if
// the window is same-party with the secondary key of a permission. For
// example, a "3rdPartyFrameStorage^https://example.com" permission would
// return true on these checks where sink is in a window that is same-site
// with https://example.com.
if (innerWindow && sink->MaybeUpdatedByNotifyOnly(innerWindow)) {
sink->PermissionChanged();
}
}
Notify(permission.value(), *principal);
}
return NS_OK;

View File

@ -35,6 +35,8 @@ class PermissionObserver final : public nsIObserver,
PermissionObserver();
virtual ~PermissionObserver();
void Notify(PermissionName aName, nsIPrincipal& aPrincipal);
nsTArray<PermissionStatus*> mSinks;
};

View File

@ -17,21 +17,15 @@
namespace mozilla::dom {
/* static */
RefPtr<PermissionStatus::CreatePromise> PermissionStatus::Create(
nsPIDOMWindowInner* aWindow, PermissionName aName) {
already_AddRefed<PermissionStatus> PermissionStatus::Create(
nsPIDOMWindowInner* aWindow, PermissionName aName, ErrorResult& aRv) {
RefPtr<PermissionStatus> status = new PermissionStatus(aWindow, aName);
return status->Init()->Then(
GetMainThreadSerialEventTarget(), __func__,
[status](nsresult aOk) {
MOZ_ASSERT(NS_SUCCEEDED(aOk));
return MozPromise<RefPtr<PermissionStatus>, nsresult,
true>::CreateAndResolve(status, __func__);
},
[](nsresult aError) {
MOZ_ASSERT(NS_FAILED(aError));
return MozPromise<RefPtr<PermissionStatus>, nsresult,
true>::CreateAndReject(aError, __func__);
});
aRv = status->Init();
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return status.forget();
}
PermissionStatus::PermissionStatus(nsPIDOMWindowInner* aWindow,
@ -42,15 +36,20 @@ PermissionStatus::PermissionStatus(nsPIDOMWindowInner* aWindow,
KeepAliveIfHasListenersFor(nsGkAtoms::onchange);
}
RefPtr<PermissionStatus::SimplePromise> PermissionStatus::Init() {
nsresult PermissionStatus::Init() {
mObserver = PermissionObserver::GetInstance();
if (NS_WARN_IF(!mObserver)) {
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
return NS_ERROR_FAILURE;
}
mObserver->AddSink(this);
return UpdateState();
nsresult rv = UpdateState();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
PermissionStatus::~PermissionStatus() {
@ -68,15 +67,15 @@ nsLiteralCString PermissionStatus::GetPermissionType() {
return PermissionNameToType(mName);
}
RefPtr<PermissionStatus::SimplePromise> PermissionStatus::UpdateState() {
nsresult PermissionStatus::UpdateState() {
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
if (NS_WARN_IF(!window)) {
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
return NS_ERROR_FAILURE;
}
RefPtr<Document> document = window->GetExtantDoc();
if (NS_WARN_IF(!document)) {
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
return NS_ERROR_FAILURE;
}
uint32_t action = nsIPermissionManager::DENY_ACTION;
@ -84,64 +83,49 @@ RefPtr<PermissionStatus::SimplePromise> PermissionStatus::UpdateState() {
PermissionDelegateHandler* permissionHandler =
document->GetPermissionDelegateHandler();
if (NS_WARN_IF(!permissionHandler)) {
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
return NS_ERROR_FAILURE;
}
nsresult rv = permissionHandler->GetPermissionForPermissionsAPI(
GetPermissionType(), &action);
if (NS_WARN_IF(NS_FAILED(rv))) {
return SimplePromise::CreateAndReject(rv, __func__);
return rv;
}
mState = ActionToPermissionState(action);
return SimplePromise::CreateAndResolve(NS_OK, __func__);
;
return NS_OK;
}
bool PermissionStatus::MaybeUpdatedBy(nsIPermission* aPermission) const {
NS_ENSURE_TRUE(aPermission, false);
already_AddRefed<nsIPrincipal> PermissionStatus::GetPrincipal() const {
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
if (NS_WARN_IF(!window)) {
return false;
return nullptr;
}
Document* doc = window->GetExtantDoc();
if (NS_WARN_IF(!doc)) {
return false;
return nullptr;
}
nsCOMPtr<nsIPrincipal> principal =
Permission::ClonePrincipalForPermission(doc->NodePrincipal());
NS_ENSURE_TRUE(principal, false);
nsCOMPtr<nsIPrincipal> permissionPrincipal;
aPermission->GetPrincipal(getter_AddRefs(permissionPrincipal));
if (!permissionPrincipal) {
return false;
}
return permissionPrincipal->Equals(principal);
}
NS_ENSURE_TRUE(principal, nullptr);
bool PermissionStatus::MaybeUpdatedByNotifyOnly(
nsPIDOMWindowInner* aInnerWindow) const {
return false;
return principal.forget();
}
void PermissionStatus::PermissionChanged() {
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
if (NS_WARN_IF(!window) || !window->IsFullyActive()) {
return;
}
auto oldState = mState;
RefPtr<PermissionStatus> self(this);
UpdateState()->Then(
GetMainThreadSerialEventTarget(), __func__,
[self, oldState]() {
if (self->mState != oldState) {
RefPtr<AsyncEventDispatcher> eventDispatcher =
new AsyncEventDispatcher(self.get(), u"change"_ns,
CanBubble::eNo);
eventDispatcher->PostDOMEvent();
}
},
[]() {
});
UpdateState();
if (mState != oldState) {
RefPtr<AsyncEventDispatcher> eventDispatcher =
new AsyncEventDispatcher(this, u"change"_ns, CanBubble::eNo);
eventDispatcher->PostDOMEvent();
}
}
void PermissionStatus::DisconnectFromOwner() {

View File

@ -10,8 +10,6 @@
#include "mozilla/dom/PermissionsBinding.h"
#include "mozilla/dom/PermissionStatusBinding.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/MozPromise.h"
#include "nsIPermission.h"
namespace mozilla::dom {
@ -21,11 +19,9 @@ class PermissionStatus : public DOMEventTargetHelper {
friend class PermissionObserver;
public:
using CreatePromise = MozPromise<RefPtr<PermissionStatus>, nsresult, true>;
using SimplePromise = MozPromise<nsresult, nsresult, true>;
static RefPtr<CreatePromise> Create(nsPIDOMWindowInner* aWindow,
PermissionName aName);
static already_AddRefed<PermissionStatus> Create(nsPIDOMWindowInner* aWindow,
PermissionName aName,
ErrorResult& aRv);
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
@ -38,7 +34,7 @@ class PermissionStatus : public DOMEventTargetHelper {
PermissionName Name() const { return mName; }
RefPtr<SimplePromise> Init();
nsresult Init();
protected:
~PermissionStatus();
@ -58,26 +54,16 @@ class PermissionStatus : public DOMEventTargetHelper {
virtual nsLiteralCString GetPermissionType();
private:
virtual RefPtr<SimplePromise> UpdateState();
nsresult UpdateState();
// These functions should be called when an permission is updated which may
// change the state of this PermissionStatus. MaybeUpdatedBy accepts the
// permission object itself that is update. When the permission's key is not
// same-origin with this object's owner window, such as for secondary-keyed
// permissions like `3rdPartyFrameStorage^...`, MaybeUpdatedByNotifyOnly will
// be called with the updated window as an argument. MaybeUpdatedByNotifyOnly
// must be defined by PermissionStatus inheritors that are double-keyed.
virtual bool MaybeUpdatedBy(nsIPermission* aPermission) const;
virtual bool MaybeUpdatedByNotifyOnly(nsPIDOMWindowInner* aInnerWindow) const;
already_AddRefed<nsIPrincipal> GetPrincipal() const;
void PermissionChanged();
PermissionName mName;
PermissionState mState;
RefPtr<PermissionObserver> mObserver;
protected:
PermissionState mState;
};
} // namespace mozilla::dom

View File

@ -18,8 +18,7 @@ static const nsLiteralCString kPermissionTypes[] = {
"persistent-storage"_ns,
// "midi" is the only public permission but internally we have both "midi"
// and "midi-sysex" (and yes, this is confusing).
"midi"_ns,
"storage-access"_ns
"midi"_ns
// clang-format on
};
@ -40,12 +39,6 @@ Maybe<PermissionName> TypeToPermissionName(const nsACString& aType) {
return Some(PermissionName::Midi);
}
// "storage-access" permissions are also annoying and require a special case.
if (StringBeginsWith(aType, "3rdPartyStorage^"_ns) ||
StringBeginsWith(aType, "3rdPartyFrameStorage^"_ns)) {
return Some(PermissionName::Storage_access);
}
for (size_t i = 0; i < ArrayLength(kPermissionTypes); ++i) {
if (kPermissionTypes[i].Equals(aType)) {
return Some(static_cast<PermissionName>(i));

View File

@ -13,7 +13,6 @@
#include "mozilla/dom/PermissionStatus.h"
#include "mozilla/dom/PermissionsBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/StorageAccessPermissionStatus.h"
#include "mozilla/Components.h"
#include "nsIPermissionManager.h"
#include "PermissionUtils.h"
@ -41,9 +40,9 @@ JSObject* Permissions::WrapObject(JSContext* aCx,
namespace {
RefPtr<MozPromise<RefPtr<PermissionStatus>, nsresult, true>>
CreatePermissionStatus(JSContext* aCx, JS::Handle<JSObject*> aPermission,
nsPIDOMWindowInner* aWindow, ErrorResult& aRv) {
already_AddRefed<PermissionStatus> CreatePermissionStatus(
JSContext* aCx, JS::Handle<JSObject*> aPermission,
nsPIDOMWindowInner* aWindow, ErrorResult& aRv) {
PermissionDescriptor permission;
JS::Rooted<JS::Value> value(aCx, JS::ObjectOrNullValue(aPermission));
if (NS_WARN_IF(!permission.Init(aCx, value))) {
@ -60,21 +59,18 @@ CreatePermissionStatus(JSContext* aCx, JS::Handle<JSObject*> aPermission,
}
bool sysex = midiPerm.mSysex.WasPassed() && midiPerm.mSysex.Value();
return MidiPermissionStatus::Create(aWindow, sysex);
return MidiPermissionStatus::Create(aWindow, sysex, aRv);
}
case PermissionName::Storage_access:
return StorageAccessPermissionStatus::Create(aWindow);
case PermissionName::Geolocation:
case PermissionName::Notifications:
case PermissionName::Push:
case PermissionName::Persistent_storage:
return PermissionStatus::Create(aWindow, permission.mName);
return PermissionStatus::Create(aWindow, permission.mName, aRv);
default:
MOZ_ASSERT_UNREACHABLE("Unhandled type");
return MozPromise<RefPtr<PermissionStatus>, nsresult,
true>::CreateAndReject(NS_ERROR_NOT_IMPLEMENTED,
__func__);
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
}
}
@ -88,29 +84,98 @@ already_AddRefed<Promise> Permissions::Query(JSContext* aCx,
return nullptr;
}
RefPtr<PermissionStatus> status =
CreatePermissionStatus(aCx, aPermission, mWindow, aRv);
if (NS_WARN_IF(aRv.Failed())) {
MOZ_ASSERT(!status);
return nullptr;
}
MOZ_ASSERT(status);
RefPtr<Promise> promise = Promise::Create(mWindow->AsGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
auto permissionStatusPromise =
CreatePermissionStatus(aCx, aPermission, mWindow, aRv);
if (!permissionStatusPromise) {
promise->MaybeResolve(status);
return promise.forget();
}
/* static */
nsresult Permissions::RemovePermission(nsIPrincipal* aPrincipal,
const nsACString& aPermissionType) {
MOZ_ASSERT(XRE_IsParentProcess());
nsCOMPtr<nsIPermissionManager> permMgr =
components::PermissionManager::Service();
if (NS_WARN_IF(!permMgr)) {
return NS_ERROR_FAILURE;
}
return permMgr->RemoveFromPrincipal(aPrincipal, aPermissionType);
}
already_AddRefed<Promise> Permissions::Revoke(JSContext* aCx,
JS::Handle<JSObject*> aPermission,
ErrorResult& aRv) {
if (!mWindow) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
permissionStatusPromise->Then(
GetMainThreadSerialEventTarget(), __func__,
[promise](const RefPtr<PermissionStatus>& aStatus) {
promise->MaybeResolve(aStatus);
return;
},
[](nsresult aError) {
MOZ_ASSERT(NS_FAILED(aError));
NS_WARNING("Failed PermissionStatus creation");
return;
});
PermissionDescriptor permission;
JS::Rooted<JS::Value> value(aCx, JS::ObjectOrNullValue(aPermission));
if (NS_WARN_IF(!permission.Init(aCx, value))) {
aRv.NoteJSContextException(aCx);
return nullptr;
}
RefPtr<Promise> promise = Promise::Create(mWindow->AsGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
nsCOMPtr<Document> document = mWindow->GetExtantDoc();
if (!document) {
promise->MaybeReject(NS_ERROR_UNEXPECTED);
return promise.forget();
}
nsCOMPtr<nsIPermissionManager> permMgr =
components::PermissionManager::Service();
if (NS_WARN_IF(!permMgr)) {
promise->MaybeReject(NS_ERROR_FAILURE);
return promise.forget();
}
const nsLiteralCString& permissionType =
PermissionNameToType(permission.mName);
nsresult rv;
if (XRE_IsParentProcess()) {
rv = RemovePermission(document->NodePrincipal(), permissionType);
} else {
// Permissions can't be removed from the content process. Send a message
// to the parent; `ContentParent::RecvRemovePermission` will call
// `RemovePermission`.
ContentChild::GetSingleton()->SendRemovePermission(
document->NodePrincipal(), permissionType, &rv);
}
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(rv);
return promise.forget();
}
RefPtr<PermissionStatus> status =
CreatePermissionStatus(aCx, aPermission, mWindow, aRv);
if (NS_WARN_IF(aRv.Failed())) {
MOZ_ASSERT(!status);
return nullptr;
}
MOZ_ASSERT(status);
promise->MaybeResolve(status);
return promise.forget();
}

View File

@ -35,6 +35,13 @@ class Permissions final : public nsISupports, public nsWrapperCache {
JS::Handle<JSObject*> aPermission,
ErrorResult& aRv);
static nsresult RemovePermission(nsIPrincipal* aPrincipal,
const nsACString& aPermissionType);
already_AddRefed<Promise> Revoke(JSContext* aCx,
JS::Handle<JSObject*> aPermission,
ErrorResult& aRv);
private:
~Permissions();

View File

@ -1,88 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/StorageAccessPermissionStatus.h"
#include "mozilla/AntiTrackingUtils.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/FeaturePolicyUtils.h"
#include "mozilla/dom/PermissionStatus.h"
#include "mozilla/dom/PermissionStatusBinding.h"
namespace mozilla::dom {
// static
RefPtr<PermissionStatus::CreatePromise> StorageAccessPermissionStatus::Create(
nsPIDOMWindowInner* aWindow) {
RefPtr<PermissionStatus> status = new StorageAccessPermissionStatus(aWindow);
return status->Init()->Then(
GetMainThreadSerialEventTarget(), __func__,
[status](nsresult aOk) {
MOZ_ASSERT(NS_SUCCEEDED(aOk));
return MozPromise<RefPtr<PermissionStatus>, nsresult,
true>::CreateAndResolve(status, __func__);
},
[](nsresult aError) {
MOZ_ASSERT(NS_FAILED(aError));
return MozPromise<RefPtr<PermissionStatus>, nsresult,
true>::CreateAndReject(aError, __func__);
});
}
StorageAccessPermissionStatus::StorageAccessPermissionStatus(
nsPIDOMWindowInner* aWindow)
: PermissionStatus(aWindow, PermissionName::Storage_access) {}
RefPtr<PermissionStatus::SimplePromise>
StorageAccessPermissionStatus::UpdateState() {
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
if (NS_WARN_IF(!window)) {
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
}
WindowGlobalChild* wgc = window->GetWindowGlobalChild();
if (NS_WARN_IF(!wgc)) {
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
}
// Perform a Permission Policy Request
if (!FeaturePolicyUtils::IsFeatureAllowed(window->GetExtantDoc(),
u"storage-access"_ns)) {
mState = PermissionState::Prompt;
return SimplePromise::CreateAndResolve(NS_OK, __func__);
}
RefPtr<StorageAccessPermissionStatus> self(this);
return wgc->SendHasStorageAccessPermission()->Then(
GetMainThreadSerialEventTarget(), __func__,
[self](bool aGranted) {
if (aGranted) {
self->mState = PermissionState::Granted;
} else {
self->mState = PermissionState::Prompt;
}
return SimplePromise::CreateAndResolve(NS_OK, __func__);
},
[](mozilla::ipc::ResponseRejectReason aError) {
return SimplePromise::CreateAndResolve(NS_ERROR_FAILURE, __func__);
});
}
bool StorageAccessPermissionStatus::MaybeUpdatedBy(
nsIPermission* aPermission) const {
return false;
}
bool StorageAccessPermissionStatus::MaybeUpdatedByNotifyOnly(
nsPIDOMWindowInner* aInnerWindow) const {
nsPIDOMWindowInner* owner = GetOwner();
NS_ENSURE_TRUE(owner, false);
NS_ENSURE_TRUE(aInnerWindow, false);
return owner->WindowID() == aInnerWindow->WindowID();
}
} // namespace mozilla::dom

View File

@ -1,30 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_StorageAccessPermissionStatus_h_
#define mozilla_dom_StorageAccessPermissionStatus_h_
#include "mozilla/dom/PermissionStatus.h"
namespace mozilla::dom {
class StorageAccessPermissionStatus final : public PermissionStatus {
public:
static RefPtr<CreatePromise> Create(nsPIDOMWindowInner* aWindow);
private:
explicit StorageAccessPermissionStatus(nsPIDOMWindowInner* aWindow);
RefPtr<SimplePromise> UpdateState() override;
bool MaybeUpdatedBy(nsIPermission* aPermission) const override;
bool MaybeUpdatedByNotifyOnly(
nsPIDOMWindowInner* aInnerWindow) const override;
};
} // namespace mozilla::dom
#endif // mozilla_dom_StorageAccessPermissionStatus_h_

View File

@ -11,7 +11,6 @@ EXPORTS.mozilla.dom += [
"MidiPermissionStatus.h",
"Permissions.h",
"PermissionStatus.h",
"StorageAccessPermissionStatus.h",
]
UNIFIED_SOURCES += [
@ -20,7 +19,6 @@ UNIFIED_SOURCES += [
"Permissions.cpp",
"PermissionStatus.cpp",
"PermissionUtils.cpp",
"StorageAccessPermissionStatus.cpp",
]
MOCHITEST_MANIFESTS += ["tests/mochitest.ini"]

View File

@ -1,30 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Helper for Permissions API Test</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<script>
'use strict';
async function helper() {
let status = await navigator.permissions
.query({ name: "storage-access" });
status.onchange = () => {
status.onchange = null;
parent.postMessage(status.state, "*")
};
parent.postMessage("ready", "*");
}
</script>
</head>
<body onload="helper()">
</body>
</html>

View File

@ -1,7 +1,6 @@
[DEFAULT]
support-files =
file_empty.html
file_storage_access_notification_helper.html
prefs =
dom.security.featurePolicy.header.enabled=true
dom.security.featurePolicy.webidl.enabled=true
@ -10,5 +9,3 @@ prefs =
fail-if = xorigin
[test_permissions_api.html]
skip-if = xorigin # Hangs
[test_storage_access_notification.html]
skip-if = xorigin # Hangs

View File

@ -106,13 +106,6 @@
type: 'persistent-storage',
expected: 'denied',
},
{
id: 'query storage-access unknown',
top: UNKNOWN_ACTION,
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'prompt',
},
{
id: 'query navigation top prompt',
top: PROMPT_ACTION,
@ -141,13 +134,6 @@
type: 'persistent-storage',
expected: 'denied',
},
{
id: 'query storage-access top prompt',
top: PROMPT_ACTION,
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'prompt',
},
{
id: 'query navigation top denied',
top: DENY_ACTION,
@ -176,13 +162,6 @@
type: 'persistent-storage',
expected: 'denied',
},
{
id: 'query storage-access top denied',
top: DENY_ACTION,
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'prompt',
},
{
id: 'query navigation top granted',
top: ALLOW_ACTION,
@ -211,13 +190,6 @@
type: 'persistent-storage',
expected: 'denied',
},
{
id: 'query storage-access top granted',
top: ALLOW_ACTION,
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'granted',
},
{
id: 'query navigation top denied, iframe has allow attribute',
top: DENY_ACTION,
@ -250,38 +222,7 @@
type: 'geo',
expected: 'prompt',
},
{
id: 'query storage-access top denied, iframe has allow none attribute',
top: DENY_ACTION,
allow: "storage-access 'none'",
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'prompt',
},
{
id: 'query storage-access top granted, iframe has allow none attribute',
top: ALLOW_ACTION,
allow: "storage-access 'none'",
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'prompt',
},
{
id: 'query storage-access top prompt, iframe has allow none attribute',
top: PROMPT_ACTION,
allow: "storage-access 'none'",
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'prompt',
},
{
id: 'query storage-access top unknown, iframe has allow none attribute',
top: UNKNOWN_ACTION,
allow: "storage-access 'none'",
name: 'storage-access',
type: '3rdPartyFrameStorage^https://example.org',
expected: 'prompt',
},
];
SimpleTest.waitForExplicitFinish();

View File

@ -63,6 +63,28 @@
await SpecialPowers.popPermissions();
return SpecialPowers.pushPermissions(permissions);
},
revokePermissions() {
const promisesToRevoke = PERMISSIONS.map(({ name }) => {
return iframeWindow.navigator.permissions
.revoke({ name })
.then(
({ state }) => is(state, 'prompt', `correct state for '${name}'`),
() => ok(false, `revoke should not have rejected for '${name}'`)
);
});
return Promise.all(promisesToRevoke);
},
revokeUnsupportedPermissions() {
const promisesToRevoke = UNSUPPORTED_PERMISSIONS.map(({ name }) => {
return iframeWindow.navigator.permissions
.revoke({ name })
.then(
() => ok(false, `revoke should not have resolved for '${name}'`),
error => is(error.name, 'TypeError', `revoke should have thrown TypeError for '${name}'`)
);
});
return Promise.all(promisesToRevoke);
},
checkPermissions(expectedState) {
const promisesToQuery = PERMISSIONS.map(({ name: expectedName }) => {
return iframeWindow.navigator.permissions
@ -127,6 +149,14 @@
() => ok(true, 'invalid query should have rejected')
);
},
testInvalidRevoke() {
return iframeWindow.navigator.permissions
.revoke({ name: 'invalid' })
.then(
() => ok(false, 'invalid revoke should not have resolved'),
() => ok(true, 'invalid revoke should have rejected')
);
},
async testNotFullyActiveDoc() {
const iframe1 = await createIframe();
const expectedErrorClass = iframe1.contentWindow.DOMException;
@ -214,6 +244,15 @@
};
}
function enablePrefs() {
const ops = {
'set': [
['dom.permissions.revoke.enable', true],
],
};
return SpecialPowers.pushPrefEnv(ops);
}
function createIframe() {
return new Promise((resolve) => {
const iframe = document.createElement('iframe');
@ -224,7 +263,8 @@
}
window.onload = () => {
createIframe()
enablePrefs()
.then(createIframe)
.then(createPermissionTester)
.then((tester) => {
return tester
@ -239,6 +279,10 @@
.then(() => tester.checkPermissions('denied'))
.then(() => tester.testStatusOnChange())
.then(() => tester.testInvalidQuery())
.then(() => tester.revokeUnsupportedPermissions())
.then(() => tester.revokePermissions())
.then(() => tester.checkPermissions('prompt'))
.then(() => tester.testInvalidRevoke())
.then(() => tester.testNotFullyActiveDoc())
.then(() => tester.testNotFullyActiveChange());
})

View File

@ -1,50 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for Permissions API</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<script type="application/javascript">
'use strict';
SimpleTest.waitForExplicitFinish();
async function setPermission(type, allow) {
await SpecialPowers.popPermissions();
await SpecialPowers.pushPermissions(
[{ type, allow, context: document }]
);
}
const {
UNKNOWN_ACTION,
PROMPT_ACTION,
ALLOW_ACTION,
DENY_ACTION
} = SpecialPowers.Ci.nsIPermissionManager;
window.addEventListener(
"message",
(event) => {
if (event.data == "ready") {
setPermission("3rdPartyFrameStorage^https://example.org", ALLOW_ACTION);
} else {
is(event.data, "granted", "storage-access permission should change to granted after the permission is set");
SimpleTest.finish();
}
}
);
</script>
</head>
<body>
<iframe id="frame" src="https://example.org/tests/dom/permission/tests/file_storage_access_notification_helper.html"/>
</body>
</html>

View File

@ -37,7 +37,6 @@ static FeatureMap sSupportedFeatures[] = {
{"web-share", FeaturePolicyUtils::FeaturePolicyValue::eSelf},
{"gamepad", FeaturePolicyUtils::FeaturePolicyValue::eAll},
{"speaker-selection", FeaturePolicyUtils::FeaturePolicyValue::eSelf},
{"storage-access", FeaturePolicyUtils::FeaturePolicyValue::eAll},
};
/*

View File

@ -19,7 +19,6 @@ let supportedFeatures = [
"microphone",
"midi",
"payment",
"storage-access",
"display-capture",
"document-domain",
"speaker-selection",

View File

@ -12,8 +12,7 @@ enum PermissionName {
"notifications",
"push",
"persistent-storage",
"midi",
"storage-access" // Defined in https://privacycg.github.io/storage-access/#permissions-integration
"midi"
};
[GenerateInit]
@ -33,4 +32,6 @@ dictionary MidiPermissionDescriptor : PermissionDescriptor {
interface Permissions {
[NewObject]
Promise<PermissionStatus> query(object permission);
[NewObject, Pref="dom.permissions.revoke.enable"]
Promise<PermissionStatus> revoke(object permission);
};

View File

@ -10,10 +10,7 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ContentPrincipal.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/ExpandedPrincipal.h"
#include "mozilla/net/NeckoMessageUtils.h"
#include "mozilla/Permission.h"
@ -32,7 +29,6 @@
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsCRT.h"
#include "nsDebug.h"
#include "nsEffectiveTLDService.h"
#include "nsIConsoleService.h"
#include "nsIUserIdleService.h"
@ -191,29 +187,6 @@ bool IsSiteScopedPermission(const nsACString& aType) {
return false;
}
// Array of permission type prefixes which have a secondary key encoded in the
// permission type. These permissions will not be stored in-process with the
// secondary key, but updates to them will cause "perm-changed" notifications on
// processes for that key.
static constexpr std::array<nsLiteralCString, 3> kSecondaryKeyedPermissions = {
{"3rdPartyStorage^"_ns, "AllowStorageAccessRequest^"_ns,
"3rdPartyFrameStorage^"_ns}};
bool GetSecondaryKey(const nsACString& aType, nsACString& aSecondaryKey) {
aSecondaryKey.Truncate();
if (aType.IsEmpty()) {
return false;
}
for (const auto& perm : kSecondaryKeyedPermissions) {
if (aType.Length() > perm.Length() &&
Substring(aType, 0, perm.Length()) == perm) {
aSecondaryKey = Substring(aType, perm.Length());
return true;
}
}
return false;
}
void OriginAppendOASuffix(OriginAttributes aOriginAttributes,
bool aForceStripOA, nsACString& aOrigin) {
PermissionManager::MaybeStripOriginAttributes(aForceStripOA,
@ -603,49 +576,6 @@ bool IsPersistentExpire(uint32_t aExpire, const nsACString& aType) {
return res;
}
nsresult NotifySecondaryKeyPermissionUpdateInContentProcess(
const nsACString& aType, const nsACString& aSecondaryKey,
nsIPrincipal* aTopPrincipal) {
NS_ENSURE_ARG_POINTER(aTopPrincipal);
MOZ_ASSERT(XRE_IsParentProcess());
AutoTArray<RefPtr<BrowsingContextGroup>, 5> bcGroups;
BrowsingContextGroup::GetAllGroups(bcGroups);
for (const auto& bcGroup : bcGroups) {
for (const auto& topBC : bcGroup->Toplevels()) {
CanonicalBrowsingContext* topCBC = topBC->Canonical();
RefPtr<nsIURI> topURI = topCBC->GetCurrentURI();
if (!topURI) {
continue;
}
bool thirdParty;
nsresult rv = aTopPrincipal->IsThirdPartyURI(topURI, &thirdParty);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
if (!thirdParty) {
AutoTArray<RefPtr<BrowsingContext>, 5> bcs;
topBC->GetAllBrowsingContextsInSubtree(bcs);
for (const auto& bc : bcs) {
CanonicalBrowsingContext* cbc = bc->Canonical();
ContentParent* cp = cbc->GetContentParent();
if (!cp) {
continue;
}
if (cp->NeedsPermissionsUpdate(aSecondaryKey)) {
WindowGlobalParent* wgp = cbc->GetCurrentWindowGlobal();
if (!wgp) {
continue;
}
bool success = wgp->SendNotifyPermissionChange(aType);
Unused << NS_WARN_IF(!success);
}
}
}
}
}
return NS_OK;
}
} // namespace
////////////////////////////////////////////////////////////////////////////////
@ -1829,21 +1759,13 @@ nsresult PermissionManager::AddInternal(
nsAutoCString permissionKey;
GetKeyForPermission(aPrincipal, aType, permissionKey);
bool isSecondaryKeyed;
nsAutoCString secondaryKey;
isSecondaryKeyed = GetSecondaryKey(aType, secondaryKey);
if (isSecondaryKeyed) {
NotifySecondaryKeyPermissionUpdateInContentProcess(aType, secondaryKey,
aPrincipal);
}
nsTArray<ContentParent*> cplist;
ContentParent::GetAll(cplist);
for (uint32_t i = 0; i < cplist.Length(); ++i) {
ContentParent* cp = cplist[i];
if (cp->NeedsPermissionsUpdate(permissionKey)) {
if (cp->NeedsPermissionsUpdate(permissionKey))
Unused << cp->SendAddPermission(permission);
}
}
}

View File

@ -82,6 +82,8 @@ description = for bug 1514869 - layout is blocked on needing sync access to a sp
description = for bug 1514869 - layout is blocked on font lookup, needs complete family-name information - not used after loading is complete
[PContent::GetHyphDict]
description = for bug 1487212 - layout requires hyphenation data from a given omnijar resource - only called once per locale by a given content process
[PContent::RemovePermission]
description = legacy sync IPC - please add detailed description
[PGMP::StartPlugin]
description = legacy sync IPC - please add detailed description
[PGMPService::LaunchGMP]

View File

@ -12,13 +12,11 @@
#include "mozilla/Components.h"
#include "mozilla/ContentBlockingAllowList.h"
#include "mozilla/ContentBlockingUserInteraction.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/BrowsingContextGroup.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/FeaturePolicy.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/net/CookieJarSettings.h"
@ -868,21 +866,6 @@ Maybe<bool> StorageAccessAPIHelper::CheckCallingContextDecidesStorageAccessAPI(
return Some(true);
}
if (aRequestingStorageAccess) {
// Perform a Permission Policy Request
FeaturePolicy* policy = aDocument->FeaturePolicy();
MOZ_ASSERT(policy);
if (!policy->AllowsFeature(u"storage-access"_ns,
dom::Optional<nsAString>())) {
nsContentUtils::ReportToConsole(
nsIScriptError::errorFlag, nsLiteralCString("requestStorageAccess"),
aDocument, nsContentUtils::eDOM_PROPERTIES,
"RequestStorageAccessPermissionsPolicy");
return Some(false);
}
}
RefPtr<BrowsingContext> bc = aDocument->GetBrowsingContext();
if (!bc) {
return Some(false);

View File

@ -36,8 +36,7 @@ this.AntiTracking = {
.STATE_COOKIES_BLOCKED_TRACKER,
iframeSandbox = null,
accessRemoval = null,
callbackAfterRemoval = null,
iframeAllow = null
callbackAfterRemoval = null
) {
// Normal mode
this.runTest(
@ -52,8 +51,7 @@ this.AntiTracking = {
false,
iframeSandbox,
accessRemoval,
callbackAfterRemoval,
iframeAllow
callbackAfterRemoval
);
// Private mode
@ -69,8 +67,7 @@ this.AntiTracking = {
true,
iframeSandbox,
accessRemoval,
callbackAfterRemoval,
iframeAllow
callbackAfterRemoval
);
},
@ -87,8 +84,7 @@ this.AntiTracking = {
runInPrivateWindow = false,
iframeSandbox = null,
accessRemoval = null,
callbackAfterRemoval = null,
iframeAllow = null
callbackAfterRemoval = null
) {
let runExtraTests = true;
let options = {};
@ -132,7 +128,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval,
callbackAfterRemoval,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -157,7 +152,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval: null, // only passed with non-blocking callback
callbackAfterRemoval: null,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -172,7 +166,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval: null, // only passed with non-blocking callback
callbackAfterRemoval: null,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -189,7 +182,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval: null, // only passed with non-blocking callback
callbackAfterRemoval: null,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -204,7 +196,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval: null, // only passed with non-blocking callback
callbackAfterRemoval: null,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -222,7 +213,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval: null, // only passed with non-blocking callback
callbackAfterRemoval: null,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -240,7 +230,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval,
callbackAfterRemoval,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -260,7 +249,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval,
callbackAfterRemoval,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -279,7 +267,6 @@ this.AntiTracking = {
accessRemoval: null, // only passed with non-blocking callback
callbackAfterRemoval: null,
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -294,7 +281,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval,
callbackAfterRemoval,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
@ -310,7 +296,6 @@ this.AntiTracking = {
accessRemoval: null, // only passed with non-blocking callback
callbackAfterRemoval: null,
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
} else {
@ -326,7 +311,6 @@ this.AntiTracking = {
iframeSandbox,
accessRemoval: options.accessRemoval,
callbackAfterRemoval: options.callbackAfterRemoval,
iframeAllow,
});
this._createCleanupTask(cleanupFunction);
}
@ -342,8 +326,7 @@ this.AntiTracking = {
runInPrivateWindow,
iframeSandbox,
false,
extraPrefs,
iframeAllow
extraPrefs
);
this._createCleanupTask(cleanupFunction);
@ -358,8 +341,7 @@ this.AntiTracking = {
[
["network.cookie.rejectForeignWithExceptions.enabled", true],
...(extraPrefs || []),
],
iframeAllow
]
);
this._createCleanupTask(cleanupFunction);
@ -372,8 +354,7 @@ this.AntiTracking = {
runInPrivateWindow,
iframeSandbox,
true,
extraPrefs,
iframeAllow
extraPrefs
);
this._createCleanupTask(cleanupFunction);
@ -388,8 +369,7 @@ this.AntiTracking = {
[
["network.cookie.rejectForeignWithExceptions.enabled", true],
...(extraPrefs || []),
],
iframeAllow
]
);
this._createCleanupTask(cleanupFunction);
}
@ -405,8 +385,7 @@ this.AntiTracking = {
runInPrivateWindow,
iframeSandbox,
false,
extraPrefs,
iframeAllow
extraPrefs
);
this._createCleanupTask(cleanupFunction);
@ -421,8 +400,7 @@ this.AntiTracking = {
[
["network.cookie.rejectForeignWithExceptions.enabled", true],
...(extraPrefs || []),
],
iframeAllow
]
);
this._createCleanupTask(cleanupFunction);
@ -435,8 +413,7 @@ this.AntiTracking = {
runInPrivateWindow,
iframeSandbox,
true,
extraPrefs,
iframeAllow
extraPrefs
);
this._createCleanupTask(cleanupFunction);
@ -451,8 +428,7 @@ this.AntiTracking = {
[
["network.cookie.rejectForeignWithExceptions.enabled", true],
...(extraPrefs || []),
],
iframeAllow
]
);
this._createCleanupTask(cleanupFunction);
}
@ -596,8 +572,6 @@ this.AntiTracking = {
" window " +
" with iframe sandbox set to " +
options.iframeSandbox +
" and iframe allow set to " +
options.iframeAllow +
" and access removal set to " +
options.accessRemoval +
(typeof options.thirdPartyPage == "string"
@ -753,7 +727,6 @@ this.AntiTracking = {
: null,
accessRemoval: options.accessRemoval,
iframeSandbox: options.iframeSandbox,
iframeAllow: options.iframeAllow,
allowList: options.allowList,
doAccessRemovalChecks,
},
@ -771,9 +744,6 @@ this.AntiTracking = {
if (typeof obj.iframeSandbox == "string") {
ifr.setAttribute("sandbox", obj.iframeSandbox);
}
if (typeof obj.iframeAllow == "string") {
ifr.setAttribute("allow", obj.iframeAllow);
}
content.addEventListener("message", function msg(event) {
if (event.data.type == "finish") {
@ -813,9 +783,6 @@ this.AntiTracking = {
if (typeof obj.iframeSandbox == "string") {
ifr.setAttribute("sandbox", obj.iframeSandbox);
}
if (typeof obj.iframeAllow == "string") {
ifr.setAttribute("allow", obj.iframeAllow);
}
content.addEventListener("message", function msg(event) {
if (event.data.type == "finish") {
@ -877,7 +844,6 @@ this.AntiTracking = {
? options.callbackAfterRemoval.toString()
: null,
iframeSandbox: options.iframeSandbox,
iframeAllow: options.iframeAllow,
},
],
async function (obj) {
@ -891,9 +857,6 @@ this.AntiTracking = {
if (typeof obj.iframeSandbox == "string") {
ifr.setAttribute("sandbox", obj.iframeSandbox);
}
if (typeof obj.iframeAllow == "string") {
ifr.setAttribute("allow", obj.iframeAllow);
}
content.addEventListener("message", function msg(event) {
if (event.data.type == "finish") {
@ -1039,8 +1002,7 @@ this.AntiTracking = {
runInPrivateWindow,
iframeSandbox,
testInSubIFrame,
extraPrefs,
iframeAllow
extraPrefs
) {
add_task(async function () {
info(
@ -1105,7 +1067,6 @@ this.AntiTracking = {
blockingCallback: blockingCallback.toString(),
nonBlockingCallback: nonBlockingCallback.toString(),
iframeSandbox,
iframeAllow,
},
],
async function (obj) {
@ -1118,9 +1079,6 @@ this.AntiTracking = {
if (typeof obj.iframeSandbox == "string") {
ifr.setAttribute("sandbox", obj.iframeSandbox);
}
if (typeof obj.iframeAllow == "string") {
ifr.setAttribute("allow", obj.iframeAllow);
}
content.addEventListener("message", function msg(event) {
if (event.data.type == "finish") {
@ -1165,8 +1123,7 @@ this.AntiTracking = {
runInPrivateWindow,
iframeSandbox,
testInSubIFrame,
extraPrefs,
iframeAllow
extraPrefs
) {
add_task(async function () {
info(
@ -1231,7 +1188,6 @@ this.AntiTracking = {
popup: TEST_POPUP_PAGE,
blockingCallback: blockingCallback.toString(),
iframeSandbox,
iframeAllow,
},
],
async function (obj) {
@ -1242,9 +1198,6 @@ this.AntiTracking = {
if (typeof obj.iframeSandbox == "string") {
ifr.setAttribute("sandbox", obj.iframeSandbox);
}
if (typeof obj.iframeAllow == "string") {
ifr.setAttribute("allow", obj.iframeAllow);
}
content.document.body.appendChild(ifr);
ifr.src = obj.page;
await loading;
@ -1365,7 +1318,6 @@ this.AntiTracking = {
popup: TEST_POPUP_PAGE,
nonBlockingCallback: nonBlockingCallback.toString(),
iframeSandbox,
iframeAllow,
},
],
async function (obj) {
@ -1376,9 +1328,6 @@ this.AntiTracking = {
if (typeof obj.iframeSandbox == "string") {
ifr.setAttribute("sandbox", obj.iframeSandbox);
}
if (typeof obj.iframeAllow == "string") {
ifr.setAttribute("allow", obj.iframeAllow);
}
content.document.body.appendChild(ifr);
ifr.src = obj.page;
await loading;

View File

@ -212,40 +212,3 @@ AntiTracking.runTest(
false, // no user-interaction test
0 // no blocking notifications
);
AntiTracking.runTest(
"Storage Access API called in a Permission Policy controlled iframe",
// blocking callback
async _ => {
let [threw, rejected] = await callRequestStorageAccess();
ok(!threw, "requestStorageAccess should not throw");
ok(rejected, "requestStorageAccess shouldn't be available");
},
null, // non-blocking callback
// cleanup function
async _ => {
// Only clear the user-interaction permissions for the tracker here so that
// the next test has a clean slate.
await new Promise(resolve => {
Services.clearData.deleteDataFromHost(
Services.io.newURI(TEST_3RD_PARTY_DOMAIN).host,
true,
Ci.nsIClearDataService.CLEAR_PERMISSIONS,
value => resolve()
);
});
},
[
["dom.storage_access.enabled", true],
[APS_PREF, false],
], // extra prefs
false, // no window open test
false, // no user-interaction test
Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, // expected blocking notifications
false, // run in normal window
null,
null,
null,
"storage-access ()" // Disable the storage-access feature
);

View File

@ -212,40 +212,3 @@ AntiTracking.runTest(
false, // no user-interaction test
0 // no blocking notifications
);
AntiTracking.runTest(
"Storage Access API called in a Permission Policy controlled iframe",
// blocking callback
async _ => {
let [threw, rejected] = await callRequestStorageAccess();
ok(!threw, "requestStorageAccess should not throw");
ok(rejected, "requestStorageAccess shouldn't be available");
},
null, // non-blocking callback
// cleanup function
async _ => {
// Only clear the user-interaction permissions for the tracker here so that
// the next test has a clean slate.
await new Promise(resolve => {
Services.clearData.deleteDataFromHost(
Services.io.newURI(TEST_3RD_PARTY_DOMAIN).host,
true,
Ci.nsIClearDataService.CLEAR_PERMISSIONS,
value => resolve()
);
});
},
[
["dom.storage_access.enabled", true],
[APS_PREF, true],
], // extra prefs
false, // no window open test
false, // no user-interaction test
Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, // expected blocking notifications
false, // run in normal window
null,
null,
null,
"storage-access ()" // Disable the storage-access feature
);