tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestUseAsDictionary.cpp (6419B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include <ostream>
      6 
      7 #include "gtest/gtest-param-test.h"
      8 #include "gtest/gtest.h"
      9 
     10 #include "mozilla/gtest/MozAssertions.h"
     11 #include "nsNetUtil.h"
     12 
     13 using namespace mozilla::net;
     14 
     15 struct TestData {
     16  bool mResult;
     17  const nsCString mHeader;
     18  // output to match:
     19  const nsCString mMatchVal;
     20  const nsCString mMatchIdVal;
     21  const nsCString mTypeVal;
     22  // matchDestVal ends with ""_ns
     23  const nsCString mMatchDestVal[5];
     24 };
     25 
     26 TEST(TestUseAsDictionary, Match)
     27 {
     28  // Note: we're not trying to test Structured Fields
     29  // (https://datatracker.ietf.org/doc/html/rfc8941) here, but the data within
     30  // it, so generally we aren't looking for format errors
     31  const struct TestData gTestArray[] = {
     32      {true,
     33       "match=\"/app/*/main.js\""_ns,
     34       "/app/*/main.js"_ns,
     35       ""_ns,
     36       ""_ns,
     37       {""_ns}},
     38      {true,
     39       "match=\"/app/*/main.js\", id=\"some_id\""_ns,
     40       "/app/*/main.js"_ns,
     41       "some_id"_ns,
     42       ""_ns,
     43       {""_ns}},
     44      // match= is required
     45      {false, "id=\"some_id\""_ns, ""_ns, "some_id"_ns, ""_ns, {""_ns}},
     46      {true,
     47       "match=\"/app/*/main.js\", id=\"some_id\", type=raw"_ns,
     48       "/app/*/main.js"_ns,
     49       "some_id"_ns,
     50       "raw"_ns,
     51       {""_ns}},
     52      // only raw is supported for type
     53      {false,
     54       "match=\"/app/*/main.js\", id=\"some_id\", type=not_raw"_ns,
     55       "/app/*/main.js"_ns,
     56       "some_id"_ns,
     57       "raw"_ns,
     58       {""_ns}},
     59      {true,
     60       "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\")"_ns,
     61       "/app/*/main.js"_ns,
     62       "some_id"_ns,
     63       ""_ns,
     64       {"style"_ns, ""_ns}},
     65      {true,
     66       "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\"), type=raw"_ns,
     67       "/app/*/main.js"_ns,
     68       "some_id"_ns,
     69       "raw"_ns,
     70       {"style"_ns, ""_ns}},
     71      {true,
     72       "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\" \"document\"), type=raw"_ns,
     73       "/app/*/main.js"_ns,
     74       "some_id"_ns,
     75       "raw"_ns,
     76       {"style"_ns, "document"_ns, ""_ns}},
     77      // adding the comma after style is a syntax error for structured fields
     78      {false,
     79       "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\", \"document\"), type=raw"_ns,
     80       "/app/*/main.js"_ns,
     81       "some_id"_ns,
     82       "raw"_ns,
     83       {"style"_ns, "document"_ns, ""_ns}},
     84      // --- Additional tests for spec compliance and edge cases ---
     85      // 1. Missing quotes around match value
     86      {false,
     87       "match=/app/*/main.js, id=\"id1\""_ns,
     88       ""_ns,
     89       "id1"_ns,
     90       ""_ns,
     91       {""_ns}},
     92      // 2. Extra unknown parameter
     93      {true,
     94       "match=\"/foo.js\", foo=bar"_ns,
     95       "/foo.js"_ns,
     96       ""_ns,
     97       ""_ns,
     98       {""_ns}},
     99      // 3. Whitespace variations
    100      {true,
    101       "  match=\"/foo.js\" , id=\"id2\"  "_ns,
    102       "/foo.js"_ns,
    103       "id2"_ns,
    104       ""_ns,
    105       {""_ns}},
    106      // 4. Empty match value
    107      {false, "match=\"\""_ns, ""_ns, ""_ns, ""_ns, {""_ns}},
    108      // 5. Duplicate match parameter (should use the last)
    109      {true,
    110       "match=\"/foo.js\", match=\"/bar.js\""_ns,
    111       "/bar.js"_ns,
    112       ""_ns,
    113       ""_ns,
    114       {""_ns}},
    115      // 6. Duplicate id parameter (should use the last)
    116      {true,
    117       "match=\"/foo.js\", id=\"id1\", id=\"id2\""_ns,
    118       "/foo.js"_ns,
    119       "id2"_ns,
    120       ""_ns,
    121       {""_ns}},
    122      // 7. Parameter order: id before match
    123      {true,
    124       "id=\"id3\", match=\"/foo.js\""_ns,
    125       "/foo.js"_ns,
    126       "id3"_ns,
    127       ""_ns,
    128       {""_ns}},
    129      // 8. Non-raw type (should fail)
    130      {false,
    131       "match=\"/foo.js\", type=compressed"_ns,
    132       "/foo.js"_ns,
    133       ""_ns,
    134       "raw"_ns,
    135       {""_ns}},
    136      // 9. Empty header
    137      {false, ""_ns, ""_ns, ""_ns, ""_ns, {""_ns}},
    138      // 10. match-dest with empty list
    139      {true,
    140       "match=\"/foo.js\", match-dest=()"_ns,
    141       "/foo.js"_ns,
    142       ""_ns,
    143       ""_ns,
    144       {""_ns}},
    145      // 11. match-dest with whitespace and multiple values
    146      {true,
    147       "match=\"/foo.js\", match-dest=( \"a\"  \"b\"  )"_ns,
    148       "/foo.js"_ns,
    149       ""_ns,
    150       ""_ns,
    151       {"a"_ns, "b"_ns, ""_ns}},
    152      // 12. match-dest with invalid value (missing quotes)
    153      {false,
    154       "match=\"/foo.js\", match-dest=(a)"_ns,
    155       "/foo.js"_ns,
    156       ""_ns,
    157       ""_ns,
    158       {""_ns}},
    159      // 13. match-dest with duplicate values
    160      {true,
    161       "match=\"/foo.js\", match-dest=(\"a\" \"a\")"_ns,
    162       "/foo.js"_ns,
    163       ""_ns,
    164       ""_ns,
    165       {"a"_ns, "a"_ns, ""_ns}},
    166      // 14. Case sensitivity: type=RAW (should fail, only 'raw' allowed)
    167      {false,
    168       "match=\"/foo.js\", type=RAW"_ns,
    169       "/foo.js"_ns,
    170       ""_ns,
    171       "raw"_ns,
    172       {""_ns}},
    173 
    174      // Note: Structured Fields requires all input to be ASCII
    175 
    176      // 18. match-dest with trailing whitespace
    177      {true,
    178       "match=\"/foo.js\", match-dest=(\"a\" )"_ns,
    179       "/foo.js"_ns,
    180       ""_ns,
    181       ""_ns,
    182       {"a"_ns, ""_ns}},
    183      // 19. match-dest with only whitespace in list (should be empty)
    184      {true,
    185       "match=\"/foo.js\", match-dest=(   )"_ns,
    186       "/foo.js"_ns,
    187       ""_ns,
    188       ""_ns,
    189       {""_ns}},
    190      // 20. match-dest with comma and whitespace (invalid)
    191      {false,
    192       "match=\"/foo.js\", match-dest=(\"a\", \"b\")"_ns,
    193       "/foo.js"_ns,
    194       ""_ns,
    195       ""_ns,
    196       {"a"_ns, "b"_ns, ""_ns}},
    197  };
    198 
    199  for (auto& test : gTestArray) {
    200    nsCString match, matchId, type;
    201    nsTArray<nsCString> matchDest;
    202    nsTArray<nsCString> matchDestVal;
    203 
    204    for (auto& dest : test.mMatchDestVal) {
    205      if (dest.IsEmpty()) {
    206        break;
    207      }
    208      matchDestVal.AppendElement(dest);
    209    }
    210 
    211    fprintf(stderr, "Testing %s\n", test.mHeader.get());
    212    ASSERT_EQ(
    213        NS_ParseUseAsDictionary(test.mHeader, match, matchId, matchDest, type),
    214        test.mResult);
    215 
    216    if (test.mResult) {
    217      ASSERT_EQ(match, test.mMatchVal);
    218      ASSERT_EQ(matchId, test.mMatchIdVal);
    219      ASSERT_EQ(matchDest.Length(), matchDestVal.Length());
    220      for (size_t i = 0; i < matchDest.Length(); i++) {
    221        ASSERT_EQ(matchDest[i], matchDestVal[i]);
    222      }
    223      ASSERT_EQ(type, test.mTypeVal);
    224    }
    225  }
    226 }