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 }