323 lines
9.2 KiB
C++
323 lines
9.2 KiB
C++
#include "gtest/gtest.h"
|
|
#include "gtest/MozGTestBench.h" // For MOZ_GTEST_BENCH
|
|
|
|
#include <regex>
|
|
#include "json/json.h"
|
|
#include "json/reader.h"
|
|
#include "mozilla/TextUtils.h"
|
|
#include "nsString.h"
|
|
#include "mozilla/net/MozURL.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsDirectoryServiceDefs.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsIFile.h"
|
|
#include "nsIURI.h"
|
|
#include "nsStreamUtils.h"
|
|
#include "mozilla/BasePrincipal.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::net;
|
|
|
|
TEST(TestMozURL, Getters)
|
|
{
|
|
nsAutoCString href("http://user:pass@example.com/path?query#ref");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
|
|
ASSERT_TRUE(url->Scheme().EqualsLiteral("http"));
|
|
|
|
ASSERT_TRUE(url->Spec() == href);
|
|
|
|
ASSERT_TRUE(url->Username().EqualsLiteral("user"));
|
|
|
|
ASSERT_TRUE(url->Password().EqualsLiteral("pass"));
|
|
|
|
ASSERT_TRUE(url->Host().EqualsLiteral("example.com"));
|
|
|
|
ASSERT_TRUE(url->FilePath().EqualsLiteral("/path"));
|
|
|
|
ASSERT_TRUE(url->Query().EqualsLiteral("query"));
|
|
|
|
ASSERT_TRUE(url->Ref().EqualsLiteral("ref"));
|
|
|
|
url = nullptr;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), ""_ns), NS_ERROR_MALFORMED_URI);
|
|
ASSERT_EQ(url, nullptr);
|
|
}
|
|
|
|
TEST(TestMozURL, MutatorChain)
|
|
{
|
|
nsAutoCString href("http://user:pass@example.com/path?query#ref");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
nsAutoCString out;
|
|
|
|
RefPtr<MozURL> url2;
|
|
ASSERT_EQ(url->Mutate()
|
|
.SetScheme("https"_ns)
|
|
.SetUsername("newuser"_ns)
|
|
.SetPassword("newpass"_ns)
|
|
.SetHostname("test"_ns)
|
|
.SetFilePath("new/file/path"_ns)
|
|
.SetQuery("bla"_ns)
|
|
.SetRef("huh"_ns)
|
|
.Finalize(getter_AddRefs(url2)),
|
|
NS_OK);
|
|
|
|
ASSERT_TRUE(url2->Spec().EqualsLiteral(
|
|
"https://newuser:newpass@test/new/file/path?bla#huh"));
|
|
}
|
|
|
|
TEST(TestMozURL, MutatorFinalizeTwice)
|
|
{
|
|
nsAutoCString href("http://user:pass@example.com/path?query#ref");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
nsAutoCString out;
|
|
|
|
RefPtr<MozURL> url2;
|
|
MozURL::Mutator mut = url->Mutate();
|
|
mut.SetScheme("https"_ns); // Change the scheme to https
|
|
ASSERT_EQ(mut.Finalize(getter_AddRefs(url2)), NS_OK);
|
|
ASSERT_TRUE(url2->Spec().EqualsLiteral(
|
|
"https://user:pass@example.com/path?query#ref"));
|
|
|
|
// Test that a second call to Finalize will result in an error code
|
|
url2 = nullptr;
|
|
ASSERT_EQ(mut.Finalize(getter_AddRefs(url2)), NS_ERROR_NOT_AVAILABLE);
|
|
ASSERT_EQ(url2, nullptr);
|
|
}
|
|
|
|
TEST(TestMozURL, MutatorErrorStatus)
|
|
{
|
|
nsAutoCString href("http://user:pass@example.com/path?query#ref");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
nsAutoCString out;
|
|
|
|
// Test that trying to set the scheme to a bad value will get you an error
|
|
MozURL::Mutator mut = url->Mutate();
|
|
mut.SetScheme("!@#$%^&*("_ns);
|
|
ASSERT_EQ(mut.GetStatus(), NS_ERROR_MALFORMED_URI);
|
|
|
|
// Test that the mutator will not work after one faulty operation
|
|
mut.SetScheme("test"_ns);
|
|
ASSERT_EQ(mut.GetStatus(), NS_ERROR_MALFORMED_URI);
|
|
}
|
|
|
|
TEST(TestMozURL, InitWithBase)
|
|
{
|
|
nsAutoCString href("https://example.net/a/b.html");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
|
|
ASSERT_TRUE(url->Spec().EqualsLiteral("https://example.net/a/b.html"));
|
|
|
|
RefPtr<MozURL> url2;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url2), "c.png"_ns, url), NS_OK);
|
|
|
|
ASSERT_TRUE(url2->Spec().EqualsLiteral("https://example.net/a/c.png"));
|
|
}
|
|
|
|
TEST(TestMozURL, Path)
|
|
{
|
|
nsAutoCString href("about:blank");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
|
|
ASSERT_TRUE(url->Spec().EqualsLiteral("about:blank"));
|
|
|
|
ASSERT_TRUE(url->Scheme().EqualsLiteral("about"));
|
|
|
|
ASSERT_TRUE(url->FilePath().EqualsLiteral("blank"));
|
|
}
|
|
|
|
TEST(TestMozURL, HostPort)
|
|
{
|
|
nsAutoCString href("https://user:pass@example.net:1234/path?query#ref");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
|
|
ASSERT_TRUE(url->HostPort().EqualsLiteral("example.net:1234"));
|
|
|
|
RefPtr<MozURL> url2;
|
|
url->Mutate().SetHostPort("test:321"_ns).Finalize(getter_AddRefs(url2));
|
|
|
|
ASSERT_TRUE(url2->HostPort().EqualsLiteral("test:321"));
|
|
ASSERT_TRUE(
|
|
url2->Spec().EqualsLiteral("https://user:pass@test:321/path?query#ref"));
|
|
|
|
href.Assign("https://user:pass@example.net:443/path?query#ref");
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
ASSERT_TRUE(url->HostPort().EqualsLiteral("example.net"));
|
|
ASSERT_EQ(url->Port(), -1);
|
|
}
|
|
|
|
TEST(TestMozURL, Origin)
|
|
{
|
|
nsAutoCString href("https://user:pass@example.net:1234/path?query#ref");
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), href), NS_OK);
|
|
|
|
nsAutoCString out;
|
|
url->Origin(out);
|
|
ASSERT_TRUE(out.EqualsLiteral("https://example.net:1234"));
|
|
|
|
RefPtr<MozURL> url2;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url2), "file:///tmp/foo"_ns), NS_OK);
|
|
url2->Origin(out);
|
|
ASSERT_TRUE(out.EqualsLiteral("file:///tmp/foo"));
|
|
|
|
RefPtr<MozURL> url3;
|
|
ASSERT_EQ(
|
|
MozURL::Init(getter_AddRefs(url3),
|
|
nsLiteralCString(
|
|
"moz-extension://53711a8f-65ed-e742-9671-1f02e267c0bc/"
|
|
"foo/bar.html")),
|
|
NS_OK);
|
|
url3->Origin(out);
|
|
ASSERT_TRUE(out.EqualsLiteral(
|
|
"moz-extension://53711a8f-65ed-e742-9671-1f02e267c0bc"));
|
|
|
|
RefPtr<MozURL> url4;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url4), "resource://foo/bar.html"_ns),
|
|
NS_OK);
|
|
url4->Origin(out);
|
|
ASSERT_TRUE(out.EqualsLiteral("resource://foo"));
|
|
|
|
RefPtr<MozURL> url5;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url5), "about:home"_ns), NS_OK);
|
|
url5->Origin(out);
|
|
ASSERT_TRUE(out.EqualsLiteral("about:home"));
|
|
}
|
|
|
|
namespace {
|
|
|
|
bool OriginMatchesExpectedOrigin(const nsACString& aOrigin,
|
|
const nsACString& aExpectedOrigin) {
|
|
if (aExpectedOrigin.Equals("null") &&
|
|
StringBeginsWith(aOrigin, "moz-nullprincipal"_ns)) {
|
|
return true;
|
|
}
|
|
return aOrigin == aExpectedOrigin;
|
|
}
|
|
|
|
void CheckOrigin(const nsACString& aSpec, const nsACString& aBase,
|
|
const nsACString& aOrigin) {
|
|
nsCOMPtr<nsIURI> baseUri;
|
|
nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = NS_NewURI(getter_AddRefs(uri), aSpec, nullptr, baseUri);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
OriginAttributes attrs;
|
|
|
|
nsCOMPtr<nsIPrincipal> principal =
|
|
BasePrincipal::CreateContentPrincipal(uri, attrs);
|
|
ASSERT_TRUE(principal);
|
|
|
|
nsCString origin;
|
|
rv = principal->GetOriginNoSuffix(origin);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
EXPECT_TRUE(OriginMatchesExpectedOrigin(origin, aOrigin));
|
|
|
|
nsCString baseDomain;
|
|
rv = principal->GetBaseDomain(baseDomain);
|
|
|
|
RefPtr<MozURL> baseUrl;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(baseUrl), aBase), NS_OK);
|
|
|
|
RefPtr<MozURL> url;
|
|
ASSERT_EQ(MozURL::Init(getter_AddRefs(url), aSpec, baseUrl), NS_OK);
|
|
|
|
url->Origin(origin);
|
|
|
|
EXPECT_TRUE(OriginMatchesExpectedOrigin(origin, aOrigin));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST(TestMozURL, UrlTestData)
|
|
{
|
|
nsCOMPtr<nsIFile> file;
|
|
nsresult rv =
|
|
NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(file));
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
rv = file->Append(u"urltestdata.json"_ns);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
bool exists;
|
|
rv = file->Exists(&exists);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
ASSERT_TRUE(exists);
|
|
|
|
nsCOMPtr<nsIInputStream> stream;
|
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
nsCOMPtr<nsIInputStream> bufferedStream;
|
|
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
|
|
stream.forget(), 4096);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
nsCString data;
|
|
rv = NS_ConsumeStream(bufferedStream, UINT32_MAX, data);
|
|
ASSERT_EQ(rv, NS_OK);
|
|
|
|
Json::Value root;
|
|
Json::CharReaderBuilder builder;
|
|
std::unique_ptr<Json::CharReader> const reader(builder.newCharReader());
|
|
ASSERT_TRUE(
|
|
reader->parse(data.BeginReading(), data.EndReading(), &root, nullptr));
|
|
ASSERT_TRUE(root.isArray());
|
|
|
|
for (auto& item : root) {
|
|
if (!item.isObject()) {
|
|
continue;
|
|
}
|
|
|
|
const Json::Value& skip = item["skip"];
|
|
ASSERT_TRUE(skip.isNull() || skip.isBool());
|
|
if (skip.isBool() && skip.asBool()) {
|
|
continue;
|
|
}
|
|
|
|
const Json::Value& failure = item["failure"];
|
|
ASSERT_TRUE(failure.isNull() || failure.isBool());
|
|
if (failure.isBool() && failure.asBool()) {
|
|
continue;
|
|
}
|
|
|
|
const Json::Value& origin = item["origin"];
|
|
ASSERT_TRUE(origin.isNull() || origin.isString());
|
|
if (origin.isNull()) {
|
|
continue;
|
|
}
|
|
const char* originBegin;
|
|
const char* originEnd;
|
|
origin.getString(&originBegin, &originEnd);
|
|
|
|
auto baseCString = nsDependentCString("about:blank");
|
|
const Json::Value& base = item["base"];
|
|
if (!base.isNull()) {
|
|
const char* baseBegin;
|
|
const char* baseEnd;
|
|
base.getString(&baseBegin, &baseEnd);
|
|
baseCString.Assign(nsDependentCSubstring(baseBegin, baseEnd));
|
|
}
|
|
|
|
const Json::Value& input = item["input"];
|
|
ASSERT_TRUE(input.isString());
|
|
const char* inputBegin;
|
|
const char* inputEnd;
|
|
input.getString(&inputBegin, &inputEnd);
|
|
|
|
CheckOrigin(nsDependentCString(inputBegin, inputEnd), baseCString,
|
|
nsDependentCString(originBegin, originEnd));
|
|
}
|
|
}
|