diff --git a/dom/localstorage/ActorsParent.cpp b/dom/localstorage/ActorsParent.cpp index d19c4caeb2b6..b99ecf625dbe 100644 --- a/dom/localstorage/ActorsParent.cpp +++ b/dom/localstorage/ActorsParent.cpp @@ -2492,6 +2492,9 @@ class ArchivedOriginScope { public: static ArchivedOriginScope* CreateFromOrigin(nsIPrincipal* aPrincipal); + static ArchivedOriginScope* CreateFromOrigin( + const nsACString& aOriginAttrSuffix, const nsACString& aOriginKey); + static ArchivedOriginScope* CreateFromPrefix(nsIPrincipal* aPrincipal); static ArchivedOriginScope* CreateFromPattern( @@ -5642,16 +5645,6 @@ nsresult PrepareDatastoreOp::Open() { if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - - rv = principal->GetPrivateBrowsingId(&mPrivateBrowsingId); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - mArchivedOriginScope = ArchivedOriginScope::CreateFromOrigin(principal); - if (NS_WARN_IF(!mArchivedOriginScope)) { - return NS_ERROR_FAILURE; - } } mState = State::Nesting; @@ -5673,6 +5666,27 @@ nsresult PrepareDatastoreOp::CheckExistingOperations() { return NS_ERROR_FAILURE; } + const PrincipalInfo& principalInfo = mParams.principalInfo(); + + nsCString originAttrSuffix; + uint32_t privateBrowsingId; + + if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) { + privateBrowsingId = 0; + } else { + MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo); + + const ContentPrincipalInfo& info = principalInfo.get_ContentPrincipalInfo(); + const OriginAttributes& attrs = info.attrs(); + attrs.CreateSuffix(originAttrSuffix); + + privateBrowsingId = attrs.mPrivateBrowsingId; + } + + mArchivedOriginScope = ArchivedOriginScope::CreateFromOrigin( + originAttrSuffix, mParams.originKey()); + MOZ_ASSERT(mArchivedOriginScope); + // Normally it's safe to access member variables without a mutex because even // though we hop between threads, the variables are never accessed by multiple // threads at the same time. @@ -5683,6 +5697,8 @@ nsresult PrepareDatastoreOp::CheckExistingOperations() { MOZ_ASSERT(!mOrigin.IsEmpty()); + mPrivateBrowsingId = privateBrowsingId; + mNestedState = NestedState::CheckClosingDatastore; // See if this PrepareDatastoreOp needs to wait. @@ -6858,6 +6874,13 @@ ArchivedOriginScope* ArchivedOriginScope::CreateFromOrigin( std::move(Origin(originAttrSuffix, originKey))); } +// static +ArchivedOriginScope* ArchivedOriginScope::CreateFromOrigin( + const nsACString& aOriginAttrSuffix, const nsACString& aOriginKey) { + return new ArchivedOriginScope( + std::move(Origin(aOriginAttrSuffix, aOriginKey))); +} + // static ArchivedOriginScope* ArchivedOriginScope::CreateFromPrefix( nsIPrincipal* aPrincipal) { diff --git a/dom/localstorage/LSObject.cpp b/dom/localstorage/LSObject.cpp index 1d47100c89ec..bf9291a66c00 100644 --- a/dom/localstorage/LSObject.cpp +++ b/dom/localstorage/LSObject.cpp @@ -220,10 +220,9 @@ nsresult LSObject::CreateForWindow(nsPIDOMWindowInner* aWindow, // localStorage is not available on some pages on purpose, for example // about:home. Match the old implementation by using GenerateOriginKey // for the check. - nsCString dummyOriginAttrSuffix; - nsCString dummyOriginKey; - nsresult rv = - GenerateOriginKey(principal, dummyOriginAttrSuffix, dummyOriginKey); + nsCString originAttrSuffix; + nsCString originKey; + nsresult rv = GenerateOriginKey(principal, originAttrSuffix, originKey); if (NS_FAILED(rv)) { return NS_ERROR_NOT_AVAILABLE; } @@ -236,12 +235,15 @@ nsresult LSObject::CreateForWindow(nsPIDOMWindowInner* aWindow, MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo); + nsCString suffix; nsCString origin; - rv = QuotaManager::GetInfoFromPrincipal(principal, nullptr, nullptr, &origin); + rv = QuotaManager::GetInfoFromPrincipal(principal, &suffix, nullptr, &origin); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } + MOZ_ASSERT(originAttrSuffix == suffix); + uint32_t privateBrowsingId; rv = principal->GetPrivateBrowsingId(&privateBrowsingId); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -260,6 +262,7 @@ nsresult LSObject::CreateForWindow(nsPIDOMWindowInner* aWindow, object->mPrincipalInfo = std::move(principalInfo); object->mPrivateBrowsingId = privateBrowsingId; object->mOrigin = origin; + object->mOriginKey = originKey; object->mDocumentURI = documentURI; object.forget(aStorage); @@ -275,10 +278,9 @@ nsresult LSObject::CreateForPrincipal(nsPIDOMWindowInner* aWindow, MOZ_ASSERT(aPrincipal); MOZ_ASSERT(aObject); - nsCString dummyOriginAttrSuffix; - nsCString dummyOriginKey; - nsresult rv = - GenerateOriginKey(aPrincipal, dummyOriginAttrSuffix, dummyOriginKey); + nsCString originAttrSuffix; + nsCString originKey; + nsresult rv = GenerateOriginKey(aPrincipal, originAttrSuffix, originKey); if (NS_FAILED(rv)) { return NS_ERROR_NOT_AVAILABLE; } @@ -292,22 +294,26 @@ nsresult LSObject::CreateForPrincipal(nsPIDOMWindowInner* aWindow, MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo || principalInfo->type() == PrincipalInfo::TSystemPrincipalInfo); + nsCString suffix; nsCString origin; if (principalInfo->type() == PrincipalInfo::TSystemPrincipalInfo) { - QuotaManager::GetInfoForChrome(nullptr, nullptr, &origin); + QuotaManager::GetInfoForChrome(&suffix, nullptr, &origin); } else { - rv = QuotaManager::GetInfoFromPrincipal(aPrincipal, nullptr, nullptr, + rv = QuotaManager::GetInfoFromPrincipal(aPrincipal, &suffix, nullptr, &origin); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } + MOZ_ASSERT(originAttrSuffix == suffix); + RefPtr object = new LSObject(aWindow, aPrincipal); object->mPrincipalInfo = std::move(principalInfo); object->mPrivateBrowsingId = aPrivate ? 1 : 0; object->mOrigin = origin; + object->mOriginKey = originKey; object->mDocumentURI = aDocumentURI; object.forget(aObject); @@ -734,6 +740,7 @@ nsresult LSObject::EnsureDatabase() { LSRequestPrepareDatastoreParams params; params.principalInfo() = *mPrincipalInfo; + params.originKey() = mOriginKey; params.createIfNotExists() = true; LSRequestResponse response; @@ -1012,20 +1019,22 @@ nsresult RequestHelper::StartAndReturnResponse(LSRequestResponse& aResponse) { return rv; } - MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { - if (!mWaiting) { - return true; - } + MOZ_ALWAYS_TRUE(SpinEventLoopUntil( + [&]() { + if (!mWaiting) { + return true; + } - { - StaticMutexAutoLock lock(gRequestHelperMutex); - if (NS_WARN_IF(gPendingSyncMessage)) { - return true; - } - } + { + StaticMutexAutoLock lock(gRequestHelperMutex); + if (NS_WARN_IF(gPendingSyncMessage)) { + return true; + } + } - return false; - }, thread)); + return false; + }, + thread)); } // If mWaiting is still set to true, it means that the event loop spinning diff --git a/dom/localstorage/LSObject.h b/dom/localstorage/LSObject.h index 55b622fb081a..3088ea573434 100644 --- a/dom/localstorage/LSObject.h +++ b/dom/localstorage/LSObject.h @@ -67,6 +67,7 @@ class LSObject final : public Storage { uint32_t mPrivateBrowsingId; nsCString mOrigin; + nsCString mOriginKey; nsString mDocumentURI; bool mInExplicitSnapshot; diff --git a/dom/localstorage/PBackgroundLSSharedTypes.ipdlh b/dom/localstorage/PBackgroundLSSharedTypes.ipdlh index 3ed292a15d51..8548cae24321 100644 --- a/dom/localstorage/PBackgroundLSSharedTypes.ipdlh +++ b/dom/localstorage/PBackgroundLSSharedTypes.ipdlh @@ -10,6 +10,7 @@ namespace dom { struct LSRequestPrepareDatastoreParams { PrincipalInfo principalInfo; + nsCString originKey; bool createIfNotExists; };