зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1228139 - Remove nsIURIWithPrincipal - part 3 - main part, r=bz
nsIURIWithPrincipal is currently used to retrieve the nsIPrincipal from a BlobURL object. BlobURLProtocolHandler has a hashtable containing, for each blobURL, a BlobImpl and its nsIPrincipal. This patch introduces BlobURLProtocolHandler::GetBlobURLPrincipal() that retrieves the nsIPrincipal from this hashtable. This patch fixes also a bug in how the revocation of blobURLs is broadcasted to other processes. This should be done immediately because each process creates its own timer to revoke them after 5 seconds. An important change is related to NS_SecurityCompareURIs() where, if 1 (or both) of the 2 URIs to compare, is a revoked BlobURL, we will QI its URL to nsIStandardURL and fail out at that point.
This commit is contained in:
Родитель
8c37ca27d9
Коммит
f6768a8ff6
|
@ -14,12 +14,12 @@
|
|||
|
||||
#include "ExpandedPrincipal.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include "mozilla/ContentPrincipal.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/CSPDictionariesBinding.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
@ -411,15 +411,12 @@ BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI,
|
|||
}
|
||||
|
||||
// Check whether the URI knows what its principal is supposed to be.
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
||||
if (uriPrinc) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
if (!principal) {
|
||||
return NullPrincipal::Create(aAttrs);
|
||||
}
|
||||
RefPtr<BasePrincipal> concrete = Cast(principal);
|
||||
return concrete.forget();
|
||||
nsCOMPtr<nsIPrincipal> blobPrincipal;
|
||||
if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
|
||||
getter_AddRefs(blobPrincipal))) {
|
||||
MOZ_ASSERT(blobPrincipal);
|
||||
RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
|
||||
return principal.forget();
|
||||
}
|
||||
|
||||
// Mint a codebase principal.
|
||||
|
@ -439,7 +436,7 @@ BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
|
|||
"CreateCodebasePrincipal does not support NullPrincipal");
|
||||
|
||||
nsAutoCString originNoSuffix;
|
||||
mozilla::OriginAttributes attrs;
|
||||
OriginAttributes attrs;
|
||||
if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "ContentPrincipal.h"
|
||||
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nscore.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsString.h"
|
||||
|
@ -15,7 +16,6 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIStandardURL.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
|
@ -27,11 +27,11 @@
|
|||
#include "nsNetCID.h"
|
||||
#include "js/Wrapper.h"
|
||||
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/dom/nsCSPContext.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/ExtensionPolicyService.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
|
@ -165,20 +165,11 @@ ContentPrincipal::GenerateOriginNoSuffixFromURI(nsIURI* aURI,
|
|||
|
||||
// This URL can be a blobURL. In this case, we should use the 'parent'
|
||||
// principal instead.
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriWithPrincipal = do_QueryInterface(origin);
|
||||
if (uriWithPrincipal) {
|
||||
nsCOMPtr<nsIPrincipal> uriPrincipal;
|
||||
rv = uriWithPrincipal->GetPrincipal(getter_AddRefs(uriPrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If there is not a principal for this blobURL, it means that the blobURL
|
||||
// has been revoked. Let's use a nullPrincipal instead.
|
||||
if (!uriPrincipal) {
|
||||
uriPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
||||
MOZ_ASSERT(uriPrincipal);
|
||||
}
|
||||
|
||||
return uriPrincipal->GetOriginNoSuffix(aOriginNoSuffix);
|
||||
nsCOMPtr<nsIPrincipal> blobPrincipal;
|
||||
if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(origin,
|
||||
getter_AddRefs(blobPrincipal))) {
|
||||
MOZ_ASSERT(blobPrincipal);
|
||||
return blobPrincipal->GetOriginNoSuffix(aOriginNoSuffix);
|
||||
}
|
||||
|
||||
// If we reached this branch, we can only create an origin if we have a
|
||||
|
@ -277,18 +268,13 @@ ContentPrincipal::GetURI(nsIURI** aURI)
|
|||
bool
|
||||
ContentPrincipal::MayLoadInternal(nsIURI* aURI)
|
||||
{
|
||||
// See if aURI is something like a Blob URI that is actually associated with
|
||||
// a principal.
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriWithPrin = do_QueryInterface(aURI);
|
||||
if (uriWithPrin) {
|
||||
nsCOMPtr<nsIPrincipal> uriPrin;
|
||||
nsresult rv = uriWithPrin->GetPrincipal(getter_AddRefs(uriPrin));
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || !uriPrin) {
|
||||
// BlobURL has been revoked.
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
return nsIPrincipal::Subsumes(uriPrin);
|
||||
nsCOMPtr<nsIPrincipal> blobPrincipal;
|
||||
if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
|
||||
getter_AddRefs(blobPrincipal))) {
|
||||
MOZ_ASSERT(blobPrincipal);
|
||||
return nsIPrincipal::Subsumes(blobPrincipal);
|
||||
}
|
||||
|
||||
// If this principal is associated with an addon, check whether that addon
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "NullPrincipal.h"
|
||||
#include "NullPrincipalURI.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsError.h"
|
||||
|
@ -185,14 +184,10 @@ bool
|
|||
NullPrincipal::MayLoadInternal(nsIURI* aURI)
|
||||
{
|
||||
// Also allow the load if we are the principal of the URI being checked.
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
||||
if (uriPrinc) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
|
||||
if (principal == this) {
|
||||
return true;
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> blobPrincipal;
|
||||
if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
|
||||
getter_AddRefs(blobPrincipal))) {
|
||||
return blobPrincipal == this;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
#include "mozilla/OriginAttributes.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/dom/URLSearchParams.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsURLHelper.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -86,18 +86,15 @@ OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
|||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (scheme.EqualsLiteral("about")) {
|
||||
mFirstPartyDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
|
||||
} else if (scheme.EqualsLiteral("blob")) {
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
||||
if (uriPrinc) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
// a revoked blobURL doesn't expose a principal.
|
||||
if (principal) {
|
||||
mFirstPartyDomain = principal->OriginAttributesRef().mFirstPartyDomain;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> blobPrincipal;
|
||||
if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
|
||||
getter_AddRefs(blobPrincipal))) {
|
||||
MOZ_ASSERT(blobPrincipal);
|
||||
mFirstPartyDomain = blobPrincipal->OriginAttributesRef().mFirstPartyDomain;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ NS_IMPL_ADDREF_INHERITED(BlobURL, mozilla::net::nsSimpleURI)
|
|||
NS_IMPL_RELEASE_INHERITED(BlobURL, mozilla::net::nsSimpleURI)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(BlobURL)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal)
|
||||
if (aIID.Equals(kHOSTOBJECTURICID))
|
||||
foundInterface = static_cast<nsIURI*>(this);
|
||||
else if (aIID.Equals(kThisSimpleURIImplementationCID)) {
|
||||
|
@ -36,30 +35,9 @@ NS_INTERFACE_MAP_BEGIN(BlobURL)
|
|||
else
|
||||
NS_INTERFACE_MAP_END_INHERITING(mozilla::net::nsSimpleURI)
|
||||
|
||||
// nsIURIWithPrincipal methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
BlobURL::GetPrincipal(nsIPrincipal** aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIPrincipal> principal = mPrincipal.get();
|
||||
principal.forget(aPrincipal);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BlobURL::GetPrincipalUri(nsIURI** aUri)
|
||||
{
|
||||
if (mPrincipal) {
|
||||
mPrincipal->GetURI(aUri);
|
||||
}
|
||||
else {
|
||||
*aUri = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
BlobURL::BlobURL()
|
||||
: mRevoked(false)
|
||||
{}
|
||||
|
||||
// nsISerializable methods:
|
||||
|
||||
|
@ -76,13 +54,10 @@ BlobURL::ReadPrivate(nsIObjectInputStream *aStream)
|
|||
nsresult rv = mozilla::net::nsSimpleURI::ReadPrivate(aStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
|
||||
rv = aStream->ReadBoolean(&mRevoked);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(supports, &rv);
|
||||
mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", principal, false);
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -91,10 +66,10 @@ BlobURL::Write(nsIObjectOutputStream* aStream)
|
|||
nsresult rv = mozilla::net::nsSimpleURI::Write(aStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = mPrincipal.get();
|
||||
return NS_WriteOptionalCompoundObject(aStream, principal,
|
||||
NS_GET_IID(nsIPrincipal),
|
||||
true);
|
||||
rv = aStream->WriteBoolean(mRevoked);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIIPCSerializableURI methods:
|
||||
|
@ -109,18 +84,7 @@ BlobURL::Serialize(mozilla::ipc::URIParams& aParams)
|
|||
mozilla::net::nsSimpleURI::Serialize(simpleParams);
|
||||
hostParams.simpleParams() = simpleParams;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = mPrincipal.get();
|
||||
if (principal) {
|
||||
PrincipalInfo info;
|
||||
nsresult rv = PrincipalToPrincipalInfo(principal, &info);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
hostParams.principal() = info;
|
||||
} else {
|
||||
hostParams.principal() = mozilla::void_t();
|
||||
}
|
||||
hostParams.revoked() = mRevoked;
|
||||
|
||||
aParams = hostParams;
|
||||
}
|
||||
|
@ -141,16 +105,7 @@ BlobURL::Deserialize(const mozilla::ipc::URIParams& aParams)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (hostParams.principal().type() == OptionalPrincipalInfo::Tvoid_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(hostParams.principal().get_PrincipalInfo());
|
||||
if (!principal) {
|
||||
return false;
|
||||
}
|
||||
mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", principal, false);
|
||||
|
||||
mRevoked = hostParams.revoked();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -158,8 +113,7 @@ nsresult
|
|||
BlobURL::SetScheme(const nsACString& aScheme)
|
||||
{
|
||||
// Disallow setting the scheme, since that could cause us to be associated
|
||||
// with a different protocol handler that doesn't expect us to be carrying
|
||||
// around a principal with nsIURIWithPrincipal.
|
||||
// with a different protocol handler.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -181,8 +135,7 @@ BlobURL::CloneInternal(mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMo
|
|||
#endif
|
||||
|
||||
BlobURL* u = static_cast<BlobURL*>(simpleClone.get());
|
||||
|
||||
u->mPrincipal = mPrincipal;
|
||||
u->mRevoked = mRevoked;
|
||||
|
||||
simpleClone.forget(aClone);
|
||||
return NS_OK;
|
||||
|
@ -209,15 +162,7 @@ BlobURL::EqualsInternal(nsIURI* aOther,
|
|||
*aResult = mozilla::net::nsSimpleURI::EqualsInternal(otherUri,
|
||||
aRefHandlingMode);
|
||||
|
||||
#ifdef DEBUG
|
||||
// mPrincipal can be null if the blobURL has been revoked.
|
||||
if (*aResult && mPrincipal && otherUri->mPrincipal) {
|
||||
bool equal = false;
|
||||
nsresult rv = mPrincipal->Equals(otherUri->mPrincipal, &equal);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv) && equal);
|
||||
}
|
||||
#endif
|
||||
|
||||
// We don't want to compare the revoked flag.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -225,7 +170,6 @@ BlobURL::EqualsInternal(nsIURI* aOther,
|
|||
NS_IMPL_NSIURIMUTATOR_ISUPPORTS(BlobURL::Mutator,
|
||||
nsIURISetters,
|
||||
nsIURIMutator,
|
||||
nsIPrincipalURIMutator,
|
||||
nsISerializable)
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -8,42 +8,25 @@
|
|||
#define mozilla_dom_BlobURL_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsSimpleURI.h"
|
||||
#include "nsIIPCSerializableURI.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "prtime.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* These URIs refer to host objects with "blob" scheme. The underlying object is
|
||||
* a BlobImpl.
|
||||
* These URIs refer to host objects with "blob" scheme.
|
||||
*/
|
||||
class BlobURL final
|
||||
: public mozilla::net::nsSimpleURI
|
||||
, public nsIURIWithPrincipal
|
||||
class BlobURL final : public mozilla::net::nsSimpleURI
|
||||
{
|
||||
private:
|
||||
explicit BlobURL(nsIPrincipal* aPrincipal)
|
||||
: mozilla::net::nsSimpleURI()
|
||||
{
|
||||
mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", aPrincipal, false);
|
||||
}
|
||||
|
||||
// For use only from deserialization
|
||||
explicit BlobURL()
|
||||
: mozilla::net::nsSimpleURI()
|
||||
{}
|
||||
BlobURL();
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIURIWITHPRINCIPAL
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_NSIIPCSERIALIZABLEURI
|
||||
|
@ -65,9 +48,13 @@ public:
|
|||
return url;
|
||||
}
|
||||
|
||||
NS_IMETHOD Mutate(nsIURIMutator * *_retval) override;
|
||||
bool
|
||||
Revoked() const
|
||||
{
|
||||
return mRevoked;
|
||||
}
|
||||
|
||||
nsMainThreadPtrHandle<nsIPrincipal> mPrincipal;
|
||||
NS_IMETHOD Mutate(nsIURIMutator * *_retval) override;
|
||||
|
||||
private:
|
||||
virtual ~BlobURL() = default;
|
||||
|
@ -80,7 +67,6 @@ public:
|
|||
class Mutator final
|
||||
: public nsIURIMutator
|
||||
, public BaseURIMutator<BlobURL>
|
||||
, public nsIPrincipalURIMutator
|
||||
, public nsISerializable
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -90,24 +76,13 @@ public:
|
|||
NS_IMETHOD
|
||||
Write(nsIObjectOutputStream *aOutputStream) override
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE NS_IMETHOD
|
||||
Read(nsIObjectInputStream* aStream) override
|
||||
{
|
||||
return InitFromInputStream(aStream);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE NS_IMETHOD
|
||||
SetPrincipal(nsIPrincipal *aPrincipal) override
|
||||
{
|
||||
if (!mURI) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mURI->mPrincipal = new nsMainThreadPtrHolder<nsIPrincipal>("nsIPrincipal", aPrincipal, false);
|
||||
return NS_OK;
|
||||
return InitFromInputStream(aStream);
|
||||
}
|
||||
|
||||
Mutator() = default;
|
||||
|
@ -119,6 +94,8 @@ public:
|
|||
};
|
||||
|
||||
friend BaseURIMutator<BlobURL>;
|
||||
|
||||
bool mRevoked;
|
||||
};
|
||||
|
||||
#define NS_HOSTOBJECTURI_CID \
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BlobURLChannel.h"
|
||||
#include "mozilla/dom/BlobImpl.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "BlobURLProtocolHandler.h"
|
||||
#include "BlobURLChannel.h"
|
||||
|
||||
#include "mozilla/dom/BlobURL.h"
|
||||
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
@ -18,6 +18,7 @@
|
|||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "nsClassHashtable.h"
|
||||
|
@ -52,14 +53,18 @@ struct DataInfo
|
|||
, mBlobImpl(aBlobImpl)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mRevoked(false)
|
||||
{}
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
}
|
||||
|
||||
DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
|
||||
: mObjectType(eMediaSource)
|
||||
, mMediaSource(aMediaSource)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mRevoked(false)
|
||||
{}
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
}
|
||||
|
||||
ObjectType mObjectType;
|
||||
|
||||
|
@ -136,6 +141,7 @@ BroadcastBlobURLRegistration(const nsACString& aURI,
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
dom::ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
|
||||
|
@ -406,12 +412,11 @@ public:
|
|||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
static void
|
||||
Create(const nsACString& aURI, bool aBroadcastToOtherProcesses)
|
||||
Create(const nsACString& aURI)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<ReleasingTimerHolder> holder =
|
||||
new ReleasingTimerHolder(aURI, aBroadcastToOtherProcesses);
|
||||
RefPtr<ReleasingTimerHolder> holder = new ReleasingTimerHolder(aURI);
|
||||
|
||||
auto raii = MakeScopeExit([holder] {
|
||||
holder->CancelTimerAndRevokeURI();
|
||||
|
@ -420,7 +425,7 @@ public:
|
|||
nsresult rv =
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other)->Dispatch(holder.forget());
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
|
||||
raii.release();
|
||||
}
|
||||
|
||||
|
@ -456,7 +461,7 @@ public:
|
|||
NS_IMETHOD
|
||||
Notify(nsITimer* aTimer) override
|
||||
{
|
||||
RevokeURI(mBroadcastToOtherProcesses);
|
||||
RevokeURI();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -488,17 +493,16 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ReleasingTimerHolder(const nsACString& aURI, bool aBroadcastToOtherProcesses)
|
||||
explicit ReleasingTimerHolder(const nsACString& aURI)
|
||||
: Runnable("ReleasingTimerHolder")
|
||||
, mURI(aURI)
|
||||
, mBroadcastToOtherProcesses(aBroadcastToOtherProcesses)
|
||||
{}
|
||||
|
||||
~ReleasingTimerHolder()
|
||||
{}
|
||||
|
||||
void
|
||||
RevokeURI(bool aBroadcastToOtherProcesses)
|
||||
RevokeURI()
|
||||
{
|
||||
// Remove the shutting down blocker
|
||||
nsCOMPtr<nsIAsyncShutdownClient> phase = GetShutdownPhase();
|
||||
|
@ -506,11 +510,6 @@ private:
|
|||
phase->RemoveBlocker(this);
|
||||
}
|
||||
|
||||
// If we have to broadcast the unregistration, let's do it now.
|
||||
if (aBroadcastToOtherProcesses) {
|
||||
BroadcastBlobURLUnregistration(mURI);
|
||||
}
|
||||
|
||||
DataInfo* info = GetDataInfo(mURI, true /* We care about revoked dataInfo */);
|
||||
if (!info) {
|
||||
// Already gone!
|
||||
|
@ -534,7 +533,7 @@ private:
|
|||
mTimer = nullptr;
|
||||
}
|
||||
|
||||
RevokeURI(false /* aBroadcastToOtherProcesses */);
|
||||
RevokeURI();
|
||||
}
|
||||
|
||||
static nsCOMPtr<nsIAsyncShutdownClient>
|
||||
|
@ -551,8 +550,6 @@ private:
|
|||
}
|
||||
|
||||
nsCString mURI;
|
||||
bool mBroadcastToOtherProcesses;
|
||||
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
};
|
||||
|
||||
|
@ -598,6 +595,9 @@ BlobURLProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
|
|||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri)
|
||||
{
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
Init();
|
||||
|
||||
nsresult rv = GenerateURIString(aPrincipal, aUri);
|
||||
|
@ -615,6 +615,9 @@ BlobURLProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
|
|||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri)
|
||||
{
|
||||
MOZ_ASSERT(aMediaSource);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
Init();
|
||||
|
||||
nsresult rv = GenerateURIString(aPrincipal, aUri);
|
||||
|
@ -631,6 +634,9 @@ BlobURLProtocolHandler::AddDataEntry(const nsACString& aURI,
|
|||
nsIPrincipal* aPrincipal,
|
||||
BlobImpl* aBlobImpl)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
|
||||
return AddDataEntryInternal(aURI, aBlobImpl, aPrincipal);
|
||||
}
|
||||
|
||||
|
@ -683,12 +689,14 @@ BlobURLProtocolHandler::RemoveDataEntry(const nsACString& aUri,
|
|||
|
||||
info->mRevoked = true;
|
||||
|
||||
if (aBroadcastToOtherProcesses && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
BroadcastBlobURLUnregistration(nsCString(aUri));
|
||||
}
|
||||
|
||||
// The timer will take care of removing the entry for real after
|
||||
// RELEASING_TIMER milliseconds. In the meantime, the DataInfo, marked as
|
||||
// revoked, will not be exposed.
|
||||
ReleasingTimerHolder::Create(aUri,
|
||||
aBroadcastToOtherProcesses &&
|
||||
info->mObjectType == DataInfo::eBlobImpl);
|
||||
ReleasingTimerHolder::Create(aUri);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
@ -817,27 +825,28 @@ BlobURLProtocolHandler::NewURI(const nsACString& aSpec,
|
|||
nsIURI **aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
nsresult rv;
|
||||
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
RefPtr<BlobImpl> blob;
|
||||
if (info && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
MOZ_ASSERT(info->mBlobImpl);
|
||||
principal = info->mPrincipal;
|
||||
blob = info->mBlobImpl;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_MutateURI(new BlobURL::Mutator())
|
||||
.SetSpec(aSpec)
|
||||
.Apply(NS_MutatorMethod(&nsIPrincipalURIMutator::SetPrincipal, principal))
|
||||
.Finalize(uri);
|
||||
nsresult rv = NS_MutateURI(new BlobURL::Mutator())
|
||||
.SetSpec(aSpec)
|
||||
.Finalize(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uri.forget(aResult);
|
||||
bool revoked = true;
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
if (info && info->mObjectType == DataInfo::eBlobImpl) {
|
||||
revoked = info->mRevoked;
|
||||
}
|
||||
|
||||
RefPtr<BlobURL> blobURL;
|
||||
rv = uri->QueryInterface(kHOSTOBJECTURICID,
|
||||
getter_AddRefs(blobURL));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
MOZ_ASSERT(blobURL);
|
||||
blobURL->mRevoked = revoked;
|
||||
|
||||
uri.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -853,27 +862,22 @@ BlobURLProtocolHandler::NewChannel2(nsIURI* aURI,
|
|||
channel.forget(aResult);
|
||||
});
|
||||
|
||||
RefPtr<BlobURL> blobURL;
|
||||
nsresult rv = aURI->QueryInterface(kHOSTOBJECTURICID,
|
||||
getter_AddRefs(blobURL));
|
||||
if (NS_FAILED(rv) || !blobURL) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DataInfo* info = GetDataInfoFromURI(aURI, true /*aAlsoIfRevoked */);
|
||||
if (!info || info->mObjectType != DataInfo::eBlobImpl || !info->mBlobImpl) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = info->mBlobImpl;
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
||||
if (!uriPrinc) {
|
||||
if (blobURL->Revoked()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
|
||||
if (!principal) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(info->mPrincipal == principal);
|
||||
|
||||
// We want to be sure that we stop the creation of the channel if the blob URL
|
||||
// is copy-and-pasted on a different context (ex. private browsing or
|
||||
// containers).
|
||||
|
@ -886,13 +890,13 @@ BlobURLProtocolHandler::NewChannel2(nsIURI* aURI,
|
|||
if (aLoadInfo &&
|
||||
!nsContentUtils::IsSystemPrincipal(aLoadInfo->LoadingPrincipal()) &&
|
||||
!ChromeUtils::IsOriginAttributesEqualIgnoringFPD(aLoadInfo->GetOriginAttributes(),
|
||||
BasePrincipal::Cast(principal)->OriginAttributesRef())) {
|
||||
BasePrincipal::Cast(info->mPrincipal)->OriginAttributesRef())) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
raii.release();
|
||||
|
||||
channel->Initialize(blobImpl);
|
||||
channel->Initialize(info->mBlobImpl);
|
||||
channel.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -919,6 +923,38 @@ BlobURLProtocolHandler::GetScheme(nsACString &result)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
BlobURLProtocolHandler::GetBlobURLPrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(aURI);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
RefPtr<BlobURL> blobURL;
|
||||
nsresult rv = aURI->QueryInterface(kHOSTOBJECTURICID,
|
||||
getter_AddRefs(blobURL));
|
||||
if (NS_FAILED(rv) || !blobURL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DataInfo* info = GetDataInfoFromURI(aURI, true /*aAlsoIfRevoked */);
|
||||
if (!info || info->mObjectType != DataInfo::eBlobImpl || !info->mBlobImpl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
|
||||
if (blobURL->Revoked()) {
|
||||
principal =
|
||||
NullPrincipal::Create(BasePrincipal::Cast(info->mPrincipal)->OriginAttributesRef());
|
||||
} else {
|
||||
principal = info->mPrincipal;
|
||||
}
|
||||
|
||||
principal.forget(aPrincipal);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
|
|
|
@ -53,6 +53,9 @@ public:
|
|||
nsIPrincipal* aPrincipal,
|
||||
mozilla::dom::BlobImpl* aBlobImpl);
|
||||
|
||||
// This method revokes a blobURL. Because some operations could still be in
|
||||
// progress, the revoking consists in marking the blobURL as revoked and in
|
||||
// removing it after RELEASING_TIMER milliseconds.
|
||||
static void RemoveDataEntry(const nsACString& aUri,
|
||||
bool aBroadcastToOTherProcesses = true);
|
||||
|
||||
|
@ -67,6 +70,22 @@ public:
|
|||
GetAllBlobURLEntries(nsTArray<mozilla::dom::BlobURLRegistrationData>& aRegistrations,
|
||||
mozilla::dom::ContentParent* aCP);
|
||||
|
||||
// This method returns false if aURI is not a known BlobURL. Otherwise it
|
||||
// returns true.
|
||||
//
|
||||
// When true is returned, the aPrincipal out param is meaningful. It gets
|
||||
// set to the principal that a channel loaded from the blob would get if
|
||||
// the blob is not already revoked and to a NullPrincipal if the blob is
|
||||
// revoked.
|
||||
//
|
||||
// This means that for a revoked blob URL this method may either return
|
||||
// false or return true and hand out a NullPrincipal in aPrincipal,
|
||||
// depending on whether the "remove it from the hashtable" timer has
|
||||
// fired. See RemoveDataEntry().
|
||||
static bool
|
||||
GetBlobURLPrincipal(nsIURI* aURI,
|
||||
nsIPrincipal** aPrincipal);
|
||||
|
||||
private:
|
||||
~BlobURLProtocolHandler();
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ struct NullPrincipalURIParams
|
|||
struct HostObjectURIParams
|
||||
{
|
||||
SimpleURIParams simpleParams;
|
||||
OptionalPrincipalInfo principal;
|
||||
bool revoked;
|
||||
};
|
||||
|
||||
union URIParams
|
||||
|
|
|
@ -126,7 +126,6 @@ XPIDL_SOURCES += [
|
|||
'nsIURI.idl',
|
||||
'nsIURIClassifier.idl',
|
||||
'nsIURIMutator.idl',
|
||||
'nsIURIWithPrincipal.idl',
|
||||
'nsIURL.idl',
|
||||
'nsIURLParser.idl',
|
||||
'nsPILoadGroupInternal.idl',
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/* 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 "nsISupports.idl"
|
||||
|
||||
interface nsIPrincipal;
|
||||
interface nsIURI;
|
||||
interface nsIURIMutator;
|
||||
|
||||
/**
|
||||
* nsIURIWithPrincipal is implemented by URIs which are associated with a
|
||||
* specific principal.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(626a5c0c-bfd8-4531-8b47-a8451b0daa33)]
|
||||
interface nsIURIWithPrincipal : nsISupports
|
||||
{
|
||||
/**
|
||||
* The principal associated with the resource returned when loading this
|
||||
* uri.
|
||||
*/
|
||||
readonly attribute nsIPrincipal principal;
|
||||
|
||||
/**
|
||||
* The uri for the principal.
|
||||
*/
|
||||
readonly attribute nsIURI principalUri;
|
||||
};
|
||||
|
||||
[builtinclass, uuid(fa138a89-c76e-4b7f-95ec-c7b56ded5ef5)]
|
||||
interface nsIPrincipalURIMutator : nsISupports
|
||||
{
|
||||
/**
|
||||
* Associates a principal to the mutated URI.
|
||||
* Would normally return nsIURIMutator, but since it only gets called
|
||||
* from C++, there is no need for that.
|
||||
*/
|
||||
[must_use, noscript] void setPrincipal(in nsIPrincipal aPrincipal);
|
||||
};
|
|
@ -61,7 +61,6 @@
|
|||
#include "nsStringStream.h"
|
||||
#include "nsISyncStreamListener.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsIURLParser.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsIViewSourceChannel.h"
|
||||
|
@ -69,6 +68,7 @@
|
|||
#include "plstr.h"
|
||||
#include "nsINestedURI.h"
|
||||
#include "mozilla/dom/nsCSPUtils.h"
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/net/HttpBaseChannel.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsISiteSecurityService.h"
|
||||
|
@ -84,6 +84,7 @@
|
|||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
using mozilla::dom::BlobURLProtocolHandler;
|
||||
using mozilla::dom::ClientInfo;
|
||||
using mozilla::dom::PerformanceStorage;
|
||||
using mozilla::dom::ServiceWorkerDescriptor;
|
||||
|
@ -2481,15 +2482,24 @@ NS_SecurityCompareURIs(nsIURI *aSourceURI,
|
|||
nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
|
||||
nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
|
||||
|
||||
// If either uri is an nsIURIWithPrincipal
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(sourceBaseURI);
|
||||
if (uriPrinc) {
|
||||
uriPrinc->GetPrincipalUri(getter_AddRefs(sourceBaseURI));
|
||||
nsCOMPtr<nsIPrincipal> sourceBlobPrincipal;
|
||||
if (BlobURLProtocolHandler::GetBlobURLPrincipal(sourceBaseURI,
|
||||
getter_AddRefs(sourceBlobPrincipal))) {
|
||||
nsCOMPtr<nsIURI> sourceBlobOwnerURI;
|
||||
nsresult rv = sourceBlobPrincipal->GetURI(getter_AddRefs(sourceBlobOwnerURI));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
sourceBaseURI = sourceBlobOwnerURI;
|
||||
}
|
||||
}
|
||||
|
||||
uriPrinc = do_QueryInterface(targetBaseURI);
|
||||
if (uriPrinc) {
|
||||
uriPrinc->GetPrincipalUri(getter_AddRefs(targetBaseURI));
|
||||
nsCOMPtr<nsIPrincipal> targetBlobPrincipal;
|
||||
if (BlobURLProtocolHandler::GetBlobURLPrincipal(targetBaseURI,
|
||||
getter_AddRefs(targetBlobPrincipal))) {
|
||||
nsCOMPtr<nsIURI> targetBlobOwnerURI;
|
||||
nsresult rv = targetBlobPrincipal->GetURI(getter_AddRefs(targetBlobOwnerURI));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
targetBaseURI = targetBlobOwnerURI;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sourceBaseURI || !targetBaseURI)
|
||||
|
|
Загрузка…
Ссылка в новой задаче