Bug 1149280 part 1. Make nullprincipal creation faster. r=smaug

This commit is contained in:
Boris Zbarsky 2015-03-31 13:11:00 -04:00
Родитель c35c1ecc2e
Коммит ab624ae20e
8 изменённых файлов: 91 добавлений и 80 удалений

Просмотреть файл

@ -15,8 +15,6 @@
#include "nsNullPrincipal.h"
#include "nsNullPrincipalURI.h"
#include "nsMemory.h"
#include "nsIUUIDGenerator.h"
#include "nsID.h"
#include "nsNetUtil.h"
#include "nsIClassInfoImpl.h"
#include "nsIObjectInputStream.h"
@ -78,7 +76,15 @@ nsNullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
return NS_SUCCEEDED(rv) ? nullPrin.forget() : nullptr;
}
#define NS_NULLPRINCIPAL_PREFIX NS_NULLPRINCIPAL_SCHEME ":"
/* static */ already_AddRefed<nsNullPrincipal>
nsNullPrincipal::Create(uint32_t aAppId, bool aInMozBrowser)
{
nsRefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
nsresult rv = nullPrin->Init(aAppId, aInMozBrowser);
NS_ENSURE_SUCCESS(rv, nullptr);
return nullPrin.forget();
}
nsresult
nsNullPrincipal::Init(uint32_t aAppId, bool aInMozBrowser)
@ -87,11 +93,8 @@ nsNullPrincipal::Init(uint32_t aAppId, bool aInMozBrowser)
mAppId = aAppId;
mInMozBrowser = aInMozBrowser;
nsCString str;
nsresult rv = GenerateNullPrincipalURI(str);
NS_ENSURE_SUCCESS(rv, rv);
mURI = new nsNullPrincipalURI(str);
mURI = nsNullPrincipalURI::Create();
NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
return NS_OK;
}
@ -102,40 +105,6 @@ nsNullPrincipal::GetScriptLocation(nsACString &aStr)
mURI->GetSpec(aStr);
}
nsresult
nsNullPrincipal::GenerateNullPrincipalURI(nsACString &aStr)
{
// FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsID id;
rv = uuidgen->GenerateUUIDInPlace(&id);
NS_ENSURE_SUCCESS(rv, rv);
char chars[NSID_LENGTH];
id.ToProvidedString(chars);
uint32_t suffixLen = NSID_LENGTH - 1;
uint32_t prefixLen = ArrayLength(NS_NULLPRINCIPAL_PREFIX) - 1;
// Use an nsCString so we only do the allocation once here and then share
// with nsJSPrincipals
aStr.SetCapacity(prefixLen + suffixLen);
aStr.Append(NS_NULLPRINCIPAL_PREFIX);
aStr.Append(chars);
if (aStr.Length() != prefixLen + suffixLen) {
NS_WARNING("Out of memory allocating null-principal URI");
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
#ifdef DEBUG
void nsNullPrincipal::dumpImpl()
{

Просмотреть файл

@ -30,6 +30,9 @@ class nsIURI;
class nsNullPrincipal final : public nsJSPrincipals
{
public:
// This should only be used by deserialization, and the factory constructor.
// Other consumers should use the Create and CreateWithInheritedAttributes
// methods.
nsNullPrincipal();
// Our refcount is managed by nsJSPrincipals. Use this macro to avoid an
@ -42,15 +45,19 @@ public:
NS_DECL_NSIPRINCIPAL
NS_DECL_NSISERIALIZABLE
// Returns null on failure.
static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIPrincipal *aInheritFrom);
// Returns null on failure.
static already_AddRefed<nsNullPrincipal>
Create(uint32_t aAppId = nsIScriptSecurityManager::NO_APP_ID,
bool aInMozBrowser = false);
nsresult Init(uint32_t aAppId = nsIScriptSecurityManager::NO_APP_ID,
bool aInMozBrowser = false);
virtual void GetScriptLocation(nsACString &aStr) override;
static nsresult GenerateNullPrincipalURI(nsACString &aStr);
#ifdef DEBUG
virtual void dumpImpl() override;
#endif

Просмотреть файл

@ -14,29 +14,53 @@
#include "nsNetUtil.h"
#include "nsEscape.h"
#include "nsCRT.h"
#include "nsIUUIDGenerator.h"
////////////////////////////////////////////////////////////////////////////////
//// nsNullPrincipalURI
nsNullPrincipalURI::nsNullPrincipalURI(const nsCString &aSpec)
nsNullPrincipalURI::nsNullPrincipalURI()
: mScheme(NS_NULLPRINCIPAL_SCHEME),
mPath(mPathBytes, ArrayLength(mPathBytes), ArrayLength(mPathBytes) - 1)
{
InitializeFromSpec(aSpec);
}
void
nsNullPrincipalURI::InitializeFromSpec(const nsCString &aSpec)
nsNullPrincipalURI::nsNullPrincipalURI(const nsNullPrincipalURI& aOther)
: mScheme(NS_NULLPRINCIPAL_SCHEME),
mPath(mPathBytes, ArrayLength(mPathBytes), ArrayLength(mPathBytes) - 1)
{
int32_t dividerPosition = aSpec.FindChar(':');
NS_ASSERTION(dividerPosition != -1, "Malformed URI!");
mPath.Assign(aOther.mPath);
}
mozilla::DebugOnly<int32_t> n = aSpec.Left(mScheme, dividerPosition);
NS_ASSERTION(n == dividerPosition, "Storing the scheme failed!");
nsresult
nsNullPrincipalURI::Init()
{
// FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
nsCOMPtr<nsIUUIDGenerator> uuidgen = services::GetUUIDGenerator();
NS_ENSURE_TRUE(uuidgen, NS_ERROR_NOT_AVAILABLE);
int32_t count = aSpec.Length() - dividerPosition - 1;
n = aSpec.Mid(mPath, dividerPosition + 1, count);
NS_ASSERTION(n == count, "Storing the path failed!");
nsID id;
nsresult rv = uuidgen->GenerateUUIDInPlace(&id);
NS_ENSURE_SUCCESS(rv, rv);
ToLowerCase(mScheme);
MOZ_ASSERT(mPathBytes == mPath.BeginWriting());
id.ToProvidedString(mPathBytes);
MOZ_ASSERT(mPath.Length() == NSID_LENGTH - 1);
MOZ_ASSERT(strlen(mPath.get()) == NSID_LENGTH - 1);
return NS_OK;
}
/* static */
already_AddRefed<nsNullPrincipalURI>
nsNullPrincipalURI::Create()
{
nsRefPtr<nsNullPrincipalURI> uri = new nsNullPrincipalURI();
nsresult rv = uri->Init();
NS_ENSURE_SUCCESS(rv, nullptr);
return uri.forget();
}
static NS_DEFINE_CID(kNullPrincipalURIImplementationCID,
@ -230,8 +254,7 @@ nsNullPrincipalURI::SetUserPass(const nsACString &aUserPass)
NS_IMETHODIMP
nsNullPrincipalURI::Clone(nsIURI **_newURI)
{
nsCOMPtr<nsIURI> uri =
new nsNullPrincipalURI(mScheme + NS_LITERAL_CSTRING(":") + mPath);
nsCOMPtr<nsIURI> uri = new nsNullPrincipalURI(*this);
uri.forget(_newURI);
return NS_OK;
}
@ -298,11 +321,9 @@ nsNullPrincipalURI::Deserialize(const mozilla::ipc::URIParams &aParams)
return false;
}
nsCString str;
nsresult rv = nsNullPrincipal::GenerateNullPrincipalURI(str);
nsresult rv = Init();
NS_ENSURE_SUCCESS(rv, false);
InitializeFromSpec(str);
return true;
}

Просмотреть файл

@ -18,6 +18,8 @@
#include "mozilla/Attributes.h"
#include "nsIIPCSerializableURI.h"
#include "mozilla/MemoryReporting.h"
#include "nsNullPrincipal.h"
#include "nsID.h"
// {51fcd543-3b52-41f7-b91b-6b54102236e6}
#define NS_NULLPRINCIPALURI_IMPLEMENTATION_CID \
@ -37,18 +39,23 @@ public:
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
explicit nsNullPrincipalURI(const nsCString &aSpec);
// NB: This constructor exists only for deserialization. Everyone
// else should call Create.
nsNullPrincipalURI();
// NB: This constructor exists only for deserialization.
nsNullPrincipalURI() { }
// Returns null on failure.
static already_AddRefed<nsNullPrincipalURI> Create();
private:
nsNullPrincipalURI(const nsNullPrincipalURI& aOther);
~nsNullPrincipalURI() {}
void InitializeFromSpec(const nsCString &aSpec);
nsresult Init();
char mPathBytes[NSID_LENGTH];
nsCString mScheme;
nsCString mPath;
nsFixedCString mPath;
};
#endif // __nsNullPrincipalURI_h__

Просмотреть файл

@ -993,7 +993,8 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId,
nsCOMPtr<nsIPrincipal> principal;
uriPrinc->GetPrincipal(getter_AddRefs(principal));
if (!principal) {
return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, result);
principal = nsNullPrincipal::Create();
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
}
principal.forget(result);
@ -1088,15 +1089,16 @@ nsScriptSecurityManager::GetCodebasePrincipalInternal(nsIURI *aURI,
NS_URIChainHasFlags(aURI,
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
&inheritsPrincipal);
if (NS_FAILED(rv) || inheritsPrincipal) {
return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, result);
}
nsCOMPtr<nsIPrincipal> principal;
rv = CreateCodebasePrincipal(aURI, aAppId, aInMozBrowser,
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*result = principal);
if (NS_FAILED(rv) || inheritsPrincipal) {
principal = nsNullPrincipal::Create();
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
} else {
rv = CreateCodebasePrincipal(aURI, aAppId, aInMozBrowser,
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
}
principal.forget(result);
return NS_OK;
}

Просмотреть файл

@ -459,7 +459,12 @@ nsContentUtils::Init()
sSecurityManager->GetSystemPrincipal(&sSystemPrincipal);
MOZ_ASSERT(sSystemPrincipal);
NS_ADDREF(sNullSubjectPrincipal = new nsNullPrincipal());
// We use the constructor here because we want infallible initialization; we
// apparently don't care whether sNullSubjectPrincipal has a sane URI or not.
nsRefPtr<nsNullPrincipal> nullPrincipal = new nsNullPrincipal();
nullPrincipal->Init();
nullPrincipal.forget(&sNullSubjectPrincipal);
nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
if (NS_FAILED(rv)) {

Просмотреть файл

@ -868,16 +868,14 @@ xpc::CreateSandboxObject(JSContext* cx, MutableHandleValue vp, nsISupports* prin
SandboxOptions& options)
{
// Create the sandbox global object
nsresult rv;
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(prinOrSop);
if (!principal) {
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(prinOrSop);
if (sop) {
principal = sop->GetPrincipal();
} else {
nsRefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
rv = nullPrin->Init();
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsNullPrincipal> nullPrin = nsNullPrincipal::Create();
NS_ENSURE_TRUE(nullPrin, NS_ERROR_FAILURE);
principal = nullPrin;
}
}

Просмотреть файл

@ -31,6 +31,8 @@ MOZ_SERVICE(ServiceWorkerManager, nsIServiceWorkerManager,
"@mozilla.org/serviceworkers/manager;1");
MOZ_SERVICE(AsyncShutdown, nsIAsyncShutdownService,
"@mozilla.org/async-shutdown-service;1")
MOZ_SERVICE(UUIDGenerator, nsIUUIDGenerator,
"@mozilla.org/uuid-generator;1");
#ifdef MOZ_USE_NAMESPACE
namespace mozilla {