Bug 1687263: part 4) Defer and in some cases avoid removing spellchecking-ranges...
[gecko.git] / caps / BasePrincipal.cpp
blobccec8e35110d55fc70a77beb9aca09474f5f8574
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/BasePrincipal.h"
9 #include "nsDocShell.h"
11 #include "ExpandedPrincipal.h"
12 #include "nsNetUtil.h"
13 #include "nsContentUtils.h"
14 #include "nsIOService.h"
15 #include "nsIURIWithSpecialOrigin.h"
16 #include "nsScriptSecurityManager.h"
17 #include "nsServiceManagerUtils.h"
18 #include "nsAboutProtocolUtils.h"
19 #include "ThirdPartyUtil.h"
20 #include "mozilla/ContentPrincipal.h"
21 #include "mozilla/NullPrincipal.h"
22 #include "mozilla/dom/BlobURLProtocolHandler.h"
23 #include "mozilla/dom/ChromeUtils.h"
24 #include "mozilla/dom/ReferrerInfo.h"
25 #include "mozilla/dom/ToJSValue.h"
26 #include "mozilla/dom/nsMixedContentBlocker.h"
27 #include "mozilla/Components.h"
28 #include "mozilla/dom/StorageUtils.h"
29 #include "mozilla/dom/StorageUtils.h"
30 #include "nsIURL.h"
31 #include "nsEffectiveTLDService.h"
32 #include "nsIURIMutator.h"
33 #include "mozilla/StaticPrefs_permissions.h"
34 #include "nsIURIMutator.h"
35 #include "prnetdb.h"
36 #include "nsIURIFixup.h"
37 #include "mozilla/dom/StorageUtils.h"
38 #include "mozilla/ContentBlocking.h"
39 #include "nsPIDOMWindow.h"
40 #include "nsIURIMutator.h"
42 #include "json/json.h"
43 #include "nsSerializationHelper.h"
45 namespace mozilla {
47 BasePrincipal::BasePrincipal(PrincipalKind aKind,
48 const nsACString& aOriginNoSuffix,
49 const OriginAttributes& aOriginAttributes)
50 : mOriginNoSuffix(NS_Atomize(aOriginNoSuffix)),
51 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
52 mOriginAttributes(aOriginAttributes),
53 mKind(aKind),
54 mHasExplicitDomain(false) {}
56 BasePrincipal::BasePrincipal(BasePrincipal* aOther,
57 const OriginAttributes& aOriginAttributes)
58 : mOriginNoSuffix(aOther->mOriginNoSuffix),
59 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
60 mOriginAttributes(aOriginAttributes),
61 mKind(aOther->mKind),
62 mHasExplicitDomain(aOther->mHasExplicitDomain) {}
64 BasePrincipal::~BasePrincipal() = default;
66 NS_IMETHODIMP
67 BasePrincipal::GetOrigin(nsACString& aOrigin) {
68 nsresult rv = GetOriginNoSuffix(aOrigin);
69 NS_ENSURE_SUCCESS(rv, rv);
71 nsAutoCString suffix;
72 rv = GetOriginSuffix(suffix);
73 NS_ENSURE_SUCCESS(rv, rv);
74 aOrigin.Append(suffix);
75 return NS_OK;
78 NS_IMETHODIMP
79 BasePrincipal::GetAsciiOrigin(nsACString& aOrigin) {
80 aOrigin.Truncate();
81 nsCOMPtr<nsIURI> prinURI;
82 nsresult rv = GetURI(getter_AddRefs(prinURI));
83 if (NS_FAILED(rv) || !prinURI) {
84 return NS_ERROR_NOT_AVAILABLE;
86 return nsContentUtils::GetASCIIOrigin(prinURI, aOrigin);
89 NS_IMETHODIMP
90 BasePrincipal::GetHostPort(nsACString& aRes) {
91 aRes.Truncate();
92 nsCOMPtr<nsIURI> prinURI;
93 nsresult rv = GetURI(getter_AddRefs(prinURI));
94 if (NS_FAILED(rv) || !prinURI) {
95 return NS_OK;
97 return prinURI->GetHostPort(aRes);
100 NS_IMETHODIMP
101 BasePrincipal::GetHost(nsACString& aRes) {
102 aRes.Truncate();
103 nsCOMPtr<nsIURI> prinURI;
104 nsresult rv = GetURI(getter_AddRefs(prinURI));
105 if (NS_FAILED(rv) || !prinURI) {
106 return NS_OK;
108 return prinURI->GetHost(aRes);
111 NS_IMETHODIMP
112 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) {
113 mOriginNoSuffix->ToUTF8String(aOrigin);
114 return NS_OK;
117 NS_IMETHODIMP
118 BasePrincipal::GetSiteOrigin(nsACString& aSiteOrigin) {
119 nsresult rv = GetSiteOriginNoSuffix(aSiteOrigin);
120 NS_ENSURE_SUCCESS(rv, rv);
122 nsAutoCString suffix;
123 rv = GetOriginSuffix(suffix);
124 NS_ENSURE_SUCCESS(rv, rv);
125 aSiteOrigin.Append(suffix);
126 return NS_OK;
129 NS_IMETHODIMP
130 BasePrincipal::GetSiteOriginNoSuffix(nsACString& aSiteOrigin) {
131 return GetOriginNoSuffix(aSiteOrigin);
134 // Returns the inner Json::value of the serialized principal
135 // Example input and return values:
136 // Null principal:
137 // {"0":{"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}} ->
138 // {"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}
140 // Content principal:
141 // {"1":{"0":"https://mozilla.com"}} -> {"0":"https://mozilla.com"}
143 // Expanded principal:
144 // {"2":{"0":"<base64principal1>,<base64principal2>"}} ->
145 // {"0":"<base64principal1>,<base64principal2>"}
147 // System principal:
148 // {"3":{}} -> {}
149 // The aKey passed in also returns the corresponding PrincipalKind enum
151 // Warning: The Json::Value* pointer is into the aRoot object
152 static const Json::Value* GetPrincipalObject(const Json::Value& aRoot,
153 int& aOutPrincipalKind) {
154 const Json::Value::Members members = aRoot.getMemberNames();
155 // We only support one top level key in the object
156 if (members.size() != 1) {
157 return nullptr;
159 // members[0] here is the "0", "1", "2", "3" principalKind
160 // that is the top level of the serialized JSON principal
161 const std::string stringPrincipalKind = members[0];
163 // Next we take the string value from the JSON
164 // and convert it into the int for the BasePrincipal::PrincipalKind enum
166 // Verify that the key is within the valid range
167 int principalKind = std::stoi(stringPrincipalKind);
168 MOZ_ASSERT(BasePrincipal::eNullPrincipal == 0,
169 "We need to rely on 0 being a bounds check for the first "
170 "principal kind.");
171 if (principalKind < 0 || principalKind > BasePrincipal::eKindMax) {
172 return nullptr;
174 MOZ_ASSERT(principalKind == BasePrincipal::eNullPrincipal ||
175 principalKind == BasePrincipal::eContentPrincipal ||
176 principalKind == BasePrincipal::eExpandedPrincipal ||
177 principalKind == BasePrincipal::eSystemPrincipal);
178 aOutPrincipalKind = principalKind;
180 if (!aRoot[stringPrincipalKind].isObject()) {
181 return nullptr;
184 // Return the inner value of the principal object
185 return &aRoot[stringPrincipalKind];
188 // Accepts the JSON inner object without the wrapping principalKind
189 // (See GetPrincipalObject for the inner object response examples)
190 // Creates an array of KeyVal objects that are all defined on the principal
191 // Each principal type (null, content, expanded) has a KeyVal that stores the
192 // fields of the JSON
194 // This simplifies deserializing elsewhere as we do the checking for presence
195 // and string values here for the complete set of serializable keys that the
196 // corresponding principal supports.
198 // The KeyVal object has the following fields:
199 // - valueWasSerialized: is true if the deserialized JSON contained a string
200 // value
201 // - value: The string that was serialized for this key
202 // - key: an SerializableKeys enum value specific to the principal.
203 // For example content principal is an enum of: eURI, eDomain,
204 // eSuffix, eCSP
207 // Given an inner content principal:
208 // {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}
209 // | | | |
210 // ----------------------------- |
211 // | | |
212 // Key ----------------------
213 // |
214 // Value
216 // They Key "0" corresponds to ContentPrincipal::eURI
217 // They Key "1" corresponds to ContentPrincipal::eSuffix
218 template <typename T>
219 static nsTArray<typename T::KeyVal> GetJSONKeys(const Json::Value* aInput) {
220 int size = T::eMax + 1;
221 nsTArray<typename T::KeyVal> fields;
222 for (int i = 0; i != size; i++) {
223 typename T::KeyVal* field = fields.AppendElement();
224 // field->valueWasSerialized returns if the field was found in the
225 // deserialized code. This simplifies the consumers from having to check
226 // length.
227 field->valueWasSerialized = false;
228 field->key = static_cast<typename T::SerializableKeys>(i);
229 const std::string key = std::to_string(field->key);
230 if (aInput->isMember(key)) {
231 const Json::Value& val = (*aInput)[key];
232 if (val.isString()) {
233 field->value.Append(nsDependentCString(val.asCString()));
234 field->valueWasSerialized = true;
238 return fields;
241 // Takes a JSON string and parses it turning it into a principal of the
242 // corresponding type
244 // Given a content principal:
246 // inner JSON object
247 // |
248 // ---------------------------------------------------------
249 // | |
250 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
251 // | | | | |
252 // | ----------------------------- |
253 // | | | |
254 // PrincipalKind | | |
255 // | ----------------------------
256 // SerializableKeys |
257 // Value
259 // The string is first deserialized with jsoncpp to get the Json::Value of the
260 // object. The inner JSON object is parsed with GetPrincipalObject which returns
261 // a KeyVal array of the inner object's fields. PrincipalKind is returned by
262 // GetPrincipalObject which is then used to decide which principal
263 // implementation of FromProperties to call. The corresponding FromProperties
264 // call takes the KeyVal fields and turns it into a principal.
265 already_AddRefed<BasePrincipal> BasePrincipal::FromJSON(
266 const nsACString& aJSON) {
267 Json::Value root;
268 Json::CharReaderBuilder builder;
269 std::unique_ptr<Json::CharReader> const reader(builder.newCharReader());
270 bool parseSuccess =
271 reader->parse(aJSON.BeginReading(), aJSON.EndReading(), &root, nullptr);
272 if (!parseSuccess) {
273 MOZ_ASSERT(false,
274 "Unable to parse string as JSON to deserialize as a principal");
275 return nullptr;
278 int principalKind = -1;
279 const Json::Value* value = GetPrincipalObject(root, principalKind);
280 if (!value) {
281 #ifdef DEBUG
282 fprintf(stderr, "Unexpected JSON principal %s\n",
283 root.toStyledString().c_str());
284 #endif
285 MOZ_ASSERT(false, "Unexpected JSON to deserialize as a principal");
287 return nullptr;
289 MOZ_ASSERT(principalKind != -1,
290 "PrincipalKind should always be >=0 by this point");
292 if (principalKind == eSystemPrincipal) {
293 RefPtr<BasePrincipal> principal =
294 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
295 return principal.forget();
298 if (principalKind == eNullPrincipal) {
299 nsTArray<NullPrincipal::KeyVal> res = GetJSONKeys<NullPrincipal>(value);
300 return NullPrincipal::FromProperties(res);
303 if (principalKind == eContentPrincipal) {
304 nsTArray<ContentPrincipal::KeyVal> res =
305 GetJSONKeys<ContentPrincipal>(value);
306 return ContentPrincipal::FromProperties(res);
309 if (principalKind == eExpandedPrincipal) {
310 nsTArray<ExpandedPrincipal::KeyVal> res =
311 GetJSONKeys<ExpandedPrincipal>(value);
312 return ExpandedPrincipal::FromProperties(res);
315 MOZ_RELEASE_ASSERT(false, "Unexpected enum to deserialize as a principal");
318 nsresult BasePrincipal::PopulateJSONObject(Json::Value& aObject) {
319 return NS_OK;
322 // Returns a JSON representation of the principal.
323 // Calling BasePrincipal::FromJSON will deserialize the JSON into
324 // the corresponding principal type.
325 nsresult BasePrincipal::ToJSON(nsACString& aResult) {
326 MOZ_ASSERT(aResult.IsEmpty(), "ToJSON only supports an empty result input");
327 aResult.Truncate();
329 Json::StreamWriterBuilder builder;
330 builder["indentation"] = "";
331 Json::Value innerJSONObject = Json::objectValue;
333 nsresult rv = PopulateJSONObject(innerJSONObject);
334 NS_ENSURE_SUCCESS(rv, rv);
336 Json::Value root = Json::objectValue;
337 std::string key = std::to_string(Kind());
338 root[key] = innerJSONObject;
339 std::string result = Json::writeString(builder, root);
340 aResult.Append(result);
341 if (aResult.Length() == 0) {
342 MOZ_ASSERT(false, "JSON writer failed to output a principal serialization");
343 return NS_ERROR_UNEXPECTED;
345 return NS_OK;
348 bool BasePrincipal::FastSubsumesIgnoringFPD(
349 nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) {
350 MOZ_ASSERT(aOther);
352 if (Kind() == eContentPrincipal &&
353 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
354 mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
355 return false;
358 return SubsumesInternal(aOther, aConsideration);
361 bool BasePrincipal::Subsumes(nsIPrincipal* aOther,
362 DocumentDomainConsideration aConsideration) {
363 MOZ_ASSERT(aOther);
364 MOZ_ASSERT_IF(Kind() == eContentPrincipal, mOriginSuffix);
366 // Expanded principals handle origin attributes for each of their
367 // sub-principals individually, null principals do only simple checks for
368 // pointer equality, and system principals are immune to origin attributes
369 // checks, so only do this check for content principals.
370 if (Kind() == eContentPrincipal &&
371 mOriginSuffix != Cast(aOther)->mOriginSuffix) {
372 return false;
375 return SubsumesInternal(aOther, aConsideration);
378 NS_IMETHODIMP
379 BasePrincipal::Equals(nsIPrincipal* aOther, bool* aResult) {
380 NS_ENSURE_ARG_POINTER(aOther);
382 *aResult = FastEquals(aOther);
384 return NS_OK;
387 NS_IMETHODIMP
388 BasePrincipal::EqualsForPermission(nsIPrincipal* aOther, bool aExactHost,
389 bool* aResult) {
390 *aResult = false;
391 NS_ENSURE_ARG_POINTER(aOther);
392 NS_ENSURE_ARG_POINTER(aResult);
394 // If the principals are equal, then they match.
395 if (FastEquals(aOther)) {
396 *aResult = true;
397 return NS_OK;
400 // If we are matching with an exact host, we're done now - the permissions
401 // don't match otherwise, we need to start comparing subdomains!
402 if (aExactHost) {
403 return NS_OK;
406 // Compare their OriginAttributes
407 const mozilla::OriginAttributes& theirAttrs = aOther->OriginAttributesRef();
408 const mozilla::OriginAttributes& ourAttrs = OriginAttributesRef();
410 if (theirAttrs != ourAttrs) {
411 return NS_OK;
414 nsCOMPtr<nsIURI> ourURI;
415 nsresult rv = GetURI(getter_AddRefs(ourURI));
416 NS_ENSURE_SUCCESS(rv, rv);
417 auto* basePrin = BasePrincipal::Cast(aOther);
419 nsCOMPtr<nsIURI> otherURI;
420 rv = basePrin->GetURI(getter_AddRefs(otherURI));
421 NS_ENSURE_SUCCESS(rv, rv);
422 // Compare schemes
423 nsAutoCString otherScheme;
424 rv = otherURI->GetScheme(otherScheme);
425 NS_ENSURE_SUCCESS(rv, rv);
427 nsAutoCString ourScheme;
428 rv = ourURI->GetScheme(ourScheme);
429 NS_ENSURE_SUCCESS(rv, rv);
431 if (otherScheme != ourScheme) {
432 return NS_OK;
435 // Compare ports
436 int32_t otherPort;
437 rv = otherURI->GetPort(&otherPort);
438 NS_ENSURE_SUCCESS(rv, rv);
440 int32_t ourPort;
441 rv = ourURI->GetPort(&ourPort);
442 NS_ENSURE_SUCCESS(rv, rv);
444 if (otherPort != ourPort) {
445 return NS_OK;
448 // Check if the host or any subdomain of their host matches.
449 nsAutoCString otherHost;
450 rv = otherURI->GetHost(otherHost);
451 if (NS_FAILED(rv) || otherHost.IsEmpty()) {
452 return NS_OK;
455 nsAutoCString ourHost;
456 rv = ourURI->GetHost(ourHost);
457 if (NS_FAILED(rv) || ourHost.IsEmpty()) {
458 return NS_OK;
461 nsCOMPtr<nsIEffectiveTLDService> tldService =
462 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
463 if (!tldService) {
464 NS_ERROR("Should have a tld service!");
465 return NS_ERROR_FAILURE;
468 // This loop will not loop forever, as GetNextSubDomain will eventually fail
469 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
470 while (otherHost != ourHost) {
471 rv = tldService->GetNextSubDomain(otherHost, otherHost);
472 if (NS_FAILED(rv)) {
473 if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
474 return NS_OK;
476 return rv;
480 *aResult = true;
481 return NS_OK;
484 NS_IMETHODIMP
485 BasePrincipal::EqualsConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
486 NS_ENSURE_ARG_POINTER(aOther);
488 *aResult = FastEqualsConsideringDomain(aOther);
490 return NS_OK;
493 NS_IMETHODIMP
494 BasePrincipal::EqualsURI(nsIURI* aOtherURI, bool* aResult) {
495 *aResult = false;
496 nsCOMPtr<nsIURI> prinURI;
497 nsresult rv = GetURI(getter_AddRefs(prinURI));
498 if (NS_FAILED(rv) || !prinURI) {
499 return NS_OK;
501 return prinURI->EqualsExceptRef(aOtherURI, aResult);
504 NS_IMETHODIMP
505 BasePrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult) {
506 NS_ENSURE_ARG_POINTER(aOther);
508 *aResult = FastSubsumes(aOther);
510 return NS_OK;
513 NS_IMETHODIMP
514 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
515 NS_ENSURE_ARG_POINTER(aOther);
517 *aResult = FastSubsumesConsideringDomain(aOther);
519 return NS_OK;
522 NS_IMETHODIMP
523 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther,
524 bool* aResult) {
525 NS_ENSURE_ARG_POINTER(aOther);
527 *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
529 return NS_OK;
532 NS_IMETHODIMP
533 BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aAllowIfInheritsPrincipal) {
534 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, false, 0);
537 NS_IMETHODIMP
538 BasePrincipal::CheckMayLoadWithReporting(nsIURI* aURI,
539 bool aAllowIfInheritsPrincipal,
540 uint64_t aInnerWindowID) {
541 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, true,
542 aInnerWindowID);
545 nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI,
546 bool aAllowIfInheritsPrincipal,
547 bool aReport,
548 uint64_t aInnerWindowID) {
549 NS_ENSURE_ARG_POINTER(aURI);
550 MOZ_ASSERT(
551 aReport || aInnerWindowID == 0,
552 "Why do we have an inner window id if we're not supposed to report?");
554 // Check the internal method first, which allows us to quickly approve loads
555 // for the System Principal.
556 if (MayLoadInternal(aURI)) {
557 return NS_OK;
560 nsresult rv;
561 if (aAllowIfInheritsPrincipal) {
562 // If the caller specified to allow loads of URIs that inherit
563 // our principal, allow the load if this URI inherits its principal.
564 bool doesInheritSecurityContext;
565 rv = NS_URIChainHasFlags(aURI,
566 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
567 &doesInheritSecurityContext);
568 if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
569 return NS_OK;
573 bool fetchableByAnyone;
574 rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE,
575 &fetchableByAnyone);
576 if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
577 return NS_OK;
580 if (aReport) {
581 nsCOMPtr<nsIURI> prinURI;
582 rv = GetURI(getter_AddRefs(prinURI));
583 if (NS_SUCCEEDED(rv) && prinURI) {
584 nsScriptSecurityManager::ReportError(
585 "CheckSameOriginError", prinURI, aURI,
586 mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
590 return NS_ERROR_DOM_BAD_URI;
593 NS_IMETHODIMP
594 BasePrincipal::IsThirdPartyURI(nsIURI* aURI, bool* aRes) {
595 if (IsSystemPrincipal() || (AddonPolicy() && AddonAllowsLoad(aURI))) {
596 *aRes = false;
597 return NS_OK;
600 *aRes = true;
601 // If we do not have a URI its always 3rd party.
602 nsCOMPtr<nsIURI> prinURI;
603 nsresult rv = GetURI(getter_AddRefs(prinURI));
604 if (NS_FAILED(rv) || !prinURI) {
605 return NS_OK;
607 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
608 return thirdPartyUtil->IsThirdPartyURI(prinURI, aURI, aRes);
611 NS_IMETHODIMP
612 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal* aPrin, bool* aRes) {
613 *aRes = true;
614 nsCOMPtr<nsIURI> prinURI;
615 nsresult rv = GetURI(getter_AddRefs(prinURI));
616 if (NS_FAILED(rv) || !prinURI) {
617 return NS_OK;
619 return aPrin->IsThirdPartyURI(prinURI, aRes);
621 NS_IMETHODIMP
622 BasePrincipal::IsThirdPartyChannel(nsIChannel* aChan, bool* aRes) {
623 if (IsSystemPrincipal()) {
624 // Nothing is 3rd party to the system principal.
625 *aRes = false;
626 return NS_OK;
629 nsCOMPtr<nsIURI> prinURI;
630 GetURI(getter_AddRefs(prinURI));
631 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
632 return thirdPartyUtil->IsThirdPartyChannel(aChan, prinURI, aRes);
635 NS_IMETHODIMP
636 BasePrincipal::IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) {
637 *aRes = false;
638 nsCOMPtr<nsIURI> prinURI;
639 nsresult rv = GetURI(getter_AddRefs(prinURI));
640 if (NS_FAILED(rv) || !prinURI) {
641 return NS_OK;
643 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
644 if (!ssm) {
645 return NS_ERROR_UNEXPECTED;
647 *aRes = NS_SUCCEEDED(
648 ssm->CheckSameOriginURI(prinURI, aURI, false, aIsPrivateWin));
649 return NS_OK;
652 NS_IMETHODIMP
653 BasePrincipal::IsL10nAllowed(nsIURI* aURI, bool* aRes) {
654 *aRes = false;
656 if (nsContentUtils::IsErrorPage(aURI)) {
657 *aRes = true;
658 return NS_OK;
661 // The system principal is always allowed.
662 if (IsSystemPrincipal()) {
663 *aRes = true;
664 return NS_OK;
667 nsCOMPtr<nsIURI> uri;
668 nsresult rv = GetURI(getter_AddRefs(uri));
669 NS_ENSURE_SUCCESS(rv, NS_OK);
671 bool hasFlags;
673 // Allow access to uris that cannot be loaded by web content.
674 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
675 &hasFlags);
676 NS_ENSURE_SUCCESS(rv, NS_OK);
677 if (hasFlags) {
678 *aRes = true;
679 return NS_OK;
682 // UI resources also get access.
683 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
684 &hasFlags);
685 NS_ENSURE_SUCCESS(rv, NS_OK);
686 if (hasFlags) {
687 *aRes = true;
688 return NS_OK;
691 auto policy = AddonPolicy();
692 *aRes = (policy && policy->IsPrivileged());
693 return NS_OK;
696 NS_IMETHODIMP
697 BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) {
698 *aRes = false;
699 nsCOMPtr<nsIURI> prinURI;
700 nsresult rv = GetURI(getter_AddRefs(prinURI));
701 if (NS_FAILED(rv) || !prinURI) {
702 return NS_OK;
704 *aRes = NS_RelaxStrictFileOriginPolicy(aURI, prinURI);
705 return NS_OK;
708 NS_IMETHODIMP
709 BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
710 const OriginAttributes& aOriginAttributes,
711 nsACString& _retval) {
712 _retval.Truncate();
713 constexpr auto space = " "_ns;
715 nsCOMPtr<nsIURI> uri;
716 nsresult rv = GetURI(getter_AddRefs(uri));
717 NS_ENSURE_SUCCESS(rv, rv);
719 nsAutoCString scheme, host, port;
720 if (uri) {
721 uri->GetScheme(scheme);
722 uri->GetHost(host);
723 port.AppendInt(NS_GetRealPort(uri));
726 if (aWithCredentials) {
727 _retval.AssignLiteral("cred");
728 } else {
729 _retval.AssignLiteral("nocred");
732 nsAutoCString spec;
733 rv = aURI->GetSpec(spec);
734 NS_ENSURE_SUCCESS(rv, rv);
736 nsAutoCString originAttributesSuffix;
737 aOriginAttributes.CreateSuffix(originAttributesSuffix);
739 _retval.Append(space + scheme + space + host + space + port + space + spec +
740 space + originAttributesSuffix);
742 return NS_OK;
745 NS_IMETHODIMP
746 BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
747 uint32_t* aRejectedReason,
748 bool* aOutAllowed) {
749 *aRejectedReason = 0;
750 *aOutAllowed = false;
752 nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aCheckWindow);
753 nsCOMPtr<nsIURI> uri;
754 nsresult rv = GetURI(getter_AddRefs(uri));
755 if (NS_FAILED(rv)) {
756 return rv;
758 *aOutAllowed =
759 ContentBlocking::ShouldAllowAccessFor(win, uri, aRejectedReason);
760 return NS_OK;
763 NS_IMETHODIMP
764 BasePrincipal::GetIsNullPrincipal(bool* aResult) {
765 *aResult = Kind() == eNullPrincipal;
766 return NS_OK;
769 NS_IMETHODIMP
770 BasePrincipal::GetIsContentPrincipal(bool* aResult) {
771 *aResult = Kind() == eContentPrincipal;
772 return NS_OK;
775 NS_IMETHODIMP
776 BasePrincipal::GetIsExpandedPrincipal(bool* aResult) {
777 *aResult = Kind() == eExpandedPrincipal;
778 return NS_OK;
781 NS_IMETHODIMP
782 BasePrincipal::GetAsciiSpec(nsACString& aSpec) {
783 aSpec.Truncate();
784 nsCOMPtr<nsIURI> prinURI;
785 nsresult rv = GetURI(getter_AddRefs(prinURI));
786 if (NS_FAILED(rv) || !prinURI) {
787 return NS_OK;
789 return prinURI->GetAsciiSpec(aSpec);
792 NS_IMETHODIMP
793 BasePrincipal::GetSpec(nsACString& aSpec) {
794 aSpec.Truncate();
795 nsCOMPtr<nsIURI> prinURI;
796 nsresult rv = GetURI(getter_AddRefs(prinURI));
797 if (NS_FAILED(rv) || !prinURI) {
798 return NS_OK;
800 return prinURI->GetSpec(aSpec);
803 NS_IMETHODIMP
804 BasePrincipal::GetAsciiHost(nsACString& aHost) {
805 aHost.Truncate();
806 nsCOMPtr<nsIURI> prinURI;
807 nsresult rv = GetURI(getter_AddRefs(prinURI));
808 if (NS_FAILED(rv) || !prinURI) {
809 return NS_OK;
811 return prinURI->GetAsciiHost(aHost);
814 NS_IMETHODIMP
815 BasePrincipal::GetExposablePrePath(nsACString& aPrepath) {
816 aPrepath.Truncate();
817 nsCOMPtr<nsIURI> prinURI;
818 nsresult rv = GetURI(getter_AddRefs(prinURI));
819 if (NS_FAILED(rv) || !prinURI) {
820 return NS_OK;
823 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(prinURI);
824 return exposableURI->GetDisplayPrePath(aPrepath);
827 NS_IMETHODIMP
828 BasePrincipal::GetExposableSpec(nsACString& aSpec) {
829 aSpec.Truncate();
830 nsCOMPtr<nsIURI> prinURI;
831 nsresult rv = GetURI(getter_AddRefs(prinURI));
832 if (NS_FAILED(rv) || !prinURI) {
833 return NS_OK;
835 nsCOMPtr<nsIURI> clone;
836 rv = NS_MutateURI(prinURI)
837 .SetQuery(""_ns)
838 .SetRef(""_ns)
839 .SetUserPass(""_ns)
840 .Finalize(clone);
841 NS_ENSURE_SUCCESS(rv, rv);
842 return clone->GetAsciiSpec(aSpec);
845 NS_IMETHODIMP
846 BasePrincipal::GetPrePath(nsACString& aPath) {
847 aPath.Truncate();
848 nsCOMPtr<nsIURI> prinURI;
849 nsresult rv = GetURI(getter_AddRefs(prinURI));
850 if (NS_FAILED(rv) || !prinURI) {
851 return NS_OK;
853 return prinURI->GetPrePath(aPath);
856 NS_IMETHODIMP
857 BasePrincipal::GetFilePath(nsACString& aPath) {
858 aPath.Truncate();
859 nsCOMPtr<nsIURI> prinURI;
860 nsresult rv = GetURI(getter_AddRefs(prinURI));
861 if (NS_FAILED(rv) || !prinURI) {
862 return NS_OK;
864 return prinURI->GetFilePath(aPath);
867 NS_IMETHODIMP
868 BasePrincipal::GetIsSystemPrincipal(bool* aResult) {
869 *aResult = IsSystemPrincipal();
870 return NS_OK;
873 NS_IMETHODIMP
874 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult) {
875 *aResult = AddonPolicy() || ContentScriptAddonPolicy();
876 return NS_OK;
879 NS_IMETHODIMP BasePrincipal::GetIsOnion(bool* aIsOnion) {
880 *aIsOnion = false;
881 nsCOMPtr<nsIURI> prinURI;
882 nsresult rv = GetURI(getter_AddRefs(prinURI));
883 if (NS_FAILED(rv) || !prinURI) {
884 return NS_OK;
887 nsAutoCString host;
888 rv = prinURI->GetHost(host);
889 if (NS_FAILED(rv)) {
890 return NS_OK;
892 *aIsOnion = StringEndsWith(host, ".onion"_ns);
893 return NS_OK;
896 NS_IMETHODIMP BasePrincipal::GetIsIpAddress(bool* aIsIpAddress) {
897 *aIsIpAddress = false;
899 nsCOMPtr<nsIURI> prinURI;
900 nsresult rv = GetURI(getter_AddRefs(prinURI));
901 if (NS_FAILED(rv) || !prinURI) {
902 return NS_OK;
905 nsAutoCString host;
906 rv = prinURI->GetHost(host);
907 if (NS_FAILED(rv)) {
908 return NS_OK;
911 PRNetAddr prAddr;
912 memset(&prAddr, 0, sizeof(prAddr));
914 if (PR_StringToNetAddr(host.get(), &prAddr) == PR_SUCCESS) {
915 *aIsIpAddress = true;
918 return NS_OK;
921 NS_IMETHODIMP BasePrincipal::GetIsLocalIpAddress(bool* aIsIpAddress) {
922 *aIsIpAddress = false;
924 nsCOMPtr<nsIURI> prinURI;
925 nsresult rv = GetURI(getter_AddRefs(prinURI));
926 if (NS_FAILED(rv) || !prinURI) {
927 return NS_OK;
930 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
931 if (NS_FAILED(rv) || !ioService) {
932 return NS_OK;
934 rv = ioService->HostnameIsLocalIPAddress(prinURI, aIsIpAddress);
935 if (NS_FAILED(rv)) {
936 *aIsIpAddress = false;
938 return NS_OK;
941 NS_IMETHODIMP
942 BasePrincipal::GetScheme(nsACString& aScheme) {
943 aScheme.Truncate();
945 nsCOMPtr<nsIURI> prinURI;
946 nsresult rv = GetURI(getter_AddRefs(prinURI));
947 if (NS_FAILED(rv) || !prinURI) {
948 return NS_OK;
951 return prinURI->GetScheme(aScheme);
954 NS_IMETHODIMP
955 BasePrincipal::SchemeIs(const char* aScheme, bool* aResult) {
956 *aResult = false;
957 nsCOMPtr<nsIURI> prinURI;
958 nsresult rv = GetURI(getter_AddRefs(prinURI));
959 if (NS_FAILED(rv) || !prinURI) {
960 return NS_OK;
962 *aResult = prinURI->SchemeIs(aScheme);
963 return NS_OK;
966 NS_IMETHODIMP
967 BasePrincipal::IsURIInPrefList(const char* aPref, bool* aResult) {
968 *aResult = false;
969 nsCOMPtr<nsIURI> prinURI;
970 nsresult rv = GetURI(getter_AddRefs(prinURI));
971 if (NS_FAILED(rv) || !prinURI) {
972 return NS_OK;
974 *aResult = nsContentUtils::IsURIInPrefList(prinURI, aPref);
975 return NS_OK;
978 NS_IMETHODIMP
979 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult) {
980 MOZ_ASSERT(NS_IsMainThread());
981 *aResult = false;
983 nsCOMPtr<nsIURI> uri;
984 nsresult rv = GetURI(getter_AddRefs(uri));
985 if (NS_FAILED(rv) || !uri) {
986 return NS_OK;
989 *aResult = nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri);
990 return NS_OK;
993 NS_IMETHODIMP
994 BasePrincipal::GetAboutModuleFlags(uint32_t* flags) {
995 *flags = 0;
996 nsCOMPtr<nsIURI> prinURI;
997 nsresult rv = GetURI(getter_AddRefs(prinURI));
998 if (NS_FAILED(rv) || !prinURI) {
999 return NS_ERROR_NOT_AVAILABLE;
1001 if (!prinURI->SchemeIs("about")) {
1002 return NS_OK;
1005 nsCOMPtr<nsIAboutModule> aboutModule;
1006 rv = NS_GetAboutModule(prinURI, getter_AddRefs(aboutModule));
1007 if (NS_FAILED(rv) || !aboutModule) {
1008 return rv;
1010 return aboutModule->GetURIFlags(prinURI, flags);
1013 NS_IMETHODIMP
1014 BasePrincipal::GetOriginAttributes(JSContext* aCx,
1015 JS::MutableHandle<JS::Value> aVal) {
1016 if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
1017 return NS_ERROR_FAILURE;
1019 return NS_OK;
1022 NS_IMETHODIMP
1023 BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) {
1024 MOZ_ASSERT(mOriginSuffix);
1025 mOriginSuffix->ToUTF8String(aOriginAttributes);
1026 return NS_OK;
1029 NS_IMETHODIMP
1030 BasePrincipal::GetUserContextId(uint32_t* aUserContextId) {
1031 *aUserContextId = UserContextId();
1032 return NS_OK;
1035 NS_IMETHODIMP
1036 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) {
1037 *aPrivateBrowsingId = PrivateBrowsingId();
1038 return NS_OK;
1041 NS_IMETHODIMP
1042 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1043 bool* aIsInIsolatedMozBrowserElement) {
1044 *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
1045 return NS_OK;
1048 nsresult BasePrincipal::GetAddonPolicy(nsISupports** aResult) {
1049 RefPtr<extensions::WebExtensionPolicy> policy(AddonPolicy());
1050 policy.forget(aResult);
1051 return NS_OK;
1054 extensions::WebExtensionPolicy* BasePrincipal::AddonPolicy() {
1055 if (Is<ContentPrincipal>()) {
1056 return As<ContentPrincipal>()->AddonPolicy();
1058 return nullptr;
1061 bool BasePrincipal::AddonHasPermission(const nsAtom* aPerm) {
1062 if (auto policy = AddonPolicy()) {
1063 return policy->HasPermission(aPerm);
1065 return false;
1068 nsIPrincipal* BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
1069 if (Is<ExpandedPrincipal>()) {
1070 return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI);
1072 return this;
1075 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1076 nsIURI* aURI, const OriginAttributes& aAttrs) {
1077 MOZ_ASSERT(aURI);
1079 nsAutoCString originNoSuffix;
1080 nsresult rv =
1081 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
1082 if (NS_FAILED(rv)) {
1083 // If the generation of the origin fails, we still want to have a valid
1084 // principal. Better to return a null principal here.
1085 return NullPrincipal::Create(aAttrs);
1088 return CreateContentPrincipal(aURI, aAttrs, originNoSuffix);
1091 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1092 nsIURI* aURI, const OriginAttributes& aAttrs,
1093 const nsACString& aOriginNoSuffix) {
1094 MOZ_ASSERT(aURI);
1095 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
1097 // If the URI is supposed to inherit the security context of whoever loads it,
1098 // we shouldn't make a content principal for it.
1099 bool inheritsPrincipal;
1100 nsresult rv = NS_URIChainHasFlags(
1101 aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
1102 &inheritsPrincipal);
1103 if (NS_FAILED(rv) || inheritsPrincipal) {
1104 return NullPrincipal::Create(aAttrs);
1107 // Check whether the URI knows what its principal is supposed to be.
1108 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1109 nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
1110 do_QueryInterface(aURI);
1111 if (uriWithSpecialOrigin) {
1112 nsCOMPtr<nsIURI> origin;
1113 rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
1114 if (NS_WARN_IF(NS_FAILED(rv))) {
1115 return nullptr;
1117 MOZ_ASSERT(origin);
1118 OriginAttributes attrs;
1119 RefPtr<BasePrincipal> principal = CreateContentPrincipal(origin, attrs);
1120 return principal.forget();
1122 #endif
1124 nsCOMPtr<nsIPrincipal> blobPrincipal;
1125 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1126 aURI, getter_AddRefs(blobPrincipal))) {
1127 MOZ_ASSERT(blobPrincipal);
1128 RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
1129 return principal.forget();
1132 // Mint a content principal.
1133 RefPtr<ContentPrincipal> principal =
1134 new ContentPrincipal(aURI, aAttrs, aOriginNoSuffix);
1135 return principal.forget();
1138 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1139 const nsACString& aOrigin) {
1140 MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns),
1141 "CreateContentPrincipal does not support System and Expanded "
1142 "principals");
1144 MOZ_ASSERT(
1145 !StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")),
1146 "CreateContentPrincipal does not support NullPrincipal");
1148 nsAutoCString originNoSuffix;
1149 OriginAttributes attrs;
1150 if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
1151 return nullptr;
1154 nsCOMPtr<nsIURI> uri;
1155 nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
1156 NS_ENSURE_SUCCESS(rv, nullptr);
1158 return BasePrincipal::CreateContentPrincipal(uri, attrs);
1161 already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingOriginAttributes(
1162 const OriginAttributes& aOriginAttributes) {
1163 if (NS_WARN_IF(!IsContentPrincipal())) {
1164 return nullptr;
1167 nsAutoCString originNoSuffix;
1168 nsresult rv = GetOriginNoSuffix(originNoSuffix);
1169 NS_ENSURE_SUCCESS(rv, nullptr);
1171 nsCOMPtr<nsIURI> uri;
1172 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri)));
1174 RefPtr<ContentPrincipal> copy =
1175 new ContentPrincipal(uri, aOriginAttributes, originNoSuffix);
1176 return copy.forget();
1179 extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
1180 if (!Is<ExpandedPrincipal>()) {
1181 return nullptr;
1184 auto expanded = As<ExpandedPrincipal>();
1185 for (auto& prin : expanded->AllowList()) {
1186 if (auto policy = BasePrincipal::Cast(prin)->AddonPolicy()) {
1187 return policy;
1191 return nullptr;
1194 bool BasePrincipal::AddonAllowsLoad(nsIURI* aURI,
1195 bool aExplicit /* = false */) {
1196 if (Is<ExpandedPrincipal>()) {
1197 return As<ExpandedPrincipal>()->AddonAllowsLoad(aURI, aExplicit);
1199 if (auto policy = AddonPolicy()) {
1200 return policy->CanAccessURI(aURI, aExplicit);
1202 return false;
1205 NS_IMETHODIMP
1206 BasePrincipal::GetLocalStorageQuotaKey(nsACString& aKey) {
1207 aKey.Truncate();
1209 nsCOMPtr<nsIURI> uri;
1210 nsresult rv = GetURI(getter_AddRefs(uri));
1211 NS_ENSURE_SUCCESS(rv, rv);
1212 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1214 // The special handling of the file scheme should be consistent with
1215 // GetStorageOriginKey.
1217 nsAutoCString baseDomain;
1218 rv = uri->GetAsciiHost(baseDomain);
1219 NS_ENSURE_SUCCESS(rv, rv);
1221 if (baseDomain.IsEmpty() && uri->SchemeIs("file")) {
1222 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1223 NS_ENSURE_SUCCESS(rv, rv);
1225 rv = url->GetDirectory(baseDomain);
1226 NS_ENSURE_SUCCESS(rv, rv);
1227 } else {
1228 nsCOMPtr<nsIEffectiveTLDService> eTLDService(
1229 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
1230 NS_ENSURE_SUCCESS(rv, rv);
1232 nsAutoCString eTLDplusOne;
1233 rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
1234 if (NS_SUCCEEDED(rv)) {
1235 baseDomain = eTLDplusOne;
1236 } else if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
1237 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
1238 rv = NS_OK;
1240 NS_ENSURE_SUCCESS(rv, rv);
1243 OriginAttributesRef().CreateSuffix(aKey);
1245 nsAutoCString subdomainsDBKey;
1246 rv = dom::StorageUtils::CreateReversedDomain(baseDomain, subdomainsDBKey);
1247 NS_ENSURE_SUCCESS(rv, rv);
1249 aKey.Append(':');
1250 aKey.Append(subdomainsDBKey);
1252 return NS_OK;
1255 NS_IMETHODIMP
1256 BasePrincipal::GetNextSubDomainPrincipal(
1257 nsIPrincipal** aNextSubDomainPrincipal) {
1258 nsCOMPtr<nsIURI> uri;
1259 nsresult rv = GetURI(getter_AddRefs(uri));
1260 if (NS_FAILED(rv) || !uri) {
1261 return NS_OK;
1264 nsAutoCString host;
1265 rv = uri->GetHost(host);
1266 if (NS_FAILED(rv) || host.IsEmpty()) {
1267 return NS_OK;
1270 nsCString subDomain;
1271 rv = nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host, subDomain);
1273 if (NS_FAILED(rv) || subDomain.IsEmpty()) {
1274 return NS_OK;
1277 nsCOMPtr<nsIURI> subDomainURI;
1278 rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI);
1279 if (NS_FAILED(rv) || !subDomainURI) {
1280 return NS_OK;
1282 // Copy the attributes over
1283 mozilla::OriginAttributes attrs = OriginAttributesRef();
1285 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1286 // Disable userContext for permissions.
1287 attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
1289 RefPtr<nsIPrincipal> principal =
1290 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
1292 if (!principal) {
1293 return NS_OK;
1295 principal.forget(aNextSubDomainPrincipal);
1296 return NS_OK;
1299 NS_IMETHODIMP
1300 BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
1301 aOriginKey.Truncate();
1303 nsCOMPtr<nsIURI> uri;
1304 nsresult rv = GetURI(getter_AddRefs(uri));
1305 NS_ENSURE_SUCCESS(rv, rv);
1306 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1308 // The special handling of the file scheme should be consistent with
1309 // GetLocalStorageQuotaKey.
1311 nsAutoCString domainOrigin;
1312 rv = uri->GetAsciiHost(domainOrigin);
1313 NS_ENSURE_SUCCESS(rv, rv);
1315 if (domainOrigin.IsEmpty()) {
1316 // For the file:/// protocol use the exact directory as domain.
1317 if (uri->SchemeIs("file")) {
1318 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1319 NS_ENSURE_SUCCESS(rv, rv);
1320 rv = url->GetDirectory(domainOrigin);
1321 NS_ENSURE_SUCCESS(rv, rv);
1325 // Append reversed domain
1326 nsAutoCString reverseDomain;
1327 rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
1328 NS_ENSURE_SUCCESS(rv, rv);
1330 aOriginKey.Append(reverseDomain);
1332 // Append scheme
1333 nsAutoCString scheme;
1334 rv = uri->GetScheme(scheme);
1335 NS_ENSURE_SUCCESS(rv, rv);
1337 aOriginKey.Append(':');
1338 aOriginKey.Append(scheme);
1340 // Append port if any
1341 int32_t port = NS_GetRealPort(uri);
1342 if (port != -1) {
1343 aOriginKey.Append(nsPrintfCString(":%d", port));
1346 return NS_OK;
1349 NS_IMETHODIMP
1350 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
1351 *aIsScriptAllowedByPolicy = false;
1352 nsCOMPtr<nsIURI> prinURI;
1353 nsresult rv = GetURI(getter_AddRefs(prinURI));
1354 if (NS_FAILED(rv) || !prinURI) {
1355 return NS_OK;
1357 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1358 if (!ssm) {
1359 return NS_ERROR_UNEXPECTED;
1361 return ssm->PolicyAllowsScript(prinURI, aIsScriptAllowedByPolicy);
1364 bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
1365 MOZ_ASSERT(IsInitialized());
1366 MOZ_ASSERT(aOther.IsInitialized());
1367 return mPrincipal->FastEquals(aOther.mPrincipal);
1370 NS_IMETHODIMP
1371 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
1372 nsIReferrerInfo** _retval) {
1373 nsCOMPtr<nsIURI> prinURI;
1374 RefPtr<dom::ReferrerInfo> info;
1375 nsresult rv = GetURI(getter_AddRefs(prinURI));
1376 if (NS_FAILED(rv) || !prinURI) {
1377 info = new dom::ReferrerInfo(nullptr);
1378 info.forget(_retval);
1379 return NS_OK;
1381 info = new dom::ReferrerInfo(prinURI, aReferrerPolicy);
1382 info.forget(_retval);
1383 return NS_OK;
1386 NS_IMPL_ADDREF(BasePrincipal::Deserializer)
1387 NS_IMPL_RELEASE(BasePrincipal::Deserializer)
1389 NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer)
1390 NS_INTERFACE_MAP_ENTRY(nsISupports)
1391 NS_INTERFACE_MAP_ENTRY(nsISerializable)
1392 if (mPrincipal) {
1393 return mPrincipal->QueryInterface(aIID, aInstancePtr);
1394 } else
1395 NS_INTERFACE_MAP_END
1397 NS_IMETHODIMP
1398 BasePrincipal::Deserializer::Write(nsIObjectOutputStream* aStream) {
1399 // Read is used still for legacy principals
1400 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
1401 return NS_OK;
1404 } // namespace mozilla