diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 9f0f645756e8..2bc6244073c0 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3097,6 +3097,48 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext, return NS_FAILED(rv) ? false : NS_CP_ACCEPTED(decision); } +// static +mozilla::PrincipalOriginAttributes +nsContentUtils::GetOriginAttributes(nsIDocument* aDocument) +{ + if (!aDocument) { + return mozilla::PrincipalOriginAttributes(); + } + + nsCOMPtr loadGroup = aDocument->GetDocumentLoadGroup(); + if (loadGroup) { + return GetOriginAttributes(loadGroup); + } + + mozilla::PrincipalOriginAttributes attrs; + mozilla::NeckoOriginAttributes nattrs; + nsCOMPtr channel = aDocument->GetChannel(); + if (channel && NS_GetOriginAttributes(channel, nattrs)) { + attrs.InheritFromNecko(nattrs); + } + return attrs; +} + +// static +mozilla::PrincipalOriginAttributes +nsContentUtils::GetOriginAttributes(nsILoadGroup* aLoadGroup) +{ + if (!aLoadGroup) { + return mozilla::PrincipalOriginAttributes(); + } + mozilla::PrincipalOriginAttributes attrs; + mozilla::DocShellOriginAttributes dsattrs; + nsCOMPtr callbacks; + aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks)); + if (callbacks) { + nsCOMPtr loadContext = do_GetInterface(callbacks); + if (loadContext && loadContext->GetOriginAttributes(dsattrs)) { + attrs.InheritFromDocShellToDoc(dsattrs, nullptr); + } + } + return attrs; +} + // static bool nsContentUtils::IsInPrivateBrowsing(nsIDocument* aDoc) diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index fab20f4e9d0a..2f7c32f7ec7e 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -785,6 +785,18 @@ public: bool aIsForWindow, uint32_t *aArgCount, const char*** aArgNames); + /** + * Returns origin attributes of the document. + **/ + static mozilla::PrincipalOriginAttributes + GetOriginAttributes(nsIDocument* aDoc); + + /** + * Returns origin attributes of the load group. + **/ + static mozilla::PrincipalOriginAttributes + GetOriginAttributes(nsILoadGroup* aLoadGroup); + /** * Returns true if this document is in a Private Browsing window. */ diff --git a/dom/cache/CacheStorage.cpp b/dom/cache/CacheStorage.cpp index 069520bb6c2a..0104240c1fc1 100644 --- a/dom/cache/CacheStorage.cpp +++ b/dom/cache/CacheStorage.cpp @@ -196,7 +196,7 @@ CacheStorage::CreateOnWorker(Namespace aNamespace, nsIGlobalObject* aGlobal, return ref.forget(); } - if (aWorkerPrivate->IsInPrivateBrowsing()) { + if (aWorkerPrivate->GetOriginAttributes().mPrivateBrowsingId > 0) { NS_WARNING("CacheStorage not supported during private browsing."); RefPtr ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR); return ref.forget(); diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 3f52ff40be40..cd7c0d18d7c1 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -245,29 +245,24 @@ GetWorkerPref(const nsACString& aPref, return result; } -// This function creates a key for a SharedWorker composed by "name|scriptSpec". -// If the name contains a '|', this will be replaced by '||'. +// This fn creates a key for a SharedWorker that contains the name, script +// spec, and the serialized origin attributes: +// "name|scriptSpec^key1=val1&key2=val2&key3=val3" void -GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName, - bool aPrivateBrowsing, nsCString& aKey) +GenerateSharedWorkerKey(const nsACString& aScriptSpec, + const nsACString& aName, + const PrincipalOriginAttributes& aAttrs, + nsCString& aKey) { + nsAutoCString suffix; + aAttrs.CreateSuffix(suffix); + aKey.Truncate(); - aKey.SetCapacity(aScriptSpec.Length() + aName.Length() + 3); - aKey.Append(aPrivateBrowsing ? "1|" : "0|"); - - nsACString::const_iterator start, end; - aName.BeginReading(start); - aName.EndReading(end); - for (; start != end; ++start) { - if (*start == '|') { - aKey.AppendASCII("||"); - } else { - aKey.Append(*start); - } - } - + aKey.SetCapacity(aName.Length() + aScriptSpec.Length() + suffix.Length() + 2); + aKey.Append(aName); aKey.Append('|'); aKey.Append(aScriptSpec); + aKey.Append(suffix); } void @@ -1641,7 +1636,7 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate) const nsCString& sharedWorkerName = aWorkerPrivate->WorkerName(); nsAutoCString key; GenerateSharedWorkerKey(sharedWorkerScriptSpec, sharedWorkerName, - aWorkerPrivate->IsInPrivateBrowsing(), key); + aWorkerPrivate->GetOriginAttributes(), key); MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(key)); SharedWorkerInfo* sharedWorkerInfo = @@ -1718,7 +1713,7 @@ RuntimeService::RemoveSharedWorker(WorkerDomainInfo* aDomainInfo, #ifdef DEBUG nsAutoCString key; GenerateSharedWorkerKey(data->mScriptSpec, data->mName, - aWorkerPrivate->IsInPrivateBrowsing(), key); + aWorkerPrivate->GetOriginAttributes(), key); MOZ_ASSERT(iter.Key() == key); #endif iter.Remove(); @@ -2434,9 +2429,10 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx, nsresult rv = aLoadInfo->mResolvedScriptURI->GetSpec(scriptSpec); NS_ENSURE_SUCCESS(rv, rv); + MOZ_ASSERT(aLoadInfo->mPrincipal); nsAutoCString key; GenerateSharedWorkerKey(scriptSpec, aName, - aLoadInfo->mPrivateBrowsing, key); + BasePrincipal::Cast(aLoadInfo->mPrincipal)->OriginAttributesRef(), key); if (mDomainMap.Get(aLoadInfo->mDomain, &domainInfo) && domainInfo->mSharedWorkerInfos.Get(key, &sharedWorkerInfo)) { diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index b40e5e4a0142..83ecb3720cf8 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -350,7 +350,7 @@ public: explicit CacheCreator(WorkerPrivate* aWorkerPrivate) : mCacheName(aWorkerPrivate->ServiceWorkerCacheName()) - , mPrivateBrowsing(aWorkerPrivate->IsInPrivateBrowsing()) + , mOriginAttributes(aWorkerPrivate->GetOriginAttributes()) { MOZ_ASSERT(aWorkerPrivate->IsServiceWorker()); MOZ_ASSERT(aWorkerPrivate->LoadScriptAsPartOfLoadingServiceWorkerScript()); @@ -411,7 +411,7 @@ private: nsTArray> mLoaders; nsString mCacheName; - bool mPrivateBrowsing; + PrincipalOriginAttributes mOriginAttributes; }; NS_IMPL_ISUPPORTS0(CacheCreator) @@ -1467,7 +1467,7 @@ CacheCreator::CreateCacheStorage(nsIPrincipal* aPrincipal) // If we're in private browsing mode, don't even try to create the // CacheStorage. Instead, just fail immediately to terminate the // ServiceWorker load. - if (NS_WARN_IF(mPrivateBrowsing)) { + if (NS_WARN_IF(mOriginAttributes.mPrivateBrowsingId > 0)) { return NS_ERROR_DOM_SECURITY_ERR; } @@ -1478,7 +1478,8 @@ CacheCreator::CreateCacheStorage(nsIPrincipal* aPrincipal) mCacheStorage = CacheStorage::CreateOnMainThread(mozilla::dom::cache::CHROME_ONLY_NAMESPACE, mSandboxGlobalObject, - aPrincipal, mPrivateBrowsing, + aPrincipal, + false, /* privateBrowsing can't be true here */ true /* force trusted origin */, error); if (NS_WARN_IF(error.Failed())) { diff --git a/dom/workers/ServiceWorkerInfo.cpp b/dom/workers/ServiceWorkerInfo.cpp index 4c5d8e1fbba7..49780d422056 100644 --- a/dom/workers/ServiceWorkerInfo.cpp +++ b/dom/workers/ServiceWorkerInfo.cpp @@ -160,6 +160,8 @@ ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal, , mSkipWaitingFlag(false) { MOZ_ASSERT(mPrincipal); + // cache origin attributes so we can use them off main thread + mOriginAttributes = BasePrincipal::Cast(mPrincipal)->OriginAttributesRef(); MOZ_ASSERT(!mScope.IsEmpty()); MOZ_ASSERT(!mScriptSpec.IsEmpty()); MOZ_ASSERT(!mCacheName.IsEmpty()); diff --git a/dom/workers/ServiceWorkerInfo.h b/dom/workers/ServiceWorkerInfo.h index 4529de159213..80910bdad1b9 100644 --- a/dom/workers/ServiceWorkerInfo.h +++ b/dom/workers/ServiceWorkerInfo.h @@ -31,6 +31,7 @@ private: const nsCString mScriptSpec; const nsString mCacheName; ServiceWorkerState mState; + PrincipalOriginAttributes mOriginAttributes; // This id is shared with WorkerPrivate to match requests issued by service // workers to their corresponding serviceWorkerInfo. @@ -104,6 +105,12 @@ public: return mState; } + const PrincipalOriginAttributes& + GetOriginAttributes() const + { + return mOriginAttributes; + } + const nsString& CacheName() const { diff --git a/dom/workers/ServiceWorkerPrivate.cpp b/dom/workers/ServiceWorkerPrivate.cpp index d24bc11a35b9..15d9d09d8903 100644 --- a/dom/workers/ServiceWorkerPrivate.cpp +++ b/dom/workers/ServiceWorkerPrivate.cpp @@ -1714,7 +1714,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy, nsContentUtils::StorageAccess access = nsContentUtils::StorageAllowedForPrincipal(info.mPrincipal); info.mStorageAllowed = access > nsContentUtils::StorageAccess::ePrivateBrowsing; - info.mPrivateBrowsing = false; + info.mOriginAttributes = mInfo->GetOriginAttributes(); nsCOMPtr csp; rv = info.mPrincipal->GetCsp(getter_AddRefs(csp)); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 0a5e438f5b2b..d8b0336d4a60 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -1739,7 +1739,6 @@ WorkerLoadInfo::WorkerLoadInfo() , mXHRParamsAllowed(false) , mPrincipalIsSystem(false) , mStorageAllowed(false) - , mPrivateBrowsing(true) , mServiceWorkersTestingInWindow(false) { MOZ_COUNT_CTOR(WorkerLoadInfo); @@ -1797,8 +1796,8 @@ WorkerLoadInfo::StealFrom(WorkerLoadInfo& aOther) mXHRParamsAllowed = aOther.mXHRParamsAllowed; mPrincipalIsSystem = aOther.mPrincipalIsSystem; mStorageAllowed = aOther.mStorageAllowed; - mPrivateBrowsing = aOther.mPrivateBrowsing; mServiceWorkersTestingInWindow = aOther.mServiceWorkersTestingInWindow; + mOriginAttributes = aOther.mOriginAttributes; } template @@ -3426,7 +3425,7 @@ WorkerPrivateParent::SetPrincipal(nsIPrincipal* aPrincipal, mLoadInfo.mLoadGroup = aLoadGroup; mLoadInfo.mPrincipalInfo = new PrincipalInfo(); - mLoadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(aLoadGroup); + mLoadInfo.mOriginAttributes = nsContentUtils::GetOriginAttributes(aLoadGroup); MOZ_ALWAYS_SUCCEEDS( PrincipalToPrincipalInfo(aPrincipal, mLoadInfo.mPrincipalInfo)); @@ -4193,7 +4192,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mFromWindow = aParent->IsFromWindow(); loadInfo.mWindowID = aParent->WindowID(); loadInfo.mStorageAllowed = aParent->IsStorageAllowed(); - loadInfo.mPrivateBrowsing = aParent->IsInPrivateBrowsing(); + loadInfo.mOriginAttributes = aParent->GetOriginAttributes(); loadInfo.mServiceWorkersTestingInWindow = aParent->ServiceWorkersTestingInWindow(); } else { @@ -4317,7 +4316,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, nsContentUtils::StorageAccess access = nsContentUtils::StorageAllowedForWindow(globalWindow); loadInfo.mStorageAllowed = access > nsContentUtils::StorageAccess::eDeny; - loadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(document); + loadInfo.mOriginAttributes = nsContentUtils::GetOriginAttributes(document); } else { // Not a window MOZ_ASSERT(isChrome); @@ -4359,7 +4358,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mFromWindow = false; loadInfo.mWindowID = UINT64_MAX; loadInfo.mStorageAllowed = true; - loadInfo.mPrivateBrowsing = false; + loadInfo.mOriginAttributes = PrincipalOriginAttributes(); } MOZ_ASSERT(loadInfo.mPrincipal); diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 4a7c66b65ca1..bc02913c4895 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -783,10 +783,10 @@ public: return mLoadInfo.mStorageAllowed; } - bool - IsInPrivateBrowsing() const + const PrincipalOriginAttributes& + GetOriginAttributes() const { - return mLoadInfo.mPrivateBrowsing; + return mLoadInfo.mOriginAttributes; } // Determine if the SW testing per-window flag is set by devtools diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index c391160df5ab..dd3b2bac3a03 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -269,8 +269,8 @@ struct WorkerLoadInfo bool mXHRParamsAllowed; bool mPrincipalIsSystem; bool mStorageAllowed; - bool mPrivateBrowsing; bool mServiceWorkersTestingInWindow; + PrincipalOriginAttributes mOriginAttributes; WorkerLoadInfo(); ~WorkerLoadInfo();