mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
69790bc62e
The inclusions were removed with the following very crude script and the resulting breakage was fixed up by hand. The manual fixups did either revert the changes done by the script, replace a generic header with a more specific one or replace a header with a forward declaration. find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2) if [ -n "$interfaces" ]; then if [[ "$interfaces" == *$'\n'* ]]; then regexp="\(" for i in $interfaces; do regexp="$regexp$i\|"; done regexp="${regexp%%\\\|}\)" else regexp="$interfaces" fi interface=$(basename "$path") rg -l "#include.*${interface%%.idl}.h" . | while read path2; do hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" ) if [ $hits -eq 0 ]; then echo "Removing ${interface} from ${path2}" grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp mv -f "$path2".tmp "$path2" fi done fi done Differential Revision: https://phabricator.services.mozilla.com/D55443 --HG-- extra : moz-landing-system : lando
392 lines
12 KiB
C++
392 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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 "xpcpublic.h"
|
|
#include "nsString.h"
|
|
#include "nsJSPrincipals.h"
|
|
#include "plstr.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsMemory.h"
|
|
#include "nsStringBuffer.h"
|
|
#include "mozilla/BasePrincipal.h"
|
|
#include "mozilla/dom/StructuredCloneTags.h"
|
|
// for mozilla::dom::workerinternals::kJSPrincipalsDebugToken
|
|
#include "mozilla/dom/workerinternals/JSSettings.h"
|
|
// for mozilla::dom::worklet::kJSPrincipalsDebugToken
|
|
#include "mozilla/dom/WorkletPrincipals.h"
|
|
#include "mozilla/ipc/BackgroundUtils.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::ipc;
|
|
|
|
NS_IMETHODIMP_(MozExternalRefCountType)
|
|
nsJSPrincipals::AddRef() {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(int32_t(refcount) >= 0, "illegal refcnt");
|
|
nsrefcnt count = ++refcount;
|
|
NS_LOG_ADDREF(this, count, "nsJSPrincipals", sizeof(*this));
|
|
return count;
|
|
}
|
|
|
|
NS_IMETHODIMP_(MozExternalRefCountType)
|
|
nsJSPrincipals::Release() {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(0 != refcount, "dup release");
|
|
nsrefcnt count = --refcount;
|
|
NS_LOG_RELEASE(this, count, "nsJSPrincipals");
|
|
if (count == 0) {
|
|
delete this;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* static */
|
|
bool nsJSPrincipals::Subsume(JSPrincipals* jsprin, JSPrincipals* other) {
|
|
bool result;
|
|
nsresult rv = nsJSPrincipals::get(jsprin)->Subsumes(
|
|
nsJSPrincipals::get(other), &result);
|
|
return NS_SUCCEEDED(rv) && result;
|
|
}
|
|
|
|
/* static */
|
|
void nsJSPrincipals::Destroy(JSPrincipals* jsprin) {
|
|
// The JS runtime can call this method during the last GC when
|
|
// nsScriptSecurityManager is destroyed. So we must not assume here that
|
|
// the security manager still exists.
|
|
|
|
nsJSPrincipals* nsjsprin = nsJSPrincipals::get(jsprin);
|
|
|
|
// We need to destroy the nsIPrincipal. We'll do this by adding
|
|
// to the refcount and calling release
|
|
|
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
// The refcount logging considers AddRef-to-1 to indicate creation,
|
|
// so trick it into thinking it's otherwise, but balance the
|
|
// Release() we do below.
|
|
nsjsprin->refcount++;
|
|
nsjsprin->AddRef();
|
|
nsjsprin->refcount--;
|
|
#else
|
|
nsjsprin->refcount++;
|
|
#endif
|
|
nsjsprin->Release();
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
|
|
// Defined here so one can do principals->dump() in the debugger
|
|
JS_PUBLIC_API void JSPrincipals::dump() {
|
|
if (debugToken == nsJSPrincipals::DEBUG_TOKEN) {
|
|
nsAutoCString str;
|
|
nsresult rv = static_cast<nsJSPrincipals*>(this)->GetScriptLocation(str);
|
|
fprintf(stderr, "nsIPrincipal (%p) = %s\n", static_cast<void*>(this),
|
|
NS_SUCCEEDED(rv) ? str.get() : "(unknown)");
|
|
} else if (debugToken == dom::workerinternals::kJSPrincipalsDebugToken) {
|
|
fprintf(stderr, "Web Worker principal singleton (%p)\n", this);
|
|
} else if (debugToken == dom::WorkletPrincipals::kJSPrincipalsDebugToken) {
|
|
fprintf(stderr, "Web Worklet principal (%p)\n", this);
|
|
} else {
|
|
fprintf(stderr,
|
|
"!!! JSPrincipals (%p) is not nsJSPrincipals instance - bad token: "
|
|
"actual=0x%x expected=0x%x\n",
|
|
this, unsigned(debugToken), unsigned(nsJSPrincipals::DEBUG_TOKEN));
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/* static */
|
|
bool nsJSPrincipals::ReadPrincipals(JSContext* aCx,
|
|
JSStructuredCloneReader* aReader,
|
|
JSPrincipals** aOutPrincipals) {
|
|
uint32_t tag;
|
|
uint32_t unused;
|
|
if (!JS_ReadUint32Pair(aReader, &tag, &unused)) {
|
|
return false;
|
|
}
|
|
|
|
if (!(tag == SCTAG_DOM_NULL_PRINCIPAL || tag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
|
|
tag == SCTAG_DOM_CONTENT_PRINCIPAL ||
|
|
tag == SCTAG_DOM_EXPANDED_PRINCIPAL ||
|
|
tag == SCTAG_DOM_WORKER_PRINCIPAL)) {
|
|
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
|
return false;
|
|
}
|
|
|
|
return ReadKnownPrincipalType(aCx, aReader, tag, aOutPrincipals);
|
|
}
|
|
|
|
static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
|
|
OriginAttributes& aAttrs, nsACString& aSpec,
|
|
nsACString& aOriginNoSuffix,
|
|
nsACString& aBaseDomain) {
|
|
uint32_t suffixLength, specLength;
|
|
if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
|
|
return false;
|
|
}
|
|
|
|
nsAutoCString suffix;
|
|
if (!suffix.SetLength(suffixLength, fallible)) {
|
|
return false;
|
|
}
|
|
|
|
if (!JS_ReadBytes(aReader, suffix.BeginWriting(), suffixLength)) {
|
|
return false;
|
|
}
|
|
|
|
if (!aAttrs.PopulateFromSuffix(suffix)) {
|
|
return false;
|
|
}
|
|
|
|
if (!aSpec.SetLength(specLength, fallible)) {
|
|
return false;
|
|
}
|
|
|
|
if (!JS_ReadBytes(aReader, aSpec.BeginWriting(), specLength)) {
|
|
return false;
|
|
}
|
|
|
|
uint32_t originNoSuffixLength, dummy;
|
|
if (!JS_ReadUint32Pair(aReader, &originNoSuffixLength, &dummy)) {
|
|
return false;
|
|
}
|
|
|
|
MOZ_ASSERT(dummy == 0);
|
|
if (dummy != 0) {
|
|
return false;
|
|
}
|
|
|
|
if (!aOriginNoSuffix.SetLength(originNoSuffixLength, fallible)) {
|
|
return false;
|
|
}
|
|
|
|
if (!JS_ReadBytes(aReader, aOriginNoSuffix.BeginWriting(),
|
|
originNoSuffixLength)) {
|
|
return false;
|
|
}
|
|
|
|
uint32_t baseDomainIsVoid, baseDomainLength;
|
|
if (!JS_ReadUint32Pair(aReader, &baseDomainIsVoid, &baseDomainLength)) {
|
|
return false;
|
|
}
|
|
|
|
MOZ_ASSERT(baseDomainIsVoid == 0 || baseDomainIsVoid == 1);
|
|
|
|
if (baseDomainIsVoid) {
|
|
MOZ_ASSERT(baseDomainLength == 0);
|
|
|
|
aBaseDomain.SetIsVoid(true);
|
|
return true;
|
|
}
|
|
|
|
if (!aBaseDomain.SetLength(baseDomainLength, fallible)) {
|
|
return false;
|
|
}
|
|
|
|
if (!JS_ReadBytes(aReader, aBaseDomain.BeginWriting(), baseDomainLength)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
|
|
PrincipalInfo& aInfo) {
|
|
if (aTag == SCTAG_DOM_SYSTEM_PRINCIPAL) {
|
|
aInfo = SystemPrincipalInfo();
|
|
} else if (aTag == SCTAG_DOM_NULL_PRINCIPAL) {
|
|
OriginAttributes attrs;
|
|
nsAutoCString spec;
|
|
nsAutoCString originNoSuffix;
|
|
nsAutoCString baseDomain;
|
|
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix, baseDomain)) {
|
|
return false;
|
|
}
|
|
aInfo = NullPrincipalInfo(attrs, spec);
|
|
} else if (aTag == SCTAG_DOM_EXPANDED_PRINCIPAL) {
|
|
uint32_t length, unused;
|
|
if (!JS_ReadUint32Pair(aReader, &length, &unused)) {
|
|
return false;
|
|
}
|
|
|
|
ExpandedPrincipalInfo expanded;
|
|
|
|
for (uint32_t i = 0; i < length; i++) {
|
|
uint32_t tag;
|
|
if (!JS_ReadUint32Pair(aReader, &tag, &unused)) {
|
|
return false;
|
|
}
|
|
|
|
PrincipalInfo sub;
|
|
if (!ReadPrincipalInfo(aReader, tag, sub)) {
|
|
return false;
|
|
}
|
|
expanded.allowlist().AppendElement(sub);
|
|
}
|
|
|
|
aInfo = expanded;
|
|
} else if (aTag == SCTAG_DOM_CONTENT_PRINCIPAL) {
|
|
OriginAttributes attrs;
|
|
nsAutoCString spec;
|
|
nsAutoCString originNoSuffix;
|
|
nsAutoCString baseDomain;
|
|
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix, baseDomain)) {
|
|
return false;
|
|
}
|
|
|
|
#ifdef FUZZING
|
|
if (originNoSuffix.IsEmpty()) {
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!originNoSuffix.IsEmpty());
|
|
|
|
// XXX: Do we care about mDomain for structured clone?
|
|
aInfo = ContentPrincipalInfo(attrs, originNoSuffix, spec, Nothing(),
|
|
baseDomain);
|
|
} else {
|
|
#ifdef FUZZING
|
|
return false;
|
|
#else
|
|
MOZ_CRASH("unexpected principal structured clone tag");
|
|
#endif
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static StaticRefPtr<nsIPrincipal> sActiveWorkerPrincipal;
|
|
|
|
nsJSPrincipals::AutoSetActiveWorkerPrincipal::AutoSetActiveWorkerPrincipal(
|
|
nsIPrincipal* aPrincipal) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_RELEASE_ASSERT(!sActiveWorkerPrincipal);
|
|
sActiveWorkerPrincipal = aPrincipal;
|
|
}
|
|
|
|
nsJSPrincipals::AutoSetActiveWorkerPrincipal::~AutoSetActiveWorkerPrincipal() {
|
|
sActiveWorkerPrincipal = nullptr;
|
|
}
|
|
|
|
/* static */
|
|
bool nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
|
|
JSStructuredCloneReader* aReader,
|
|
uint32_t aTag,
|
|
JSPrincipals** aOutPrincipals) {
|
|
MOZ_ASSERT(aTag == SCTAG_DOM_NULL_PRINCIPAL ||
|
|
aTag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
|
|
aTag == SCTAG_DOM_CONTENT_PRINCIPAL ||
|
|
aTag == SCTAG_DOM_EXPANDED_PRINCIPAL ||
|
|
aTag == SCTAG_DOM_WORKER_PRINCIPAL);
|
|
|
|
if (NS_WARN_IF(!NS_IsMainThread())) {
|
|
xpc::Throw(aCx, NS_ERROR_UNCATCHABLE_EXCEPTION);
|
|
return false;
|
|
}
|
|
|
|
if (aTag == SCTAG_DOM_WORKER_PRINCIPAL) {
|
|
// When reading principals which were written on a worker thread, we need to
|
|
// know the principal of the worker which did the write.
|
|
if (!sActiveWorkerPrincipal) {
|
|
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
|
return false;
|
|
}
|
|
RefPtr<nsJSPrincipals> retval = get(sActiveWorkerPrincipal);
|
|
retval.forget(aOutPrincipals);
|
|
return true;
|
|
}
|
|
|
|
PrincipalInfo info;
|
|
if (!ReadPrincipalInfo(aReader, aTag, info)) {
|
|
return false;
|
|
}
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIPrincipal> prin = PrincipalInfoToPrincipal(info, &rv);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
|
return false;
|
|
}
|
|
|
|
*aOutPrincipals = get(prin.forget().take());
|
|
return true;
|
|
}
|
|
|
|
static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
|
|
const OriginAttributes& aAttrs,
|
|
const nsCString& aSpec,
|
|
const nsCString& aOriginNoSuffix,
|
|
const nsCString& aBaseDomain) {
|
|
nsAutoCString suffix;
|
|
aAttrs.CreateSuffix(suffix);
|
|
|
|
if (!(JS_WriteUint32Pair(aWriter, suffix.Length(), aSpec.Length()) &&
|
|
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
|
|
JS_WriteBytes(aWriter, aSpec.get(), aSpec.Length()) &&
|
|
JS_WriteUint32Pair(aWriter, aOriginNoSuffix.Length(), 0) &&
|
|
JS_WriteBytes(aWriter, aOriginNoSuffix.get(),
|
|
aOriginNoSuffix.Length()))) {
|
|
return false;
|
|
}
|
|
|
|
if (aBaseDomain.IsVoid()) {
|
|
return JS_WriteUint32Pair(aWriter, 1, 0);
|
|
}
|
|
|
|
return JS_WriteUint32Pair(aWriter, 0, aBaseDomain.Length()) &&
|
|
JS_WriteBytes(aWriter, aBaseDomain.get(), aBaseDomain.Length());
|
|
}
|
|
|
|
/* static */
|
|
bool nsJSPrincipals::WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
|
|
const PrincipalInfo& aInfo) {
|
|
if (aInfo.type() == PrincipalInfo::TNullPrincipalInfo) {
|
|
const NullPrincipalInfo& nullInfo = aInfo;
|
|
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_NULL_PRINCIPAL, 0) &&
|
|
::WritePrincipalInfo(aWriter, nullInfo.attrs(), nullInfo.spec(),
|
|
EmptyCString(), EmptyCString());
|
|
}
|
|
if (aInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
|
|
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_SYSTEM_PRINCIPAL, 0);
|
|
}
|
|
if (aInfo.type() == PrincipalInfo::TExpandedPrincipalInfo) {
|
|
const ExpandedPrincipalInfo& expanded = aInfo;
|
|
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_EXPANDED_PRINCIPAL, 0) ||
|
|
!JS_WriteUint32Pair(aWriter, expanded.allowlist().Length(), 0)) {
|
|
return false;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < expanded.allowlist().Length(); i++) {
|
|
if (!WritePrincipalInfo(aWriter, expanded.allowlist()[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
MOZ_ASSERT(aInfo.type() == PrincipalInfo::TContentPrincipalInfo);
|
|
const ContentPrincipalInfo& cInfo = aInfo;
|
|
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL, 0) &&
|
|
::WritePrincipalInfo(aWriter, cInfo.attrs(), cInfo.spec(),
|
|
cInfo.originNoSuffix(), cInfo.baseDomain());
|
|
}
|
|
|
|
bool nsJSPrincipals::write(JSContext* aCx, JSStructuredCloneWriter* aWriter) {
|
|
PrincipalInfo info;
|
|
if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(this, &info)))) {
|
|
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
|
return false;
|
|
}
|
|
|
|
return WritePrincipalInfo(aWriter, info);
|
|
}
|
|
|
|
bool nsJSPrincipals::isSystemOrAddonPrincipal() {
|
|
return this->IsSystemPrincipal() ||
|
|
this->GetIsAddonOrExpandedAddonPrincipal();
|
|
}
|