mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1623278 - Use SafeRefPtr for IDBFactory. r=dom-workers-and-storage-reviewers,asuth
Differential Revision: https://phabricator.services.mozilla.com/D66972 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
e614684d09
commit
da859a31b2
@ -4625,7 +4625,12 @@ Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
|
||||
IDBFactory* nsGlobalWindowInner::GetIndexedDB(ErrorResult& aError) {
|
||||
if (!mIndexedDB) {
|
||||
// This may keep mIndexedDB null without setting an error.
|
||||
aError = IDBFactory::CreateForWindow(this, getter_AddRefs(mIndexedDB));
|
||||
auto res = IDBFactory::CreateForWindow(this);
|
||||
if (res.isErr()) {
|
||||
aError = res.unwrapErr();
|
||||
} else {
|
||||
mIndexedDB = res.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
return mIndexedDB;
|
||||
|
@ -491,18 +491,18 @@ class MOZ_STACK_CLASS ResultHelper final : public IDBRequest::ResultCallback {
|
||||
|
||||
class PermissionRequestMainProcessHelper final : public PermissionRequestBase {
|
||||
BackgroundFactoryRequestChild* mActor;
|
||||
RefPtr<IDBFactory> mFactory;
|
||||
SafeRefPtr<IDBFactory> mFactory;
|
||||
|
||||
public:
|
||||
PermissionRequestMainProcessHelper(BackgroundFactoryRequestChild* aActor,
|
||||
IDBFactory* aFactory,
|
||||
SafeRefPtr<IDBFactory> aFactory,
|
||||
Element* aOwnerElement,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: PermissionRequestBase(aOwnerElement, aPrincipal),
|
||||
mActor(aActor),
|
||||
mFactory(aFactory) {
|
||||
mFactory(std::move(aFactory)) {
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(aFactory);
|
||||
MOZ_ASSERT(mFactory);
|
||||
aActor->AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
@ -857,16 +857,16 @@ class WorkerPermissionChallenge final : public Runnable {
|
||||
public:
|
||||
WorkerPermissionChallenge(WorkerPrivate* aWorkerPrivate,
|
||||
BackgroundFactoryRequestChild* aActor,
|
||||
IDBFactory* aFactory,
|
||||
SafeRefPtr<IDBFactory> aFactory,
|
||||
PrincipalInfo&& aPrincipalInfo)
|
||||
: Runnable("indexedDB::WorkerPermissionChallenge"),
|
||||
mWorkerPrivate(aWorkerPrivate),
|
||||
mActor(aActor),
|
||||
mFactory(aFactory),
|
||||
mFactory(std::move(aFactory)),
|
||||
mPrincipalInfo(std::move(aPrincipalInfo)) {
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(aFactory);
|
||||
MOZ_ASSERT(mFactory);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
@ -908,7 +908,7 @@ class WorkerPermissionChallenge final : public Runnable {
|
||||
|
||||
MaybeCollectGarbageOnIPCMessage();
|
||||
|
||||
const RefPtr<IDBFactory> factory = std::move(mFactory);
|
||||
const SafeRefPtr<IDBFactory> factory = std::move(mFactory);
|
||||
Unused << factory; // XXX see Bug 1605075
|
||||
|
||||
mActor->SendPermissionRetry();
|
||||
@ -976,7 +976,7 @@ class WorkerPermissionChallenge final : public Runnable {
|
||||
private:
|
||||
WorkerPrivate* const mWorkerPrivate;
|
||||
BackgroundFactoryRequestChild* mActor;
|
||||
RefPtr<IDBFactory> mFactory;
|
||||
SafeRefPtr<IDBFactory> mFactory;
|
||||
const PrincipalInfo mPrincipalInfo;
|
||||
};
|
||||
|
||||
@ -1442,11 +1442,10 @@ void BackgroundRequestChildBase::AssertIsOnOwningThread() const {
|
||||
* BackgroundFactoryChild
|
||||
******************************************************************************/
|
||||
|
||||
BackgroundFactoryChild::BackgroundFactoryChild(IDBFactory* aFactory)
|
||||
: mFactory(aFactory) {
|
||||
BackgroundFactoryChild::BackgroundFactoryChild(IDBFactory& aFactory)
|
||||
: mFactory(&aFactory) {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aFactory);
|
||||
aFactory->AssertIsOnOwningThread();
|
||||
mFactory->AssertIsOnOwningThread();
|
||||
|
||||
MOZ_COUNT_CTOR(indexedDB::BackgroundFactoryChild);
|
||||
}
|
||||
@ -1531,16 +1530,16 @@ BackgroundFactoryChild::RecvPBackgroundIDBDatabaseConstructor(
|
||||
******************************************************************************/
|
||||
|
||||
BackgroundFactoryRequestChild::BackgroundFactoryRequestChild(
|
||||
IDBFactory* aFactory, IDBOpenDBRequest* aOpenRequest, bool aIsDeleteOp,
|
||||
uint64_t aRequestedVersion)
|
||||
SafeRefPtr<IDBFactory> aFactory, IDBOpenDBRequest* aOpenRequest,
|
||||
bool aIsDeleteOp, uint64_t aRequestedVersion)
|
||||
: BackgroundRequestChildBase(aOpenRequest),
|
||||
mFactory(aFactory),
|
||||
mFactory(std::move(aFactory)),
|
||||
mDatabaseActor(nullptr),
|
||||
mRequestedVersion(aRequestedVersion),
|
||||
mIsDeleteOp(aIsDeleteOp) {
|
||||
// Can't assert owning thread here because IPDL has not yet set our manager!
|
||||
MOZ_ASSERT(aFactory);
|
||||
aFactory->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFactory);
|
||||
mFactory->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aOpenRequest);
|
||||
|
||||
MOZ_COUNT_CTOR(indexedDB::BackgroundFactoryRequestChild);
|
||||
@ -1702,7 +1701,7 @@ mozilla::ipc::IPCResult BackgroundFactoryRequestChild::RecvPermissionChallenge(
|
||||
workerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
RefPtr<WorkerPermissionChallenge> challenge = new WorkerPermissionChallenge(
|
||||
workerPrivate, this, mFactory, std::move(aPrincipalInfo));
|
||||
workerPrivate, this, mFactory.clonePtr(), std::move(aPrincipalInfo));
|
||||
if (!challenge->Dispatch()) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
@ -1733,8 +1732,8 @@ mozilla::ipc::IPCResult BackgroundFactoryRequestChild::RecvPermissionChallenge(
|
||||
}
|
||||
|
||||
RefPtr<PermissionRequestMainProcessHelper> helper =
|
||||
new PermissionRequestMainProcessHelper(this, mFactory, ownerElement,
|
||||
principal);
|
||||
new PermissionRequestMainProcessHelper(this, mFactory.clonePtr(),
|
||||
ownerElement, principal);
|
||||
|
||||
PermissionRequestBase::PermissionValue permission;
|
||||
if (NS_WARN_IF(NS_FAILED(helper->PromptIfNeeded(&permission)))) {
|
||||
@ -1854,12 +1853,15 @@ void BackgroundDatabaseChild::EnsureDOMObject() {
|
||||
auto request = mOpenRequestActor->GetOpenDBRequest();
|
||||
MOZ_ASSERT(request);
|
||||
|
||||
auto factory =
|
||||
auto& factory =
|
||||
static_cast<BackgroundFactoryChild*>(Manager())->GetDOMObject();
|
||||
MOZ_ASSERT(factory);
|
||||
|
||||
mTemporaryStrongDatabase =
|
||||
IDBDatabase::Create(request, factory, this, std::move(mSpec));
|
||||
// TODO: This AcquireStrongRefFromRawPtr looks suspicious. This should be
|
||||
// changed or at least well explained, see also comment on
|
||||
// BackgroundFactoryChild.
|
||||
mTemporaryStrongDatabase = IDBDatabase::Create(
|
||||
request, SafeRefPtr{&factory, AcquireStrongRefFromRawPtr{}}, this,
|
||||
std::move(mSpec));
|
||||
|
||||
MOZ_ASSERT(mTemporaryStrongDatabase);
|
||||
mTemporaryStrongDatabase->AssertIsOnOwningThread();
|
||||
|
@ -145,6 +145,10 @@ class BackgroundFactoryChild final : public PBackgroundIDBFactoryChild {
|
||||
friend class mozilla::ipc::BackgroundChildImpl;
|
||||
friend IDBFactory;
|
||||
|
||||
// TODO: This long-lived raw pointer is very suspicious, in particular as it
|
||||
// is used in BackgroundDatabaseChild::EnsureDOMObject to reacquire a strong
|
||||
// reference. What ensures it is kept alive, and why can't we store a strong
|
||||
// reference here?
|
||||
IDBFactory* mFactory;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
@ -154,16 +158,17 @@ class BackgroundFactoryChild final : public PBackgroundIDBFactoryChild {
|
||||
NS_ASSERT_OWNINGTHREAD(BackgroundFactoryChild);
|
||||
}
|
||||
|
||||
IDBFactory* GetDOMObject() const {
|
||||
IDBFactory& GetDOMObject() const {
|
||||
AssertIsOnOwningThread();
|
||||
return mFactory;
|
||||
MOZ_ASSERT(mFactory);
|
||||
return *mFactory;
|
||||
}
|
||||
|
||||
bool SendDeleteMe() = delete;
|
||||
|
||||
private:
|
||||
// Only created by IDBFactory.
|
||||
explicit BackgroundFactoryChild(IDBFactory* aFactory);
|
||||
explicit BackgroundFactoryChild(IDBFactory& aFactory);
|
||||
|
||||
// Only destroyed by mozilla::ipc::BackgroundChildImpl.
|
||||
~BackgroundFactoryChild();
|
||||
@ -222,7 +227,7 @@ class BackgroundFactoryRequestChild final
|
||||
friend class PermissionRequestChild;
|
||||
friend class PermissionRequestParent;
|
||||
|
||||
const RefPtr<IDBFactory> mFactory;
|
||||
const SafeRefPtr<IDBFactory> mFactory;
|
||||
|
||||
// Normally when opening of a database is successful, we receive a database
|
||||
// actor in request response, so we can use it to call ReleaseDOMObject()
|
||||
@ -245,7 +250,7 @@ class BackgroundFactoryRequestChild final
|
||||
|
||||
private:
|
||||
// Only created by IDBFactory.
|
||||
BackgroundFactoryRequestChild(IDBFactory* aFactory,
|
||||
BackgroundFactoryRequestChild(SafeRefPtr<IDBFactory> aFactory,
|
||||
IDBOpenDBRequest* aOpenRequest,
|
||||
bool aIsDeleteOp, uint64_t aRequestedVersion);
|
||||
|
||||
|
@ -146,11 +146,12 @@ class IDBDatabase::Observer final : public nsIObserver {
|
||||
NS_DECL_NSIOBSERVER
|
||||
};
|
||||
|
||||
IDBDatabase::IDBDatabase(IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
|
||||
IDBDatabase::IDBDatabase(IDBOpenDBRequest* aRequest,
|
||||
SafeRefPtr<IDBFactory> aFactory,
|
||||
BackgroundDatabaseChild* aActor,
|
||||
UniquePtr<DatabaseSpec> aSpec)
|
||||
: DOMEventTargetHelper(aRequest),
|
||||
mFactory(aFactory),
|
||||
mFactory(std::move(aFactory)),
|
||||
mSpec(std::move(aSpec)),
|
||||
mBackgroundActor(aActor),
|
||||
mFileHandleDisabled(aRequest->IsFileHandleDisabled()),
|
||||
@ -159,8 +160,8 @@ IDBDatabase::IDBDatabase(IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
|
||||
mQuotaExceeded(false),
|
||||
mIncreasedActiveDatabaseCount(false) {
|
||||
MOZ_ASSERT(aRequest);
|
||||
MOZ_ASSERT(aFactory);
|
||||
aFactory->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFactory);
|
||||
mFactory->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(mSpec);
|
||||
}
|
||||
@ -173,7 +174,7 @@ IDBDatabase::~IDBDatabase() {
|
||||
|
||||
// static
|
||||
RefPtr<IDBDatabase> IDBDatabase::Create(IDBOpenDBRequest* aRequest,
|
||||
IDBFactory* aFactory,
|
||||
SafeRefPtr<IDBFactory> aFactory,
|
||||
BackgroundDatabaseChild* aActor,
|
||||
UniquePtr<DatabaseSpec> aSpec) {
|
||||
MOZ_ASSERT(aRequest);
|
||||
@ -183,7 +184,7 @@ RefPtr<IDBDatabase> IDBDatabase::Create(IDBOpenDBRequest* aRequest,
|
||||
MOZ_ASSERT(aSpec);
|
||||
|
||||
RefPtr<IDBDatabase> db =
|
||||
new IDBDatabase(aRequest, aFactory, aActor, std::move(aSpec));
|
||||
new IDBDatabase(aRequest, aFactory.clonePtr(), aActor, std::move(aSpec));
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
@ -228,7 +229,7 @@ void IDBDatabase::AssertIsOnOwningThread() const {
|
||||
|
||||
nsIEventTarget* IDBDatabase::EventTarget() const {
|
||||
AssertIsOnOwningThread();
|
||||
return Factory()->EventTarget();
|
||||
return mFactory->EventTarget();
|
||||
}
|
||||
|
||||
void IDBDatabase::CloseInternal() {
|
||||
@ -1042,7 +1043,7 @@ void IDBDatabase::LastRelease() {
|
||||
|
||||
nsresult IDBDatabase::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
nsresult rv =
|
||||
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, mFactory);
|
||||
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, *mFactory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ class IDBDatabase final : public DOMEventTargetHelper {
|
||||
// The factory must be kept alive when IndexedDB is used in multiple
|
||||
// processes. If it dies then the entire actor tree will be destroyed with it
|
||||
// and the world will explode.
|
||||
RefPtr<IDBFactory> mFactory;
|
||||
SafeRefPtr<IDBFactory> mFactory;
|
||||
|
||||
UniquePtr<DatabaseSpec> mSpec;
|
||||
|
||||
@ -89,7 +89,7 @@ class IDBDatabase final : public DOMEventTargetHelper {
|
||||
|
||||
public:
|
||||
static MOZ_MUST_USE RefPtr<IDBDatabase> Create(
|
||||
IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
|
||||
IDBOpenDBRequest* aRequest, SafeRefPtr<IDBFactory> aFactory,
|
||||
indexedDB::BackgroundDatabaseChild* aActor,
|
||||
UniquePtr<DatabaseSpec> aSpec);
|
||||
|
||||
@ -147,12 +147,6 @@ class IDBDatabase final : public DOMEventTargetHelper {
|
||||
// DatabaseInfo.
|
||||
void RevertToPreviousState();
|
||||
|
||||
IDBFactory* Factory() const {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mFactory;
|
||||
}
|
||||
|
||||
void RegisterTransaction(IDBTransaction* aTransaction);
|
||||
|
||||
void UnregisterTransaction(IDBTransaction* aTransaction);
|
||||
@ -238,7 +232,7 @@ class IDBDatabase final : public DOMEventTargetHelper {
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
IDBDatabase(IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
|
||||
IDBDatabase(IDBOpenDBRequest* aRequest, SafeRefPtr<IDBFactory> aFactory,
|
||||
indexedDB::BackgroundDatabaseChild* aActor,
|
||||
UniquePtr<DatabaseSpec> aSpec);
|
||||
|
||||
|
@ -113,7 +113,7 @@ struct IDBFactory::PendingRequestInfo {
|
||||
}
|
||||
};
|
||||
|
||||
IDBFactory::IDBFactory()
|
||||
IDBFactory::IDBFactory(const IDBFactoryGuard&)
|
||||
: mBackgroundActor(nullptr),
|
||||
mInnerWindowID(0),
|
||||
mActiveTransactionCount(0),
|
||||
@ -133,26 +133,24 @@ IDBFactory::~IDBFactory() {
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
|
||||
IDBFactory** aFactory) {
|
||||
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForWindow(
|
||||
nsPIDOMWindowInner* aWindow) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aFactory);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = AllowedForWindowInternal(aWindow, &principal);
|
||||
|
||||
if (rv == NS_ERROR_DOM_NOT_SUPPORTED_ERR) {
|
||||
NS_WARNING("IndexedDB is not permitted in a third-party window.");
|
||||
*aFactory = nullptr;
|
||||
return NS_OK;
|
||||
return RefPtr<IDBFactory>{};
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (rv == NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
}
|
||||
return rv;
|
||||
return Err(rv);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(principal);
|
||||
@ -161,7 +159,7 @@ nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
|
||||
rv = PrincipalToPrincipalInfo(principal, principalInfo.get());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo ||
|
||||
@ -169,13 +167,13 @@ nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
|
||||
|
||||
if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
|
||||
|
||||
RefPtr<IDBFactory> factory = new IDBFactory();
|
||||
auto factory = MakeRefPtr<IDBFactory>(IDBFactoryGuard{});
|
||||
factory->mPrincipalInfo = std::move(principalInfo);
|
||||
|
||||
factory->mGlobal = do_QueryInterface(aWindow);
|
||||
@ -188,19 +186,18 @@ nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
|
||||
factory->mPrivateBrowsingMode =
|
||||
loadContext && loadContext->UsePrivateBrowsing();
|
||||
|
||||
factory.forget(aFactory);
|
||||
return NS_OK;
|
||||
return factory;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult IDBFactory::CreateForMainThreadJS(nsIGlobalObject* aGlobal,
|
||||
IDBFactory** aFactory) {
|
||||
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForMainThreadJS(
|
||||
nsIGlobalObject* aGlobal) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aGlobal);
|
||||
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aGlobal);
|
||||
if (NS_WARN_IF(!sop)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
auto principalInfo = MakeUnique<PrincipalInfo>();
|
||||
@ -208,52 +205,36 @@ nsresult IDBFactory::CreateForMainThreadJS(nsIGlobalObject* aGlobal,
|
||||
MOZ_ASSERT(principal);
|
||||
bool isSystem;
|
||||
if (!AllowedForPrincipal(principal, &isSystem)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = PrincipalToPrincipalInfo(principal, principalInfo.get());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return Err(rv);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
rv = CreateForMainThreadJSInternal(aGlobal, std::move(principalInfo),
|
||||
aFactory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!principalInfo);
|
||||
|
||||
return NS_OK;
|
||||
return CreateForMainThreadJSInternal(aGlobal, std::move(principalInfo));
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult IDBFactory::CreateForWorker(nsIGlobalObject* aGlobal,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
uint64_t aInnerWindowID,
|
||||
IDBFactory** aFactory) {
|
||||
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForWorker(
|
||||
nsIGlobalObject* aGlobal, const PrincipalInfo& aPrincipalInfo,
|
||||
uint64_t aInnerWindowID) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aGlobal);
|
||||
MOZ_ASSERT(aPrincipalInfo.type() != PrincipalInfo::T__None);
|
||||
|
||||
nsresult rv =
|
||||
CreateInternal(aGlobal, MakeUnique<PrincipalInfo>(aPrincipalInfo),
|
||||
aInnerWindowID, aFactory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return CreateInternal(aGlobal, MakeUnique<PrincipalInfo>(aPrincipalInfo),
|
||||
aInnerWindowID);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult IDBFactory::CreateForMainThreadJSInternal(
|
||||
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
|
||||
IDBFactory** aFactory) {
|
||||
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForMainThreadJSInternal(
|
||||
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aGlobal);
|
||||
MOZ_ASSERT(aPrincipalInfo);
|
||||
@ -261,44 +242,34 @@ nsresult IDBFactory::CreateForMainThreadJSInternal(
|
||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate();
|
||||
if (NS_WARN_IF(!mgr)) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = CreateInternal(aGlobal, std::move(aPrincipalInfo),
|
||||
/* aInnerWindowID */ 0, aFactory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return CreateInternal(aGlobal, std::move(aPrincipalInfo),
|
||||
/* aInnerWindowID */ 0);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult IDBFactory::CreateInternal(nsIGlobalObject* aGlobal,
|
||||
UniquePtr<PrincipalInfo> aPrincipalInfo,
|
||||
uint64_t aInnerWindowID,
|
||||
IDBFactory** aFactory) {
|
||||
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateInternal(
|
||||
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
|
||||
uint64_t aInnerWindowID) {
|
||||
MOZ_ASSERT(aGlobal);
|
||||
MOZ_ASSERT(aPrincipalInfo);
|
||||
MOZ_ASSERT(aPrincipalInfo->type() != PrincipalInfo::T__None);
|
||||
MOZ_ASSERT(aFactory);
|
||||
|
||||
if (aPrincipalInfo->type() != PrincipalInfo::TContentPrincipalInfo &&
|
||||
aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) {
|
||||
NS_WARNING("IndexedDB not allowed for this principal!");
|
||||
aPrincipalInfo = nullptr;
|
||||
*aFactory = nullptr;
|
||||
return NS_OK;
|
||||
return RefPtr<IDBFactory>{};
|
||||
}
|
||||
|
||||
RefPtr<IDBFactory> factory = new IDBFactory();
|
||||
auto factory = MakeRefPtr<IDBFactory>(IDBFactoryGuard{});
|
||||
factory->mPrincipalInfo = std::move(aPrincipalInfo);
|
||||
factory->mGlobal = aGlobal;
|
||||
factory->mEventTarget = GetCurrentThreadEventTarget();
|
||||
factory->mInnerWindowID = aInnerWindowID;
|
||||
|
||||
factory.forget(aFactory);
|
||||
return NS_OK;
|
||||
return factory;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -686,7 +657,7 @@ RefPtr<IDBOpenDBRequest> IDBFactory::OpenInternal(
|
||||
}
|
||||
|
||||
{
|
||||
BackgroundFactoryChild* actor = new BackgroundFactoryChild(this);
|
||||
BackgroundFactoryChild* actor = new BackgroundFactoryChild(*this);
|
||||
|
||||
// Set EventTarget for the top-level actor.
|
||||
// All child actors created later inherit the same event target.
|
||||
@ -715,8 +686,8 @@ RefPtr<IDBOpenDBRequest> IDBFactory::OpenInternal(
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<IDBOpenDBRequest> request =
|
||||
IDBOpenDBRequest::Create(aCx, this, mGlobal);
|
||||
RefPtr<IDBOpenDBRequest> request = IDBOpenDBRequest::Create(
|
||||
aCx, SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, mGlobal);
|
||||
if (!request) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
aRv.ThrowUncatchableException();
|
||||
@ -776,8 +747,9 @@ nsresult IDBFactory::InitiateRequest(IDBOpenDBRequest* aRequest,
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
auto actor = new BackgroundFactoryRequestChild(this, aRequest, deleting,
|
||||
requestedVersion);
|
||||
auto actor = new BackgroundFactoryRequestChild(
|
||||
SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aRequest, deleting,
|
||||
requestedVersion);
|
||||
|
||||
if (!mBackgroundActor->SendPBackgroundIDBFactoryRequestConstructor(actor,
|
||||
aParams)) {
|
||||
|
@ -56,6 +56,7 @@ class IDBFactory final : public nsISupports, public nsWrapperCache {
|
||||
|
||||
class BackgroundCreateCallback;
|
||||
struct PendingRequestInfo;
|
||||
struct IDBFactoryGuard {};
|
||||
|
||||
UniquePtr<PrincipalInfo> mPrincipalInfo;
|
||||
|
||||
@ -79,16 +80,17 @@ class IDBFactory final : public nsISupports, public nsWrapperCache {
|
||||
bool mPrivateBrowsingMode;
|
||||
|
||||
public:
|
||||
static nsresult CreateForWindow(nsPIDOMWindowInner* aWindow,
|
||||
IDBFactory** aFactory);
|
||||
explicit IDBFactory(const IDBFactoryGuard&);
|
||||
|
||||
static nsresult CreateForMainThreadJS(nsIGlobalObject* aGlobal,
|
||||
IDBFactory** aFactory);
|
||||
static Result<RefPtr<IDBFactory>, nsresult> CreateForWindow(
|
||||
nsPIDOMWindowInner* aWindow);
|
||||
|
||||
static nsresult CreateForWorker(nsIGlobalObject* aGlobal,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
uint64_t aInnerWindowID,
|
||||
IDBFactory** aFactory);
|
||||
static Result<RefPtr<IDBFactory>, nsresult> CreateForMainThreadJS(
|
||||
nsIGlobalObject* aGlobal);
|
||||
|
||||
static Result<RefPtr<IDBFactory>, nsresult> CreateForWorker(
|
||||
nsIGlobalObject* aGlobal, const PrincipalInfo& aPrincipalInfo,
|
||||
uint64_t aInnerWindowID);
|
||||
|
||||
static bool AllowedForWindow(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
@ -182,17 +184,14 @@ class IDBFactory final : public nsISupports, public nsWrapperCache {
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
IDBFactory();
|
||||
~IDBFactory();
|
||||
|
||||
static nsresult CreateForMainThreadJSInternal(
|
||||
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
|
||||
IDBFactory** aFactory);
|
||||
static Result<RefPtr<IDBFactory>, nsresult> CreateForMainThreadJSInternal(
|
||||
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo);
|
||||
|
||||
static nsresult CreateInternal(nsIGlobalObject* aGlobal,
|
||||
UniquePtr<PrincipalInfo> aPrincipalInfo,
|
||||
uint64_t aInnerWindowID,
|
||||
IDBFactory** aFactory);
|
||||
static Result<RefPtr<IDBFactory>, nsresult> CreateInternal(
|
||||
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
|
||||
uint64_t aInnerWindowID);
|
||||
|
||||
static nsresult AllowedForWindowInternal(nsPIDOMWindowInner* aWindow,
|
||||
nsCOMPtr<nsIPrincipal>* aPrincipal);
|
||||
|
@ -369,15 +369,15 @@ void IDBRequest::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
aVisitor.SetParentTarget(mTransaction, false);
|
||||
}
|
||||
|
||||
IDBOpenDBRequest::IDBOpenDBRequest(IDBFactory* aFactory,
|
||||
IDBOpenDBRequest::IDBOpenDBRequest(SafeRefPtr<IDBFactory> aFactory,
|
||||
nsIGlobalObject* aGlobal,
|
||||
bool aFileHandleDisabled)
|
||||
: IDBRequest(aGlobal),
|
||||
mFactory(aFactory),
|
||||
mFactory(std::move(aFactory)),
|
||||
mFileHandleDisabled(aFileHandleDisabled),
|
||||
mIncreasedActiveDatabaseCount(false) {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aFactory);
|
||||
MOZ_ASSERT(mFactory);
|
||||
MOZ_ASSERT(aGlobal);
|
||||
}
|
||||
|
||||
@ -387,9 +387,8 @@ IDBOpenDBRequest::~IDBOpenDBRequest() {
|
||||
}
|
||||
|
||||
// static
|
||||
RefPtr<IDBOpenDBRequest> IDBOpenDBRequest::Create(JSContext* aCx,
|
||||
IDBFactory* aFactory,
|
||||
nsIGlobalObject* aGlobal) {
|
||||
RefPtr<IDBOpenDBRequest> IDBOpenDBRequest::Create(
|
||||
JSContext* aCx, SafeRefPtr<IDBFactory> aFactory, nsIGlobalObject* aGlobal) {
|
||||
MOZ_ASSERT(aFactory);
|
||||
aFactory->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aGlobal);
|
||||
@ -397,7 +396,7 @@ RefPtr<IDBOpenDBRequest> IDBOpenDBRequest::Create(JSContext* aCx,
|
||||
bool fileHandleDisabled = !IndexedDatabaseManager::IsFileHandleEnabled();
|
||||
|
||||
RefPtr<IDBOpenDBRequest> request =
|
||||
new IDBOpenDBRequest(aFactory, aGlobal, fileHandleDisabled);
|
||||
new IDBOpenDBRequest(std::move(aFactory), aGlobal, fileHandleDisabled);
|
||||
CaptureCaller(aCx, request->mFilename, &request->mLineNo, &request->mColumn);
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
@ -500,7 +499,7 @@ NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||
|
||||
nsresult IDBOpenDBRequest::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
nsresult rv =
|
||||
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, mFactory);
|
||||
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, *mFactory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/dom/IDBRequestBinding.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "SafeRefPtr.h"
|
||||
|
||||
#define PRIVATE_IDBREQUEST_IID \
|
||||
{ \
|
||||
@ -181,7 +182,7 @@ class NS_NO_VTABLE IDBRequest::ResultCallback {
|
||||
|
||||
class IDBOpenDBRequest final : public IDBRequest {
|
||||
// Only touched on the owning thread.
|
||||
RefPtr<IDBFactory> mFactory;
|
||||
SafeRefPtr<IDBFactory> mFactory;
|
||||
|
||||
RefPtr<StrongWorkerRef> mWorkerRef;
|
||||
|
||||
@ -189,9 +190,9 @@ class IDBOpenDBRequest final : public IDBRequest {
|
||||
bool mIncreasedActiveDatabaseCount;
|
||||
|
||||
public:
|
||||
static MOZ_MUST_USE RefPtr<IDBOpenDBRequest> Create(JSContext* aCx,
|
||||
IDBFactory* aFactory,
|
||||
nsIGlobalObject* aGlobal);
|
||||
static MOZ_MUST_USE RefPtr<IDBOpenDBRequest> Create(
|
||||
JSContext* aCx, SafeRefPtr<IDBFactory> aFactory,
|
||||
nsIGlobalObject* aGlobal);
|
||||
|
||||
bool IsFileHandleDisabled() const { return mFileHandleDisabled; }
|
||||
|
||||
@ -204,8 +205,6 @@ class IDBOpenDBRequest final : public IDBRequest {
|
||||
// EventTarget
|
||||
virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
|
||||
|
||||
IDBFactory* Factory() const { return mFactory; }
|
||||
|
||||
IMPL_EVENT_HANDLER(blocked);
|
||||
IMPL_EVENT_HANDLER(upgradeneeded);
|
||||
|
||||
@ -217,7 +216,7 @@ class IDBOpenDBRequest final : public IDBRequest {
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
IDBOpenDBRequest(IDBFactory* aFactory, nsIGlobalObject* aGlobal,
|
||||
IDBOpenDBRequest(SafeRefPtr<IDBFactory> aFactory, nsIGlobalObject* aGlobal,
|
||||
bool aFileHandleDisabled);
|
||||
|
||||
~IDBOpenDBRequest();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "SafeRefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -380,9 +380,8 @@ void IndexedDatabaseManager::Destroy() {
|
||||
|
||||
// static
|
||||
nsresult IndexedDatabaseManager::CommonPostHandleEvent(
|
||||
EventChainPostVisitor& aVisitor, IDBFactory* aFactory) {
|
||||
EventChainPostVisitor& aVisitor, const IDBFactory& aFactory) {
|
||||
MOZ_ASSERT(aVisitor.mDOMEvent);
|
||||
MOZ_ASSERT(aFactory);
|
||||
|
||||
if (!gPrefErrorEventToSelfError) {
|
||||
return NS_OK;
|
||||
@ -475,8 +474,8 @@ nsresult IndexedDatabaseManager::CommonPostHandleEvent(
|
||||
|
||||
// Log the error to the error console.
|
||||
ScriptErrorHelper::Dump(errorName, init.mFilename, init.mLineno, init.mColno,
|
||||
nsIScriptError::errorFlag, aFactory->IsChrome(),
|
||||
aFactory->InnerWindowID());
|
||||
nsIScriptError::errorFlag, aFactory.IsChrome(),
|
||||
aFactory.InnerWindowID());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -525,12 +524,13 @@ bool IndexedDatabaseManager::DefineIndexedDB(JSContext* aCx,
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<IDBFactory> factory;
|
||||
if (NS_FAILED(
|
||||
IDBFactory::CreateForMainThreadJS(global, getter_AddRefs(factory)))) {
|
||||
auto res = IDBFactory::CreateForMainThreadJS(global);
|
||||
if (res.isErr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto factory = res.unwrap();
|
||||
|
||||
MOZ_ASSERT(factory, "This should never fail for chrome!");
|
||||
|
||||
JS::Rooted<JS::Value> indexedDB(aCx);
|
||||
|
@ -133,7 +133,7 @@ class IndexedDatabaseManager final {
|
||||
static const nsCString& GetLocale();
|
||||
|
||||
static nsresult CommonPostHandleEvent(EventChainPostVisitor& aVisitor,
|
||||
IDBFactory* aFactory);
|
||||
const IDBFactory& aFactory);
|
||||
|
||||
static bool ResolveSandboxBinding(JSContext* aCx);
|
||||
|
||||
|
@ -480,14 +480,14 @@ already_AddRefed<IDBFactory> WorkerGlobalScope::GetIndexedDB(
|
||||
const PrincipalInfo& principalInfo =
|
||||
mWorkerPrivate->GetEffectiveStoragePrincipalInfo();
|
||||
|
||||
nsresult rv = IDBFactory::CreateForWorker(this, principalInfo,
|
||||
mWorkerPrivate->WindowID(),
|
||||
getter_AddRefs(indexedDB));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aErrorResult = rv;
|
||||
auto res = IDBFactory::CreateForWorker(this, principalInfo,
|
||||
mWorkerPrivate->WindowID());
|
||||
if (NS_WARN_IF(res.isErr())) {
|
||||
aErrorResult = res.unwrapErr();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
indexedDB = res.unwrap();
|
||||
mIndexedDB = indexedDB;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user