tor-browser

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

TestMozURL.cpp (9410B)


      1 #include "gtest/gtest.h"
      2 #include "gtest/MozGTestBench.h"  // For MOZ_GTEST_BENCH
      3 
      4 #include <regex>
      5 #include "json/json.h"
      6 #include "json/reader.h"
      7 #include "nsString.h"
      8 #include "mozilla/net/MozURL.h"
      9 #include "nsCOMPtr.h"
     10 #include "nsDirectoryServiceDefs.h"
     11 #include "nsNetUtil.h"
     12 #include "nsIFile.h"
     13 #include "nsIURI.h"
     14 #include "nsStreamUtils.h"
     15 #include "mozilla/BasePrincipal.h"
     16 
     17 using namespace mozilla;
     18 using namespace mozilla::net;
     19 
     20 TEST(TestMozURL, Getters)
     21 {
     22  nsAutoCString href("http://user:pass@example.com/path?query#ref");
     23  RefPtr<MozURL> url;
     24  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
     25 
     26  ASSERT_TRUE(url->Scheme().EqualsLiteral("http"));
     27 
     28  ASSERT_TRUE(url->Spec() == href);
     29 
     30  ASSERT_TRUE(url->Username().EqualsLiteral("user"));
     31 
     32  ASSERT_TRUE(url->Password().EqualsLiteral("pass"));
     33 
     34  ASSERT_TRUE(url->Host().EqualsLiteral("example.com"));
     35 
     36  ASSERT_TRUE(url->FilePath().EqualsLiteral("/path"));
     37 
     38  ASSERT_TRUE(url->Query().EqualsLiteral("query"));
     39 
     40  ASSERT_TRUE(url->Ref().EqualsLiteral("ref"));
     41 
     42  url = nullptr;
     43  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), ""_ns), NS_ERROR_MALFORMED_URI);
     44  ASSERT_EQ(url, nullptr);
     45 }
     46 
     47 TEST(TestMozURL, MutatorChain)
     48 {
     49  nsAutoCString href("http://user:pass@example.com/path?query#ref");
     50  RefPtr<MozURL> url;
     51  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
     52  nsAutoCString out;
     53 
     54  RefPtr<MozURL> url2;
     55  ASSERT_EQ(url->Mutate()
     56                .SetScheme("https"_ns)
     57                .SetUsername("newuser"_ns)
     58                .SetPassword("newpass"_ns)
     59                .SetHostname("test"_ns)
     60                .SetFilePath("new/file/path"_ns)
     61                .SetQuery("bla"_ns)
     62                .SetRef("huh"_ns)
     63                .Finalize(getter_AddRefs(url2)),
     64            NS_OK);
     65 
     66  ASSERT_TRUE(url2->Spec().EqualsLiteral(
     67      "https://newuser:newpass@test/new/file/path?bla#huh"));
     68 }
     69 
     70 TEST(TestMozURL, MutatorFinalizeTwice)
     71 {
     72  nsAutoCString href("http://user:pass@example.com/path?query#ref");
     73  RefPtr<MozURL> url;
     74  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
     75  nsAutoCString out;
     76 
     77  RefPtr<MozURL> url2;
     78  MozURL::Mutator mut = url->Mutate();
     79  mut.SetScheme("https"_ns);  // Change the scheme to https
     80  ASSERT_EQ(mut.Finalize(getter_AddRefs(url2)), NS_OK);
     81  ASSERT_TRUE(url2->Spec().EqualsLiteral(
     82      "https://user:pass@example.com/path?query#ref"));
     83 
     84  // Test that a second call to Finalize will result in an error code
     85  url2 = nullptr;
     86  ASSERT_EQ(mut.Finalize(getter_AddRefs(url2)), NS_ERROR_NOT_AVAILABLE);
     87  ASSERT_EQ(url2, nullptr);
     88 }
     89 
     90 TEST(TestMozURL, MutatorErrorStatus)
     91 {
     92  nsAutoCString href("http://user:pass@example.com/path?query#ref");
     93  RefPtr<MozURL> url;
     94  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
     95  nsAutoCString out;
     96 
     97  // Test that trying to set the scheme to a bad value will get you an error
     98  MozURL::Mutator mut = url->Mutate();
     99  mut.SetScheme("!@#$%^&*("_ns);
    100  ASSERT_EQ(mut.GetStatus(), NS_ERROR_MALFORMED_URI);
    101 
    102  // Test that the mutator will not work after one faulty operation
    103  mut.SetScheme("test"_ns);
    104  ASSERT_EQ(mut.GetStatus(), NS_ERROR_MALFORMED_URI);
    105 }
    106 
    107 TEST(TestMozURL, InitWithBase)
    108 {
    109  nsAutoCString href("https://example.net/a/b.html");
    110  RefPtr<MozURL> url;
    111  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
    112 
    113  ASSERT_TRUE(url->Spec().EqualsLiteral("https://example.net/a/b.html"));
    114 
    115  RefPtr<MozURL> url2;
    116  ASSERT_EQ(MozURL::Init(getter_AddRefs(url2), "c.png"_ns, url), NS_OK);
    117 
    118  ASSERT_TRUE(url2->Spec().EqualsLiteral("https://example.net/a/c.png"));
    119 }
    120 
    121 TEST(TestMozURL, Path)
    122 {
    123  nsAutoCString href("about:blank");
    124  RefPtr<MozURL> url;
    125  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
    126 
    127  ASSERT_TRUE(url->Spec().EqualsLiteral("about:blank"));
    128 
    129  ASSERT_TRUE(url->Scheme().EqualsLiteral("about"));
    130 
    131  ASSERT_TRUE(url->FilePath().EqualsLiteral("blank"));
    132 }
    133 
    134 TEST(TestMozURL, HostPort)
    135 {
    136  nsAutoCString href("https://user:pass@example.net:1234/path?query#ref");
    137  RefPtr<MozURL> url;
    138  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
    139 
    140  ASSERT_TRUE(url->HostPort().EqualsLiteral("example.net:1234"));
    141 
    142  RefPtr<MozURL> url2;
    143  url->Mutate().SetHostPort("test:321"_ns).Finalize(getter_AddRefs(url2));
    144 
    145  ASSERT_TRUE(url2->HostPort().EqualsLiteral("test:321"));
    146  ASSERT_TRUE(
    147      url2->Spec().EqualsLiteral("https://user:pass@test:321/path?query#ref"));
    148 
    149  href.Assign("https://user:pass@example.net:443/path?query#ref");
    150  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
    151  ASSERT_TRUE(url->HostPort().EqualsLiteral("example.net"));
    152  ASSERT_EQ(url->Port(), -1);
    153 }
    154 
    155 TEST(TestMozURL, Origin)
    156 {
    157  nsAutoCString href("https://user:pass@example.net:1234/path?query#ref");
    158  RefPtr<MozURL> url;
    159  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
    160 
    161  nsAutoCString out;
    162  url->Origin(out);
    163  ASSERT_TRUE(out.EqualsLiteral("https://example.net:1234"));
    164 
    165  RefPtr<MozURL> url2;
    166  ASSERT_EQ(MozURL::Init(getter_AddRefs(url2), "file:///tmp/foo"_ns), NS_OK);
    167  url2->Origin(out);
    168  ASSERT_TRUE(out.EqualsLiteral("file:///tmp/foo"));
    169 
    170  RefPtr<MozURL> url3;
    171  ASSERT_EQ(
    172      MozURL::Init(getter_AddRefs(url3),
    173                   nsLiteralCString(
    174                       "moz-extension://53711a8f-65ed-e742-9671-1f02e267c0bc/"
    175                       "foo/bar.html")),
    176      NS_OK);
    177  url3->Origin(out);
    178  ASSERT_TRUE(out.EqualsLiteral(
    179      "moz-extension://53711a8f-65ed-e742-9671-1f02e267c0bc"));
    180 
    181  RefPtr<MozURL> url4;
    182  ASSERT_EQ(MozURL::Init(getter_AddRefs(url4), "resource://foo/bar.html"_ns),
    183            NS_OK);
    184  url4->Origin(out);
    185  ASSERT_TRUE(out.EqualsLiteral("resource://foo"));
    186 
    187  RefPtr<MozURL> url5;
    188  ASSERT_EQ(MozURL::Init(getter_AddRefs(url5), "about:home"_ns), NS_OK);
    189  url5->Origin(out);
    190  ASSERT_TRUE(out.EqualsLiteral("about:home"));
    191 }
    192 
    193 namespace {
    194 
    195 bool OriginMatchesExpectedOrigin(const nsACString& aOrigin,
    196                                 const nsACString& aExpectedOrigin) {
    197  if (aExpectedOrigin.Equals("null") &&
    198      StringBeginsWith(aOrigin, "moz-nullprincipal"_ns)) {
    199    return true;
    200  }
    201  return aOrigin == aExpectedOrigin;
    202 }
    203 
    204 void CheckOrigin(const nsACString& aSpec, const nsACString& aBase,
    205                 const nsACString& aOrigin) {
    206  nsCOMPtr<nsIURI> baseUri;
    207  nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase);
    208  ASSERT_EQ(rv, NS_OK);
    209 
    210  nsCOMPtr<nsIURI> uri;
    211  rv = NS_NewURI(getter_AddRefs(uri), aSpec, nullptr, baseUri);
    212  ASSERT_EQ(rv, NS_OK);
    213 
    214  OriginAttributes attrs;
    215 
    216  nsCOMPtr<nsIPrincipal> principal =
    217      BasePrincipal::CreateContentPrincipal(uri, attrs);
    218  ASSERT_TRUE(principal);
    219 
    220  nsCString origin;
    221  rv = principal->GetOriginNoSuffix(origin);
    222  ASSERT_EQ(rv, NS_OK);
    223 
    224  EXPECT_TRUE(OriginMatchesExpectedOrigin(origin, aOrigin));
    225 
    226  nsCString baseDomain;
    227  rv = principal->GetBaseDomain(baseDomain);
    228 
    229  RefPtr<MozURL> baseUrl;
    230  ASSERT_EQ(MozURL::Init(getter_AddRefs(baseUrl), aBase), NS_OK);
    231 
    232  RefPtr<MozURL> url;
    233  ASSERT_EQ(MozURL::Init(getter_AddRefs(url), aSpec, baseUrl), NS_OK);
    234 
    235  url->Origin(origin);
    236 
    237  EXPECT_TRUE(OriginMatchesExpectedOrigin(origin, aOrigin));
    238 }
    239 
    240 }  // namespace
    241 
    242 TEST(TestMozURL, UrlTestData)
    243 {
    244  nsCOMPtr<nsIFile> file;
    245  nsresult rv =
    246      NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(file));
    247  ASSERT_EQ(rv, NS_OK);
    248 
    249  rv = file->Append(u"urltestdata.json"_ns);
    250  ASSERT_EQ(rv, NS_OK);
    251 
    252  bool exists;
    253  rv = file->Exists(&exists);
    254  ASSERT_EQ(rv, NS_OK);
    255 
    256  ASSERT_TRUE(exists);
    257 
    258  nsCOMPtr<nsIInputStream> stream;
    259  rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
    260  ASSERT_EQ(rv, NS_OK);
    261 
    262  nsCOMPtr<nsIInputStream> bufferedStream;
    263  rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
    264                                 stream.forget(), 4096);
    265  ASSERT_EQ(rv, NS_OK);
    266 
    267  nsCString data;
    268  rv = NS_ConsumeStream(bufferedStream, UINT32_MAX, data);
    269  ASSERT_EQ(rv, NS_OK);
    270 
    271  Json::Value root;
    272  Json::CharReaderBuilder builder;
    273  std::unique_ptr<Json::CharReader> const reader(builder.newCharReader());
    274  ASSERT_TRUE(
    275      reader->parse(data.BeginReading(), data.EndReading(), &root, nullptr));
    276  ASSERT_TRUE(root.isArray());
    277 
    278  for (auto& item : root) {
    279    if (!item.isObject()) {
    280      continue;
    281    }
    282 
    283    const Json::Value& skip = item["skip"];
    284    ASSERT_TRUE(skip.isNull() || skip.isBool());
    285    if (skip.isBool() && skip.asBool()) {
    286      continue;
    287    }
    288 
    289    const Json::Value& failure = item["failure"];
    290    ASSERT_TRUE(failure.isNull() || failure.isBool());
    291    if (failure.isBool() && failure.asBool()) {
    292      continue;
    293    }
    294 
    295    const Json::Value& origin = item["origin"];
    296    ASSERT_TRUE(origin.isNull() || origin.isString());
    297    if (origin.isNull()) {
    298      continue;
    299    }
    300    const char* originBegin;
    301    const char* originEnd;
    302    origin.getString(&originBegin, &originEnd);
    303 
    304    auto baseCString = nsDependentCString("about:blank");
    305    const Json::Value& base = item["base"];
    306    if (!base.isNull()) {
    307      const char* baseBegin;
    308      const char* baseEnd;
    309      base.getString(&baseBegin, &baseEnd);
    310      baseCString.Assign(nsDependentCSubstring(baseBegin, baseEnd));
    311    }
    312 
    313    const Json::Value& input = item["input"];
    314    ASSERT_TRUE(input.isString());
    315    const char* inputBegin;
    316    const char* inputEnd;
    317    input.getString(&inputBegin, &inputEnd);
    318 
    319    CheckOrigin(nsDependentCString(inputBegin, inputEnd), baseCString,
    320                nsDependentCString(originBegin, originEnd));
    321  }
    322 }