Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/netwerk/base/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 19 kB image not shown  

Quelle  nsSimpleURI.cpp

  Sprache: C
 

/* 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/. */


#undef LOG
#include "ipc/IPCMessageUtils.h"

#include "nsSimpleURI.h"
#include "nscore.h"
#include "nsCRT.h"
#include "nsString.h"
#include "nsURLHelper.h"
#include "nsNetCID.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsEscape.h"
#include "nsError.h"
#include "nsQueryObject.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TextUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "nsIClassInfoImpl.h"
#include "nsIURIMutator.h"
#include "mozilla/net/MozURL.h"
#include "mozilla/StaticPrefs_network.h"

using namespace mozilla::ipc;

namespace mozilla {
namespace net {

NS_IMPL_CLASSINFO(nsSimpleURI, nullptr, nsIClassInfo::THREADSAFE,
                  NS_SIMPLEURI_CID)
// Empty CI getter. We only need nsIClassInfo for Serialization
NS_IMPL_CI_INTERFACE_GETTER0(nsSimpleURI)

////////////////////////////////////////////////////////////////////////////////
// nsSimpleURI methods:

NS_IMPL_ADDREF(nsSimpleURI)
NS_IMPL_RELEASE(nsSimpleURI)
NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
  NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsISerializable,
                     nsIIPCSerializableURI, nsIURIWithSizeOf)
  NS_INTERFACE_TABLE_TO_MAP_SEGUE
  NS_IMPL_QUERY_CLASSINFO(nsSimpleURI)
  NS_INTERFACE_MAP_ENTRY_CONCRETE(nsSimpleURI)
NS_INTERFACE_MAP_END

////////////////////////////////////////////////////////////////////////////////
// nsISerializable methods:

NS_IMETHODIMP
nsSimpleURI::Read(nsIObjectInputStream* aStream) {
  MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
  return NS_ERROR_NOT_IMPLEMENTED;
}

nsresult nsSimpleURI::ReadPrivate(nsIObjectInputStream* aStream) {
  nsresult rv;

  bool isMutable;
  rv = aStream->ReadBoolean(&isMutable);
  if (NS_FAILED(rv)) return rv;
  (void)isMutable;

  nsAutoCString scheme;
  rv = aStream->ReadCString(scheme);
  if (NS_FAILED(rv)) return rv;

  nsAutoCString path;
  rv = aStream->ReadCString(path);
  if (NS_FAILED(rv)) return rv;

  bool isRefValid;
  rv = aStream->ReadBoolean(&isRefValid);
  if (NS_FAILED(rv)) return rv;

  nsAutoCString ref;
  if (isRefValid) {
    rv = aStream->ReadCString(ref);
    if (NS_FAILED(rv)) return rv;
  }

  bool isQueryValid;
  rv = aStream->ReadBoolean(&isQueryValid);
  if (NS_FAILED(rv)) return rv;

  nsAutoCString query;
  if (isQueryValid) {
    rv = aStream->ReadCString(query);
    if (NS_FAILED(rv)) return rv;
  }

  // Re-constitute the spec, and initialize from it.
  nsAutoCString spec = scheme + ":"_ns + path;
  if (isQueryValid) {
    spec += "?"_ns + query;
  }
  if (isRefValid) {
    spec += "#"_ns + ref;
  }
  return SetSpecInternal(spec);
}

NS_IMETHODIMP
nsSimpleURI::Write(nsIObjectOutputStream* aStream) {
  nsresult rv;

  rv = aStream->WriteBoolean(false);  // former mMutable
  if (NS_FAILED(rv)) return rv;

  rv = aStream->WriteCString(Scheme());
  if (NS_FAILED(rv)) return rv;

  rv = aStream->WriteCString(Path());
  if (NS_FAILED(rv)) return rv;

  rv = aStream->WriteBoolean(IsRefValid());
  if (NS_FAILED(rv)) return rv;

  if (IsRefValid()) {
    rv = aStream->WriteCString(Ref());
    if (NS_FAILED(rv)) return rv;
  }

  rv = aStream->WriteBoolean(IsQueryValid());
  if (NS_FAILED(rv)) return rv;

  if (IsQueryValid()) {
    rv = aStream->WriteCString(Query());
    if (NS_FAILED(rv)) return rv;
  }

  return NS_OK;
}

void nsSimpleURI::Serialize(URIParams& aParams) {
  SimpleURIParams params;

  params.spec() = mSpec;

  aParams = params;
}

bool nsSimpleURI::Deserialize(const URIParams& aParams) {
  if (aParams.type() != URIParams::TSimpleURIParams) {
    NS_ERROR("Received unknown parameters from the other process!");
    return false;
  }

  const SimpleURIParams& params = aParams.get_SimpleURIParams();

  nsresult rv = SetSpecInternal(params.spec());
  if (NS_FAILED(rv)) {
    NS_ERROR("Failed to set spec from other process");
    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
// nsIURI methods:

NS_IMETHODIMP
nsSimpleURI::GetSpec(nsACString& result) {
  result = mSpec;
  return NS_OK;
}

// result may contain unescaped UTF-8 characters
NS_IMETHODIMP
nsSimpleURI::GetSpecIgnoringRef(nsACString& result) {
  if (!IsRefValid()) {
    // Optimization: If there is no ref which needs to be trimmed, call
    // `GetSpec` to allow result to share the `mSpec` string buffer.
    return GetSpec(result);
  }

  result = SpecIgnoringRef();
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetDisplaySpec(nsACString& aUnicodeSpec) {
  return GetSpec(aUnicodeSpec);
}

NS_IMETHODIMP
nsSimpleURI::GetDisplayHostPort(nsACString& aUnicodeHostPort) {
  return GetHostPort(aUnicodeHostPort);
}

NS_IMETHODIMP
nsSimpleURI::GetDisplayHost(nsACString& aUnicodeHost) {
  return GetHost(aUnicodeHost);
}

NS_IMETHODIMP
nsSimpleURI::GetDisplayPrePath(nsACString& aPrePath) {
  return GetPrePath(aPrePath);
}

NS_IMETHODIMP
nsSimpleURI::GetHasRef(bool* result) {
  *result = IsRefValid();
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetHasUserPass(bool* result) {
  *result = false;
  return NS_OK;
}

nsresult nsSimpleURI::SetSpecInternal(const nsACString& aSpec,
                                      bool aStripWhitespace) {
  if (StaticPrefs::network_url_max_length() &&
      aSpec.Length() > StaticPrefs::network_url_max_length()) {
    return NS_ERROR_MALFORMED_URI;
  }

  nsAutoCString scheme;
  nsresult rv = net_ExtractURLScheme(aSpec, scheme);
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsAutoCString spec;
  rv = net_FilterAndEscapeURI(
      aSpec, esc_OnlyNonASCII,
      aStripWhitespace ? ASCIIMask::MaskWhitespace() : ASCIIMask::MaskCRLFTab(),
      spec);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Copy the filtered string into `mSpec`. We'll try not to mutate this buffer
  // unless it's required so we can share the (potentially very large data: URI)
  // string buffer.
  mSpec = std::move(spec);
  mPathSep = mSpec.FindChar(':');
  MOZ_ASSERT(mPathSep != kNotFound, "A colon should be in this string");
  mQuerySep = kNotFound;
  mRefSep = kNotFound;

  // Check if `net_ExtractURLScheme` changed the scheme as written, and update
  // `mSpec` if it did.
  if (Scheme() != scheme) {
    if (!mSpec.Replace(SchemeStart(), SchemeLen(), scheme, fallible)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
    mPathSep = scheme.Length();
    MOZ_ASSERT(mSpec.CharAt(mPathSep) == ':');
  }

  // Populate the remaining members.
  return SetPathQueryRefInternal();
}

NS_IMETHODIMP
nsSimpleURI::GetScheme(nsACString& result) {
  result = Scheme();
  return NS_OK;
}

nsresult nsSimpleURI::SetScheme(const nsACString& input) {
  // Strip tabs, newlines, carriage returns from input
  nsAutoCString scheme(input);
  scheme.StripTaggedASCII(ASCIIMask::MaskCRLFTab());
  ToLowerCase(scheme);

  if (!net_IsValidScheme(scheme)) {
    NS_WARNING("the given url scheme contains invalid characters");
    return NS_ERROR_MALFORMED_URI;
  }

  int32_t delta = static_cast<int32_t>(scheme.Length()) - mPathSep;
  mSpec.Replace(SchemeStart(), SchemeLen(), scheme);

  // Adjust the separator indexes to account for the change in scheme length.
  mPathSep += delta;
  MOZ_ASSERT(mSpec.CharAt(mPathSep) == ':');
  if (IsQueryValid()) {
    mQuerySep += delta;
    MOZ_ASSERT(mSpec.CharAt(mQuerySep) == '?');
  }
  if (IsRefValid()) {
    mRefSep += delta;
    MOZ_ASSERT(mSpec.CharAt(mRefSep) == '#');
  }

  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetPrePath(nsACString& result) {
  result = Substring(mSpec, 0, PathStart());
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetUserPass(nsACString& result) { return NS_ERROR_FAILURE; }

nsresult nsSimpleURI::SetUserPass(const nsACString& userPass) {
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsSimpleURI::GetUsername(nsACString& result) { return NS_ERROR_FAILURE; }

nsresult nsSimpleURI::SetUsername(const nsACString& userName) {
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsSimpleURI::GetPassword(nsACString& result) { return NS_ERROR_FAILURE; }

nsresult nsSimpleURI::SetPassword(const nsACString& password) {
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsSimpleURI::GetHostPort(nsACString& result) {
  // Note: Audit all callers before changing this to return an empty
  // string -- CAPS and UI code may depend on this throwing.
  // Note: If this is changed, change GetAsciiHostPort as well.
  return NS_ERROR_FAILURE;
}

nsresult nsSimpleURI::SetHostPort(const nsACString& aValue) {
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsSimpleURI::GetHost(nsACString& result) {
  // Note: Audit all callers before changing this to return an empty
  // string -- CAPS and UI code depend on this throwing.
  return NS_ERROR_FAILURE;
}

nsresult nsSimpleURI::SetHost(const nsACString& host) {
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsSimpleURI::GetPort(int32_t* result) {
  // Note: Audit all callers before changing this to return an empty
  // string -- CAPS and UI code may depend on this throwing.
  return NS_ERROR_FAILURE;
}

nsresult nsSimpleURI::SetPort(int32_t port) { return NS_ERROR_FAILURE; }

NS_IMETHODIMP
nsSimpleURI::GetPathQueryRef(nsACString& result) {
  result = Substring(mSpec, PathStart());
  return NS_OK;
}

nsresult nsSimpleURI::SetPathQueryRef(const nsACString& aPath) {
  if (StaticPrefs::network_url_max_length()) {
    CheckedInt<uint32_t> newLength(mSpec.Length());
    newLength -= PathLen();
    newLength += aPath.Length();
    if (!newLength.isValid() ||
        newLength.value() > StaticPrefs::network_url_max_length()) {
      return NS_ERROR_MALFORMED_URI;
    }
  }

  nsAutoCString path;
  nsresult rv = NS_EscapeURL(aPath, esc_OnlyNonASCII, path, fallible);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Clear out the components being replaced. They'll be re-initialized below.
  mQuerySep = kNotFound;
  mRefSep = kNotFound;

  mSpec.Truncate(PathStart());
  if (!mSpec.Append(path, fallible)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  return SetPathQueryRefInternal();
}

nsresult nsSimpleURI::SetPathQueryRefInternal() {
  MOZ_ASSERT(mSpec.CharAt(mPathSep) == ':');
  MOZ_ASSERT(mQuerySep == kNotFound);
  MOZ_ASSERT(mRefSep == kNotFound);

  // Initialize `mQuerySep` and `mRefSep` if those components are present.
  int32_t pathEnd = mSpec.FindCharInSet("?#", PathStart());
  if (pathEnd != kNotFound) {
    if (mSpec.CharAt(pathEnd) == '?') {
      mQuerySep = pathEnd;
    } else {
      mRefSep = pathEnd;
    }
  }

  if (IsQueryValid()) {
    mRefSep = mSpec.FindChar('#', QueryStart());
  }

  // Unlike the path or query, `mRef` also requires spaces to be escaped.
  if (IsRefValid()) {
    // NOTE: `NS_EscapeURLSpan` could theoretically OOM-fail, but there is no
    // fallible version of `NS_EscapeURL` which won't do an unnecessary copy in
    // the non-escaping case.
    nsAutoCString escapedRef;
    if (NS_EscapeURLSpan(Ref(), esc_Ref, escapedRef)) {
      if (!mSpec.Replace(RefStart(), RefLen(), escapedRef, fallible)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
    }
  }

  if (Scheme() != "javascript"_ns && !IsQueryValid() && !IsRefValid()) {
    TrimTrailingCharactersFromPath();
  }
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetRef(nsACString& result) {
  if (!IsRefValid()) {
    result.Truncate();
  } else {
    result = Ref();
  }

  return NS_OK;
}

// NOTE: SetRef("") removes our ref, whereas SetRef("#") sets it to the empty
// string (and will result in .spec and .path having a terminal #).
nsresult nsSimpleURI::SetRef(const nsACString& aRef) {
  if (StaticPrefs::network_url_max_length() &&
      aRef.Length() > StaticPrefs::network_url_max_length()) {
    return NS_ERROR_MALFORMED_URI;
  }

  nsAutoCString filteredRef(aRef);
  filteredRef.StripTaggedASCII(ASCIIMask::MaskCRLFTab());

  nsAutoCString ref;
  nsresult rv = NS_EscapeURL(filteredRef, esc_Ref, ref, fallible);
  if (NS_FAILED(rv)) {
    return rv;
  }

  if (ref.IsEmpty() && !IsRefValid()) {
    return NS_OK;  // nothing to do
  }

  int32_t cutStart;
  int32_t cutLength;
  if (IsRefValid()) {
    cutStart = mRefSep;
    cutLength = RefEnd() - cutStart;
  } else {
    cutStart = mSpec.Length();
    cutLength = 0;
  }

  nsCString prefix;
  if (!ref.IsEmpty() && ref[0] != '#') {
    // The replace includes the `#` character, so ensure it's present in the
    // ref (unless we're removing the ref).
    prefix = "#"_ns;
  }
  if (!mSpec.Replace(cutStart, cutLength, prefix + ref, fallible)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  if (ref.IsEmpty()) {
    mRefSep = kNotFound;
  } else {
    mRefSep = cutStart;
    MOZ_ASSERT(mSpec.CharAt(mRefSep) == '#');
  }

  // Trim trailing invalid chars when ref and query are removed
  if (Scheme() != "javascript"_ns && !IsRefValid() && !IsQueryValid()) {
    TrimTrailingCharactersFromPath();
  }

  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::Equals(nsIURI* other, bool* result) {
  return EqualsInternal(other, eHonorRef, result);
}

NS_IMETHODIMP
nsSimpleURI::EqualsExceptRef(nsIURI* other, bool* result) {
  return EqualsInternal(other, eIgnoreRef, result);
}

/* virtual */
nsresult nsSimpleURI::EqualsInternal(
    nsIURI* other, nsSimpleURI::RefHandlingEnum refHandlingMode, bool* result) {
  NS_ENSURE_ARG_POINTER(other);
  MOZ_ASSERT(result, "null pointer");

  RefPtr<nsSimpleURI> otherUri = do_QueryObject(other);
  if (!otherUri) {
    *result = false;
    return NS_OK;
  }

  *result = EqualsInternal(otherUri, refHandlingMode);
  return NS_OK;
}

bool nsSimpleURI::EqualsInternal(nsSimpleURI* otherUri,
                                 RefHandlingEnum refHandlingMode) {
  if (refHandlingMode != eHonorRef) {
    return SpecIgnoringRef() == otherUri->SpecIgnoringRef();
  }

  return mSpec == otherUri->mSpec;
}

NS_IMETHODIMP
nsSimpleURI::SchemeIs(const char* i_Scheme, bool* o_Equals) {
  MOZ_ASSERT(o_Equals, "null pointer");
  if (!i_Scheme) {
    *o_Equals = false;
    return NS_OK;
  }

  *o_Equals = Scheme().EqualsIgnoreCase(i_Scheme);
  return NS_OK;
}

/* virtual */ already_AddRefed<nsSimpleURI> nsSimpleURI::StartClone() {
  RefPtr<nsSimpleURI> url = new nsSimpleURI();
  return url.forget();
}

nsresult nsSimpleURI::Clone(nsIURI** result) {
  RefPtr<nsSimpleURI> url = StartClone();
  if (!url) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  url->mSpec = mSpec;
  url->mPathSep = mPathSep;
  url->mQuerySep = mQuerySep;
  url->mRefSep = mRefSep;

  url.forget(result);
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::Resolve(const nsACString& relativePath, nsACString& result) {
  nsAutoCString scheme;
  nsresult rv = net_ExtractURLScheme(relativePath, scheme);
  if (NS_SUCCEEDED(rv)) {
    result = relativePath;
    return NS_OK;
  }

  nsAutoCString spec;
  rv = GetAsciiSpec(spec);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    // If getting the spec fails for some reason, preserve behaviour and just
    // return the relative path.
    result = relativePath;
    return NS_OK;
  }

  RefPtr<MozURL> url;
  rv = MozURL::Init(getter_AddRefs(url), spec);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    // If parsing the current url fails, we revert to the previous behaviour
    // and just return the relative path.
    result = relativePath;
    return NS_OK;
  }

  RefPtr<MozURL> url2;
  rv = MozURL::Init(getter_AddRefs(url2), relativePath, url);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    // If parsing the relative url fails, we revert to the previous behaviour
    // and just return the relative path.
    result = relativePath;
    return NS_OK;
  }

  result = url2->Spec();
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetAsciiSpec(nsACString& aResult) {
  nsresult rv = GetSpec(aResult);
  if (NS_FAILED(rv)) return rv;
  MOZ_ASSERT(IsAscii(aResult), "The spec should be ASCII");
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetAsciiHostPort(nsACString& result) {
  // XXX This behavior mimics GetHostPort.
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsSimpleURI::GetAsciiHost(nsACString& result) {
  result.Truncate();
  return NS_OK;
}

// Among the sub-classes that inherit (directly or indirectly) from
// nsSimpleURI, measurement of the following members may be added later if
// DMD finds it is worthwhile:
// - nsJSURI: mBaseURI
// - nsSimpleNestedURI: mInnerURI
// - nsBlobURI: mPrincipal
size_t nsSimpleURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
  return aMallocSizeOf(this) +
         mSpec.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}

NS_IMETHODIMP
nsSimpleURI::GetFilePath(nsACString& aFilePath) {
  aFilePath = Path();
  return NS_OK;
}

nsresult nsSimpleURI::SetFilePath(const nsACString& aFilePath) {
  if (Path().IsEmpty() || Path().First() != '/') {
    // cannot-be-a-base
    return NS_ERROR_MALFORMED_URI;
  }
  const char* current = aFilePath.BeginReading();
  const char* end = aFilePath.EndReading();

  // Only go up to the first ? or # symbol
  for (; current < end; ++current) {
    if (*current == '?' || *current == '#') {
      break;
    }
  }
  return SetPathQueryRef(
      nsDependentCSubstring(aFilePath.BeginReading(), current));
}

NS_IMETHODIMP
nsSimpleURI::GetQuery(nsACString& aQuery) {
  if (!IsQueryValid()) {
    aQuery.Truncate();
  } else {
    aQuery = Query();
  }
  return NS_OK;
}

NS_IMETHODIMP
nsSimpleURI::GetHasQuery(bool* result) {
  *result = IsQueryValid();
  return NS_OK;
}

nsresult nsSimpleURI::SetQuery(const nsACString& aQuery) {
  if (StaticPrefs::network_url_max_length() &&
      aQuery.Length() > StaticPrefs::network_url_max_length()) {
    return NS_ERROR_MALFORMED_URI;
  }
  nsAutoCString query;
  nsresult rv = NS_EscapeURL(aQuery, esc_OnlyNonASCII, query, fallible);
  if (NS_FAILED(rv)) {
    return rv;
  }

  if (query.IsEmpty() && !IsQueryValid()) {
    return NS_OK;  // nothing to do
  }

  int32_t cutStart;
  int32_t cutLength;
  if (IsQueryValid()) {
    cutStart = mQuerySep;
    cutLength = QueryEnd() - cutStart;
  } else if (IsRefValid()) {
    cutStart = mRefSep;
    cutLength = 0;
  } else {
    cutStart = mSpec.Length();
    cutLength = 0;
  }

  nsCString prefix;
  if (!query.IsEmpty() && query[0] != '?') {
    // The replace includes the `?` character, so ensure it's present in the
    // query (unless we're removing the query).
    prefix = "?"_ns;
  }
  if (!mSpec.Replace(cutStart, cutLength, prefix + query, fallible)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  // Update `mQuerySep` and `mRefSep`.
  if (query.IsEmpty()) {
    mQuerySep = kNotFound;
  } else {
    mQuerySep = cutStart;
    MOZ_ASSERT(mSpec.CharAt(mQuerySep) == '?');
  }
  if (mRefSep != kNotFound) {
    mRefSep -= cutLength;
    mRefSep += prefix.Length() + query.Length();
    MOZ_ASSERT(mSpec.CharAt(mRefSep) == '#');
  }

  // Trim trailing invalid chars when ref and query are removed
  if (Scheme() != "javascript"_ns && !IsRefValid() && !IsQueryValid()) {
    TrimTrailingCharactersFromPath();
  }

  return NS_OK;
}

nsresult nsSimpleURI::SetQueryWithEncoding(const nsACString& aQuery,
                                           const Encoding* aEncoding) {
  return SetQuery(aQuery);
}

void nsSimpleURI::TrimTrailingCharactersFromPath() {
  MOZ_ASSERT(!IsQueryValid());
  MOZ_ASSERT(!IsRefValid());

  const auto* start = mSpec.BeginReading();
  const auto* end = mSpec.EndReading();

  auto charFilter = [](char c) { return static_cast<uint8_t>(c) > 0x20; };
  const auto* newEnd =
      std::find_if(std::reverse_iterator<decltype(end)>(end),
                   std::reverse_iterator<decltype(start)>(start), charFilter)
          .base();

  auto trailCount = std::distance(newEnd, end);
  if (trailCount) {
    mSpec.Truncate(mSpec.Length() - trailCount);
  }
}

// Queries this list of interfaces. If none match, it queries mURI.
NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleURI::Mutator, nsIURISetters,
                                nsIURIMutator, nsISerializable,
                                nsISimpleURIMutator)

NS_IMETHODIMP
nsSimpleURI::Mutate(nsIURIMutator** aMutator) {
  RefPtr<nsSimpleURI::Mutator> mutator = new nsSimpleURI::Mutator();
  nsresult rv = mutator->InitFromURI(this);
  if (NS_FAILED(rv)) {
    return rv;
  }
  mutator.forget(aMutator);
  return NS_OK;
}

}  // namespace net
}  // namespace mozilla

Messung V0.5 in Prozent
C=83 H=92 G=87

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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 und die Messung sind noch experimentell.