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

Quelle  TestNoVarySearchUtils.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 "gtest/gtest.h"

#include "mozilla/gtest/MozAssertions.h"
#include "mozilla/net/NoVarySearchUtils.h"
#include "nsNetUtil.h"

using namespace mozilla::net;

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

static NoVarySearchData Parse(const char* aHeader) {
  return ParseNoVarySearchHeader(nsDependentCString(aHeader));
}

static nsCOMPtr<nsIURI> MakeURI(const char* aSpec) {
  nsCOMPtr<nsIURI> uri;
  NS_NewURI(getter_AddRefs(uri), nsDependentCString(aSpec));
  return uri;
}

static bool Equiv(const char* aURIA, const char* aURIB, const char* aHeader) {
  auto data = Parse(aHeader);
  nsCOMPtr<nsIURI> uriA = MakeURI(aURIA);
  nsCOMPtr<nsIURI> uriB = MakeURI(aURIB);
  return URLsAreEquivalentModuloVariationConfig(uriA, uriB, data);
}

// ---------------------------------------------------------------------------
// ParseNoVarySearchHeader tests
// ---------------------------------------------------------------------------

TEST(TestNoVarySearchParse, EmptyHeader)
{
  auto d = Parse("");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
  EXPECT_TRUE(d.varyOnKeyOrder);
}

TEST(TestNoVarySearchParse, InvalidSF)
{
  auto d = Parse("!!!not valid sf!!!");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
}

TEST(TestNoVarySearchParse, ParamsInvalidType)
{
  // params with an integer value is not a valid type → ExactMatch
  auto d = Parse("params=42");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
}

TEST(TestNoVarySearchParse, UnknownKeysOnly)
{
  // Header with only unknown keys → ExactMatch (no params, no except)
  auto d = Parse("x-custom=?1, x-other=?0");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
  EXPECT_TRUE(d.varyOnKeyOrder);
}

TEST(TestNoVarySearchParse, ParamsAndExceptTogether)
{
  // params=(inner list) + except → invalid → ExactMatch
  auto d = Parse(R"(params=("a"), except=("b"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
}

TEST(TestNoVarySearchParse, ExceptWithoutParams)
{
  // except without params → invalid → ExactMatch
  auto d = Parse(R"(except=("a"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
}

TEST(TestNoVarySearchParse, ExceptEmptyWithoutParams)
{
  // except with empty inner list, no params → invalid → ExactMatch
  auto d = Parse("except=()");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
}

TEST(TestNoVarySearchParse, ParamsBareToken)
{
  // bare `params` token → IgnoreAll
  // https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#section-5.1-6
  auto d = Parse("params");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::IgnoreAll);
  EXPECT_TRUE(d.paramNames.IsEmpty());
  EXPECT_TRUE(d.varyOnKeyOrder);
}

TEST(TestNoVarySearchParse, ParamsExplicitBooleanTrue)
{
  // params=?1 (explicit boolean true) → IgnoreAll, same as bare params
  auto d = Parse("params=?1");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::IgnoreAll);
  EXPECT_TRUE(d.paramNames.IsEmpty());
}

TEST(TestNoVarySearchParse, ParamsExplicitBooleanFalse)
{
  // params=?0 (boolean false) → ExactMatch (not IgnoreAll)
  auto d = Parse("params=?0");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
}

TEST(TestNoVarySearchParse, ParamsSingleItem)
{
  auto d = Parse(R"(params=("a"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::Blocklist);
  ASSERT_EQ(d.paramNames.Length(), 1u);
  EXPECT_EQ(d.paramNames[0], "a"_ns);
}

TEST(TestNoVarySearchParse, ParamsMultipleItems)
{
  auto d = Parse(R"(params=("a" "b" "c"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::Blocklist);
  ASSERT_EQ(d.paramNames.Length(), 3u);
  EXPECT_EQ(d.paramNames[0], "a"_ns);
  EXPECT_EQ(d.paramNames[1], "b"_ns);
  EXPECT_EQ(d.paramNames[2], "c"_ns);
}

TEST(TestNoVarySearchParse, ExceptAllowlist)
{
  // params, except=("id") → Allowlist
  // https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#section-5.1-7
  auto d = Parse(R"(params, except=("id"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::Allowlist);
  ASSERT_EQ(d.paramNames.Length(), 1u);
  EXPECT_EQ(d.paramNames[0], "id"_ns);
}

TEST(TestNoVarySearchParse, ExceptAllowlistExplicitBoolTrue)
{
  // params=?1 + except=(...) → Allowlist (same as bare params + except)
  auto d = Parse(R"(params=?1, except=("id"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::Allowlist);
  ASSERT_EQ(d.paramNames.Length(), 1u);
  EXPECT_EQ(d.paramNames[0], "id"_ns);
}

TEST(TestNoVarySearchParse, ExceptMultipleKeys)
{
  auto d = Parse(R"(params, except=("id" "type"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::Allowlist);
  ASSERT_EQ(d.paramNames.Length(), 2u);
}

TEST(TestNoVarySearchParse, KeyOrderTrue)
{
  // bare key-order → varyOnKeyOrder=false
  // https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#section-5.1-4
  auto d = Parse("key-order");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::ExactMatch);
  EXPECT_FALSE(d.varyOnKeyOrder);
}

TEST(TestNoVarySearchParse, KeyOrderExplicitTrue)
{
  // key-order=?1 (explicit boolean true) → varyOnKeyOrder=false
  auto d = Parse("key-order=?1");
  EXPECT_FALSE(d.varyOnKeyOrder);
}

TEST(TestNoVarySearchParse, KeyOrderExplicitFalse)
{
  // key-order=?0 → varyOnKeyOrder=true (order matters, explicit default)
  auto d = Parse("key-order=?0");
  EXPECT_TRUE(d.varyOnKeyOrder);
}

TEST(TestNoVarySearchParse, KeyOrderCombinedWithParams)
{
  auto d = Parse(R"(params=("utm"), key-order)");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::Blocklist);
  ASSERT_EQ(d.paramNames.Length(), 1u);
  EXPECT_EQ(d.paramNames[0], "utm"_ns);
  EXPECT_FALSE(d.varyOnKeyOrder);
}

TEST(TestNoVarySearchParse, SFExtensionParamsOnItemsIgnored)
{
  // Unknown SF parameters on items must be ignored
  auto d = Parse(R"(params=("a";unknown="x"))");
  EXPECT_EQ(d.paramsRule, NoVarySearchData::ParamsRule::Blocklist);
  ASSERT_EQ(d.paramNames.Length(), 1u);
  EXPECT_EQ(d.paramNames[0], "a"_ns);
}

// ---------------------------------------------------------------------------
// URLsAreEquivalentModuloVariationConfig — parametrized tests
// ---------------------------------------------------------------------------

struct EquivTestData {
  const char* description;
  const char* urlA;
  const char* urlB;
  const char* header;
  bool expected;
};

static const EquivTestData kEquivTests[] = {
    // ExactMatch (no header)
    {"ExactMatch: identical URLs", "https://example.com/page?a=1&b=2",
     "https://example.com/page?a=1&b=2", "", true},
    {"ExactMatch: different query value", "https://example.com/page?a=1&b=2",
     "https://example.com/page?a=1&b=3", "", false},

    // Structural mismatches always return false regardless of NVS
    {"Different scheme", "https://example.com/page?a=1",
     "http://example.com/page?a=1", "params", false},
    {"Different host", "https://example.com/page?a=1",
     "https://other.com/page?a=1", "params", false},
    {"Different path", "https://example.com/page?a=1",
     "https://example.com/other?a=1", "params", false},

    // Blocklist: params=("a")
    {"Blocklist: ignored param differs → HIT", "https://example.com/p?a=1&b=2",
     "https://example.com/p?a=99&b=2", R"(params=("a"))", true},
    {"Blocklist: non-listed param differs → MISS",
     "https://example.com/p?a=1&b=2", "https://example.com/p?a=1&b=99",
     R"(params=("a"))", false},
    {"Blocklist: multiple ignored params", "https://example.com/p?a=1&b=2",
     "https://example.com/p?a=9&b=8", R"(params=("a" "b"))", true},

    // Blocklist: many params in query string, only some in NVS list
    {"Blocklist: many params, only listed ones ignored → HIT",
     "https://example.com/p?a=1&b=2&c=3&d=4&e=5",
     "https://example.com/p?a=9&b=8&c=3&d=4&e=5", R"(params=("a" "b"))", true},
    {"Blocklist: many params, non-listed param differs → MISS",
     "https://example.com/p?a=1&b=2&c=3&d=4&e=5",
     "https://example.com/p?a=9&b=8&c=3&d=4&e=99", R"(params=("a" "b"))",
     false},

    // Blocklist: params in query don't match any NVS listed params
    {"Blocklist: no query params match NVS list → treated as ExactMatch",
     "https://example.com/p?x=1&y=2", "https://example.com/p?x=1&y=3",
     R"(params=("a" "b"))", false},
    {"Blocklist: no query params match NVS list, identical → HIT",
     "https://example.com/p?x=1&y=2", "https://example.com/p?x=1&y=2",
     R"(params=("a" "b"))", true},

    // IgnoreAll: params
    {"IgnoreAll: completely different params → HIT",
     "https://example.com/p?a=1&b=2", "https://example.com/p?x=9&y=8", "params",
     true},
    {"IgnoreAll: no query vs query → HIT", "https://example.com/p",
     "https://example.com/p?a=1&b=2", "params", true},
    {"IgnoreAll: params=?1 explicit → HIT", "https://example.com/p?a=1",
     "https://example.com/p?b=99", "params=?1", true},

    // Allowlist: params, except=("id")
    {"Allowlist: kept param same → HIT",
     "https://example.com/p?id=42&noise=abc",
     "https://example.com/p?id=42&noise=xyz", R"(params, except=("id"))", true},
    {"Allowlist: kept param differs → MISS", "https://example.com/p?id=42",
     "https://example.com/p?id=99", R"(params, except=("id"))", false},
    {"Allowlist: params=?1 + except, kept param same → HIT",
     "https://example.com/p?id=42&noise=abc",
     "https://example.com/p?id=42&noise=xyz", R"(params=?1, except=("id"))",
     true},

    // key-order
    {"key-order: reordered params → HIT", "https://example.com/p?a=1&b=2",
     "https://example.com/p?b=2&a=1", "key-order", true},
    {"key-order: reordered but value differs → MISS",
     "https://example.com/p?a=1&b=2", "https://example.com/p?b=9&a=1",
     "key-order", false},
    {"key-order=?0: reordered → MISS", "https://example.com/p?a=1&b=2",
     "https://example.com/p?b=2&a=1", "key-order=?0", false},
    {"key-order=?1: reordered → HIT", "https://example.com/p?a=1&b=2",
     "https://example.com/p?b=2&a=1", "key-order=?1", true},
    {"key-order: extra param → MISS", "https://example.com/p?a=1&b=2",
     "https://example.com/p?a=1&b=2&c=3", "key-order", false},

    // Combined
    {"Combined params+key-order: ignored param and order both differ → HIT",
     "https://example.com/p?utm=x&b=2&a=1",
     "https://example.com/p?a=1&b=2&utm=y", R"(params=("utm"), key-order)",
     true},

    // Invalid SF → ExactMatch fallback
    {"Invalid SF (params inner list + except) → ExactMatch → MISS",
     "https://example.com/p?a=1", "https://example.com/p?a=2",
     R"(params=("a"), except=("b"))", false},

    // multi-value params
    {"key-order: multi-value, same values reordered by key → HIT",
     "https://example.com/p?a=1&a=2&b=3", "https://example.com/p?b=3&a=1&a=2",
     "key-order", true},
    {"key-order: multi-value, values for same key in different order → MISS",
     "https://example.com/p?a=1&a=2", "https://example.com/p?a=2&a=1",
     "key-order", false},
};

class TestNoVarySearchEquivalence
    : public testing::TestWithParam<EquivTestData> {};

TEST_P(TestNoVarySearchEquivalence, Check) {
  const EquivTestData& t = GetParam();
  EXPECT_EQ(Equiv(t.urlA, t.urlB, t.header), t.expected) << t.description;
  // Equivalence must be symmetric
  EXPECT_EQ(Equiv(t.urlB, t.urlA, t.header), t.expected)
      << t.description << " (symmetric)";
}

INSTANTIATE_TEST_SUITE_P(TestNoVarySearch, TestNoVarySearchEquivalence,
                         testing::ValuesIn(kEquivTests));

Messung V0.5 in Prozent
C=85 H=96 G=90

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-09-28) ¤

*Bot Zugriff






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.