Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/caps/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  nsJSPrincipals.cpp   Sprache: 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 "nsIPrincipal.h"
#include "xpcpublic.h"
#include "nsString.h"
#include "nsJSPrincipals.h"
#include "nsCOMPtr.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"

using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::ipc;

NS_IMETHODIMP_(MozExternalRefCountType)
nsJSPrincipals::AddRef() {
  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(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 {
    fprintf(stderr,
            "!!! JSPrincipals (%p) is not nsJSPrincipals instance - bad token: "
            "actual=0x%x expected=0x%x\n",
            thisunsigned(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) {
    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;
  }

  if (baseDomainIsVoid != 0 && baseDomainIsVoid != 1) {
    return false;
  }

  if (baseDomainIsVoid) {
    if (baseDomainLength != 0) {
      return false;
    }

    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 */
bool nsJSPrincipals::ReadPrincipalInfo(JSStructuredCloneReader* aReader,
                                       PrincipalInfo& aInfo) {
  uint32_t tag, unused;
  if (!JS_ReadUint32Pair(aReader, &tag, &unused)) {
    return false;
  }
  return ::ReadPrincipalInfo(aReader, tag, aInfo);
}

/* 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);

  PrincipalInfo info;
  if (!::ReadPrincipalInfo(aReader, aTag, info)) {
    return false;
  }

  auto principalOrErr = PrincipalInfoToPrincipal(info);
  if (NS_WARN_IF(principalOrErr.isErr())) {
    xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
    return false;
  }

  nsCOMPtr<nsIPrincipal> principal = principalOrErr.unwrap();

  *aOutPrincipals = get(principal.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(),
                                ""_ns, ""_ns);
  }
  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() {
  JS::AutoSuppressGCAnalysis suppress;
  return this->IsSystemPrincipal() ||
         this->GetIsAddonOrExpandedAddonPrincipal();
}

98%


¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.