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

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


#include "UrlClassifierExceptionList.h"
#include "nsIEffectiveTLDService.h"
#include "nsIUrlClassifierExceptionListEntry.h"
#include "nsIURI.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/ProfilerMarkers.h"
#include "nsNetCID.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/RustRegex.h"

namespace mozilla::net {

NS_IMPL_ISUPPORTS(UrlClassifierExceptionList, nsIUrlClassifierExceptionList)

NS_IMETHODIMP
UrlClassifierExceptionList::Init(const nsACString& aFeature) {
  mFeature = aFeature;
  return NS_OK;
}

NS_IMETHODIMP
UrlClassifierExceptionList::AddEntry(
    nsIUrlClassifierExceptionListEntry* aEntry) {
  NS_ENSURE_ARG_POINTER(aEntry);

  // From the url patterns in the entry, extract the site and top level site.
  // They are used as keys in the exception entry maps.

  nsAutoCString urlPattern;
  nsresult rv = aEntry->GetUrlPattern(urlPattern);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoCString topLevelUrlPattern;
  rv = aEntry->GetTopLevelUrlPattern(topLevelUrlPattern);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoCString topLevelSite;
  rv = GetSchemelessSiteFromUrlPattern(topLevelUrlPattern, topLevelSite);
  NS_ENSURE_SUCCESS(rv, rv);

  // topLevelUrlPattern is not mandatory, but if topLevelUrlPattern is set,
  // topLevelSite populated as well.
  NS_ENSURE_TRUE(topLevelUrlPattern.IsEmpty() == topLevelSite.IsEmpty(),
                 NS_ERROR_INVALID_ARG);

  if (MOZ_LOG_TEST(gChannelClassifierLog, LogLevel::Debug)) {
    nsAutoCString entryString;
    (void)aEntry->Describe(entryString);
    UC_LOG_DEBUG(("UrlClassifierExceptionList::%s - Adding entry: %s",
                  __FUNCTION__, entryString.get()));
  }

  // If the top level site is empty, the exception applies across all top
  // level sites. Store it in the global exceptions map.
  if (topLevelSite.IsEmpty()) {
    nsAutoCString site;
    rv = GetSchemelessSiteFromUrlPattern(urlPattern, site);
    NS_ENSURE_SUCCESS(rv, rv);

    // We must be able to parse a site from the url pattern.
    NS_ENSURE_TRUE(!site.IsEmpty(), NS_ERROR_INVALID_ARG);

    mGlobalExceptions.LookupOrInsert(site).AppendElement(aEntry);
    return NS_OK;
  }

  // Otherwise, store it in the site specific exception map.
  mExceptions.LookupOrInsert(topLevelSite).AppendElement(aEntry);

  return NS_OK;
}

NS_IMETHODIMP
UrlClassifierExceptionList::Matches(nsIURI* aURI, nsIURI* aTopLevelURI,
                                    bool aIsPrivateBrowsing, bool* aResult) {
  NS_ENSURE_ARG_POINTER(aURI);
  NS_ENSURE_ARG_POINTER(aResult);

  // Record how long it takes to perform the exception list lookup.
  AUTO_PROFILER_MARKER_UNTYPED("UrlClassifierExceptionList::Matches", OTHER,
                               MarkerTiming::IntervalStart());

  *aResult = false;

  UC_LOG_DEBUG(
      ("UrlClassifierExceptionList::%s - aURI: %s, aTopLevelURI: %s, "
       "aIsPrivateBrowsing: %d",
       __FUNCTION__, aURI->GetSpecOrDefault().get(),
       aTopLevelURI ? aTopLevelURI->GetSpecOrDefault().get() : "null",
       aIsPrivateBrowsing));

  // Get the eTLD service so we can compute sites from URIs.
  nsresult rv;
  nsCOMPtr<nsIEffectiveTLDService> eTLDService(
      do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  // If given, compute the (schemeless) site from the top level URI.
  // If not we will leave it empty and only look for global exceptions.
  nsAutoCString aTopLevelSite;
  if (aTopLevelURI) {
    rv = eTLDService->GetSchemelessSite(aTopLevelURI, aTopLevelSite);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Compute the (schemeless) site from the URI of the load.
  nsAutoCString aSite;
  rv = eTLDService->GetSchemelessSite(aURI, aSite);
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the list of exceptions that apply to the current load.
  // We need to check both global and site specific exceptions

  // 1. Check global exceptions, which apply to all top level sites and lookup
  //    entries matching the current load (aSite).
  ExceptionEntryArray* globalExceptions =
      mGlobalExceptions.Lookup(aSite).DataPtrOrNull();

  *aResult = ExceptionListMatchesLoad(globalExceptions, aURI, aTopLevelURI,
                                      aIsPrivateBrowsing);
  if (*aResult) {
    // We found a match, no need to check the site specific exceptions.
    return NS_OK;
  }

  // 2. Get exceptions which apply only to the current top level site.
  ExceptionEntryArray* siteSpecificExceptions =
      mExceptions.Lookup(aTopLevelSite).DataPtrOrNull();
  if (siteSpecificExceptions) {
    *aResult = ExceptionListMatchesLoad(siteSpecificExceptions, aURI,
                                        aTopLevelURI, aIsPrivateBrowsing);
    if (*aResult) {
      return NS_OK;
    }
  }

  if (!(*aResult)) {
    UC_LOG_DEBUG(("%s - No match found", __FUNCTION__));
  }

  return NS_OK;
}

bool UrlClassifierExceptionList::ExceptionListMatchesLoad(
    ExceptionEntryArray* aExceptions, nsIURI* aURI, nsIURI* aTopLevelURI,
    bool aIsPrivateBrowsing) {
  MOZ_ASSERT(aURI);

  if (!aExceptions) {
    return false;
  }
  for (const auto& entry : *aExceptions) {
    bool match = false;
    nsresult rv =
        entry->Matches(aURI, aTopLevelURI, aIsPrivateBrowsing, &match);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      continue;
    }
    if (match) {
      // Match found, return immediately.
      if (MOZ_LOG_TEST(gChannelClassifierLog, LogLevel::Debug)) {
        nsAutoCString entryString;
        (void)entry->Describe(entryString);
        UC_LOG_DEBUG(
            ("UrlClassifierExceptionList::%s - Exception list match found. "
             "entry: %s",
             __FUNCTION__, entryString.get()));
      }
      return true;
    }
  }
  return false;
}

NS_IMETHODIMP
UrlClassifierExceptionList::GetSchemelessSiteFromUrlPattern(
    const nsACString& aUrlPattern, nsACString& aSite) {
  if (aUrlPattern.IsEmpty()) {
    aSite.Truncate();
    return NS_OK;
  }

  // Extract the host portion from the url pattern. This regex only supports url
  // patterns with a host.
  mozilla::RustRegex regex("://(?:\\*\\.)?([^/*]+)");
  mozilla::RustRegexCaptures captures = regex.FindCaptures(aUrlPattern);
  NS_ENSURE_TRUE(captures.IsValid(), NS_ERROR_INVALID_ARG);

  // Get the host from the first capture group
  auto maybeMatch = captures[1];
  NS_ENSURE_TRUE(maybeMatch, NS_ERROR_INVALID_ARG);

  nsAutoCString host;
  host.Assign(Substring(aUrlPattern, maybeMatch->start,
                        maybeMatch->end - maybeMatch->start));
  NS_ENSURE_TRUE(!host.IsEmpty(), NS_ERROR_INVALID_ARG);

  // Get the eTLD service to convert host to schemeless site
  nsresult rv;
  nsCOMPtr<nsIEffectiveTLDService> eTLDService(
      do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  return eTLDService->GetSchemelessSiteFromHost(host, aSite);
}

NS_IMETHODIMP
UrlClassifierExceptionList::TestGetEntries(
    nsTArray<RefPtr<nsIUrlClassifierExceptionListEntry>>& aEntries) {
  // Global entries (not top-level specific)
  for (const auto& entry : mGlobalExceptions) {
    const ExceptionEntryArray& entries = entry.GetData();
    aEntries.AppendElements(entries);
  }

  // Site specific entries.
  for (const auto& entry : mExceptions) {
    const ExceptionEntryArray& entries = entry.GetData();
    // Append all entries from this array to the result
    aEntries.AppendElements(entries);
  }

  return NS_OK;
}
}  // namespace mozilla::net

Messung V0.5 in Prozent
C=84 H=91 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.