Bug 1517921 [wpt PR 14728] - [manifest] Make sure deleted tests are removed from...
[gecko.git] / docshell / base / nsDocShellLoadState.cpp
blob318201cd5d6cc541d6a8cd9766bedf57c5d3c5ab
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 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 "nsDocShellLoadState.h"
8 #include "nsIDocShell.h"
9 #include "nsIDocShellTreeItem.h"
10 #include "nsIScriptSecurityManager.h"
11 #include "nsIWebNavigation.h"
12 #include "nsIChildChannel.h"
14 #include "mozilla/OriginAttributes.h"
15 #include "mozilla/NullPrincipal.h"
17 #include "mozilla/dom/PContent.h"
19 nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI)
20 : mURI(aURI),
21 mResultPrincipalURIIsSome(false),
22 mKeepResultPrincipalURIIfSet(false),
23 mLoadReplace(false),
24 mInheritPrincipal(false),
25 mPrincipalIsExplicit(false),
26 mForceAllowDataURI(false),
27 mOriginalFrameSrc(false),
28 mSendReferrer(true),
29 mReferrerPolicy(mozilla::net::RP_Unset),
30 mLoadType(LOAD_NORMAL),
31 mTarget(),
32 mSrcdocData(VoidString()),
33 mLoadFlags(0),
34 mFirstParty(false),
35 mTypeHint(VoidCString()),
36 mFileName(VoidString()),
37 mIsFromProcessingFrameAttributes(false) {
38 MOZ_ASSERT(aURI, "Cannot create a LoadState with a null URI!");
41 nsDocShellLoadState::nsDocShellLoadState(DocShellLoadStateInit& aLoadState) {
42 MOZ_ASSERT(aLoadState.URI(), "Cannot create a LoadState with a null URI!");
43 mResultPrincipalURIIsSome = aLoadState.ResultPrincipalURIIsSome();
44 mKeepResultPrincipalURIIfSet = aLoadState.KeepResultPrincipalURIIfSet();
45 mLoadReplace = aLoadState.LoadReplace();
46 mInheritPrincipal = aLoadState.InheritPrincipal();
47 mPrincipalIsExplicit = aLoadState.PrincipalIsExplicit();
48 mForceAllowDataURI = aLoadState.ForceAllowDataURI();
49 mOriginalFrameSrc = aLoadState.OriginalFrameSrc();
50 mSendReferrer = aLoadState.SendReferrer();
51 mReferrerPolicy = (mozilla::net::ReferrerPolicy)aLoadState.ReferrerPolicy();
52 mLoadType = aLoadState.LoadType();
53 mTarget = aLoadState.Target();
54 mLoadFlags = aLoadState.LoadFlags();
55 mFirstParty = aLoadState.FirstParty();
56 mTypeHint = aLoadState.TypeHint();
57 mFileName = aLoadState.FileName();
58 mIsFromProcessingFrameAttributes =
59 aLoadState.IsFromProcessingFrameAttributes();
60 mReferrer = aLoadState.Referrer();
61 mURI = aLoadState.URI();
62 mOriginalURI = aLoadState.OriginalURI();
63 mBaseURI = aLoadState.BaseURI();
64 mTriggeringPrincipal = aLoadState.TriggeringPrincipal();
65 mPrincipalToInherit = aLoadState.PrincipalToInherit();
68 nsDocShellLoadState::~nsDocShellLoadState() {}
70 nsresult nsDocShellLoadState::CreateFromPendingChannel(
71 nsIChildChannel* aPendingChannel, nsDocShellLoadState** aResult) {
72 nsCOMPtr<nsIChannel> channel = do_QueryInterface(aPendingChannel);
73 if (NS_WARN_IF(!channel)) {
74 return NS_ERROR_UNEXPECTED;
77 // Create the nsDocShellLoadState object with default state pulled from the
78 // passed-in channel.
79 nsCOMPtr<nsIURI> uri;
80 nsresult rv = channel->GetURI(getter_AddRefs(uri));
81 if (NS_WARN_IF(NS_FAILED(rv))) {
82 return rv;
85 RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(uri);
86 loadState->mPendingRedirectedChannel = aPendingChannel;
88 // Pull relevant state from the channel, and store it on the
89 // nsDocShellLoadState.
90 nsCOMPtr<nsIURI> originalUri;
91 rv = channel->GetOriginalURI(getter_AddRefs(originalUri));
92 if (NS_WARN_IF(NS_FAILED(rv))) {
93 return rv;
95 loadState->SetOriginalURI(originalUri);
97 nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
98 if (NS_WARN_IF(!loadInfo)) {
99 return NS_ERROR_FAILURE;
101 loadState->SetTriggeringPrincipal(loadInfo->TriggeringPrincipal());
103 // Return the newly created loadState.
104 loadState.forget(aResult);
105 return NS_OK;
108 nsIURI* nsDocShellLoadState::Referrer() const { return mReferrer; }
110 void nsDocShellLoadState::SetReferrer(nsIURI* aReferrer) {
111 mReferrer = aReferrer;
114 nsIURI* nsDocShellLoadState::URI() const { return mURI; }
116 void nsDocShellLoadState::SetURI(nsIURI* aURI) { mURI = aURI; }
118 nsIURI* nsDocShellLoadState::OriginalURI() const { return mOriginalURI; }
120 void nsDocShellLoadState::SetOriginalURI(nsIURI* aOriginalURI) {
121 mOriginalURI = aOriginalURI;
124 nsIURI* nsDocShellLoadState::ResultPrincipalURI() const {
125 return mResultPrincipalURI;
128 void nsDocShellLoadState::SetResultPrincipalURI(nsIURI* aResultPrincipalURI) {
129 mResultPrincipalURI = aResultPrincipalURI;
132 bool nsDocShellLoadState::ResultPrincipalURIIsSome() const {
133 return mResultPrincipalURIIsSome;
136 void nsDocShellLoadState::SetResultPrincipalURIIsSome(bool aIsSome) {
137 mResultPrincipalURIIsSome = aIsSome;
140 bool nsDocShellLoadState::KeepResultPrincipalURIIfSet() const {
141 return mKeepResultPrincipalURIIfSet;
144 void nsDocShellLoadState::SetKeepResultPrincipalURIIfSet(bool aKeep) {
145 mKeepResultPrincipalURIIfSet = aKeep;
148 bool nsDocShellLoadState::LoadReplace() const { return mLoadReplace; }
150 void nsDocShellLoadState::SetLoadReplace(bool aLoadReplace) {
151 mLoadReplace = aLoadReplace;
154 nsIPrincipal* nsDocShellLoadState::TriggeringPrincipal() const {
155 return mTriggeringPrincipal;
158 void nsDocShellLoadState::SetTriggeringPrincipal(
159 nsIPrincipal* aTriggeringPrincipal) {
160 mTriggeringPrincipal = aTriggeringPrincipal;
163 nsIPrincipal* nsDocShellLoadState::PrincipalToInherit() const {
164 return mPrincipalToInherit;
167 void nsDocShellLoadState::SetPrincipalToInherit(
168 nsIPrincipal* aPrincipalToInherit) {
169 mPrincipalToInherit = aPrincipalToInherit;
172 bool nsDocShellLoadState::InheritPrincipal() const { return mInheritPrincipal; }
174 void nsDocShellLoadState::SetInheritPrincipal(bool aInheritPrincipal) {
175 mInheritPrincipal = aInheritPrincipal;
178 bool nsDocShellLoadState::PrincipalIsExplicit() const {
179 return mPrincipalIsExplicit;
182 void nsDocShellLoadState::SetPrincipalIsExplicit(bool aPrincipalIsExplicit) {
183 mPrincipalIsExplicit = aPrincipalIsExplicit;
186 bool nsDocShellLoadState::ForceAllowDataURI() const {
187 return mForceAllowDataURI;
190 void nsDocShellLoadState::SetForceAllowDataURI(bool aForceAllowDataURI) {
191 mForceAllowDataURI = aForceAllowDataURI;
194 bool nsDocShellLoadState::OriginalFrameSrc() const { return mOriginalFrameSrc; }
196 void nsDocShellLoadState::SetOriginalFrameSrc(bool aOriginalFrameSrc) {
197 mOriginalFrameSrc = aOriginalFrameSrc;
200 uint32_t nsDocShellLoadState::LoadType() const { return mLoadType; }
202 void nsDocShellLoadState::SetLoadType(uint32_t aLoadType) {
203 mLoadType = aLoadType;
206 nsISHEntry* nsDocShellLoadState::SHEntry() const { return mSHEntry; }
208 void nsDocShellLoadState::SetSHEntry(nsISHEntry* aSHEntry) {
209 mSHEntry = aSHEntry;
212 const nsString& nsDocShellLoadState::Target() const { return mTarget; }
214 void nsDocShellLoadState::SetTarget(const nsAString& aTarget) {
215 mTarget = aTarget;
218 nsIInputStream* nsDocShellLoadState::PostDataStream() const {
219 return mPostDataStream;
222 void nsDocShellLoadState::SetPostDataStream(nsIInputStream* aStream) {
223 mPostDataStream = aStream;
226 nsIInputStream* nsDocShellLoadState::HeadersStream() const {
227 return mHeadersStream;
230 void nsDocShellLoadState::SetHeadersStream(nsIInputStream* aHeadersStream) {
231 mHeadersStream = aHeadersStream;
234 bool nsDocShellLoadState::SendReferrer() const { return mSendReferrer; }
236 void nsDocShellLoadState::SetSendReferrer(bool aSendReferrer) {
237 mSendReferrer = aSendReferrer;
240 mozilla::net::ReferrerPolicy nsDocShellLoadState::ReferrerPolicy() const {
241 return mReferrerPolicy;
244 void nsDocShellLoadState::SetReferrerPolicy(
245 mozilla::net::ReferrerPolicy aReferrerPolicy) {
246 mReferrerPolicy = aReferrerPolicy;
249 const nsString& nsDocShellLoadState::SrcdocData() const { return mSrcdocData; }
251 void nsDocShellLoadState::SetSrcdocData(const nsAString& aSrcdocData) {
252 mSrcdocData = aSrcdocData;
255 nsIDocShell* nsDocShellLoadState::SourceDocShell() const {
256 return mSourceDocShell;
259 void nsDocShellLoadState::SetSourceDocShell(nsIDocShell* aSourceDocShell) {
260 mSourceDocShell = aSourceDocShell;
263 nsIURI* nsDocShellLoadState::BaseURI() const { return mBaseURI; }
265 void nsDocShellLoadState::SetBaseURI(nsIURI* aBaseURI) { mBaseURI = aBaseURI; }
267 void nsDocShellLoadState::GetMaybeResultPrincipalURI(
268 mozilla::Maybe<nsCOMPtr<nsIURI>>& aRPURI) const {
269 bool isSome = ResultPrincipalURIIsSome();
270 aRPURI.reset();
272 if (!isSome) {
273 return;
276 nsCOMPtr<nsIURI> uri = ResultPrincipalURI();
277 aRPURI.emplace(std::move(uri));
280 void nsDocShellLoadState::SetMaybeResultPrincipalURI(
281 mozilla::Maybe<nsCOMPtr<nsIURI>> const& aRPURI) {
282 SetResultPrincipalURI(aRPURI.refOr(nullptr));
283 SetResultPrincipalURIIsSome(aRPURI.isSome());
286 uint32_t nsDocShellLoadState::LoadFlags() const { return mLoadFlags; }
288 void nsDocShellLoadState::SetLoadFlags(uint32_t aLoadFlags) {
289 mLoadFlags = aLoadFlags;
292 void nsDocShellLoadState::SetLoadFlag(uint32_t aFlag) { mLoadFlags |= aFlag; }
294 void nsDocShellLoadState::UnsetLoadFlag(uint32_t aFlag) {
295 mLoadFlags &= ~aFlag;
298 bool nsDocShellLoadState::HasLoadFlags(uint32_t aFlags) {
299 return (mLoadFlags & aFlags) == aFlags;
302 bool nsDocShellLoadState::FirstParty() const { return mFirstParty; }
304 void nsDocShellLoadState::SetFirstParty(bool aFirstParty) {
305 mFirstParty = aFirstParty;
308 const nsCString& nsDocShellLoadState::TypeHint() const { return mTypeHint; }
310 void nsDocShellLoadState::SetTypeHint(const nsCString& aTypeHint) {
311 mTypeHint = aTypeHint;
314 const nsString& nsDocShellLoadState::FileName() const { return mFileName; }
316 void nsDocShellLoadState::SetFileName(const nsAString& aFileName) {
317 mFileName = aFileName;
320 nsresult nsDocShellLoadState::SetupInheritingPrincipal(
321 uint32_t aItemType, const mozilla::OriginAttributes& aOriginAttributes) {
322 // We need a principalToInherit.
324 // If principalIsExplicit is not set there are 4 possibilities:
325 // (1) If the system principal or an expanded principal was passed
326 // in and we're a typeContent docshell, inherit the principal
327 // from the current document instead.
328 // (2) In all other cases when the principal passed in is not null,
329 // use that principal.
330 // (3) If the caller has allowed inheriting from the current document,
331 // or if we're being called from system code (eg chrome JS or pure
332 // C++) then inheritPrincipal should be true and InternalLoad will get
333 // a principal from the current document. If none of these things are
334 // true, then
335 // (4) we don't pass a principal into the channel, and a principal will be
336 // created later from the channel's internal data.
338 // If principalIsExplicit *is* set, there are 4 possibilities
339 // (1) If the system principal or an expanded principal was passed in
340 // and we're a typeContent docshell, return an error.
341 // (2) In all other cases when the principal passed in is not null,
342 // use that principal.
343 // (3) If the caller has allowed inheriting from the current document,
344 // then inheritPrincipal should be true and InternalLoad will get
345 // a principal from the current document. If none of these things are
346 // true, then
347 // (4) we dont' pass a principal into the channel, and a principal will be
348 // created later from the channel's internal data.
349 mPrincipalToInherit = mTriggeringPrincipal;
350 if (mPrincipalToInherit && aItemType != nsIDocShellTreeItem::typeChrome) {
351 if (nsContentUtils::IsSystemPrincipal(mPrincipalToInherit)) {
352 if (mPrincipalIsExplicit) {
353 return NS_ERROR_DOM_SECURITY_ERR;
355 mPrincipalToInherit = nullptr;
356 mInheritPrincipal = true;
357 } else if (nsContentUtils::IsExpandedPrincipal(mPrincipalToInherit)) {
358 if (mPrincipalIsExplicit) {
359 return NS_ERROR_DOM_SECURITY_ERR;
361 // Don't inherit from the current page. Just do the safe thing
362 // and pretend that we were loaded by a nullprincipal.
364 // We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
365 // have origin attributes.
366 mPrincipalToInherit = NullPrincipal::CreateWithInheritedAttributes(
367 aOriginAttributes, false);
368 mInheritPrincipal = false;
372 if (!mPrincipalToInherit && !mInheritPrincipal && !mPrincipalIsExplicit) {
373 // See if there's system or chrome JS code running
374 mInheritPrincipal = nsContentUtils::LegacyIsCallerChromeOrNativeCode();
377 if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL) {
378 mInheritPrincipal = false;
379 // If mFirstParty is true and the pref 'privacy.firstparty.isolate' is
380 // enabled, we will set firstPartyDomain on the origin attributes.
381 mPrincipalToInherit = NullPrincipal::CreateWithInheritedAttributes(
382 aOriginAttributes, mFirstParty);
385 return NS_OK;
388 nsresult nsDocShellLoadState::SetupTriggeringPrincipal(
389 const mozilla::OriginAttributes& aOriginAttributes) {
390 // If the triggeringPrincipal is not set, we first try to create a principal
391 // from the referrer, since the referrer URI reflects the web origin that
392 // triggered the load. If there is no referrer URI, we fall back to using the
393 // SystemPrincipal. It's safe to assume that no provided triggeringPrincipal
394 // and no referrer simulate a load that was triggered by the system. It's
395 // important to note that this block of code needs to appear *after* the block
396 // where we munge the principalToInherit, because otherwise we would never
397 // enter code blocks checking if the principalToInherit is null and we will
398 // end up with a wrong inheritPrincipal flag.
399 if (!mTriggeringPrincipal) {
400 if (mReferrer) {
401 mTriggeringPrincipal =
402 BasePrincipal::CreateCodebasePrincipal(mReferrer, aOriginAttributes);
404 if (!mTriggeringPrincipal) {
405 return NS_ERROR_FAILURE;
407 } else {
408 mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
411 return NS_OK;
414 void nsDocShellLoadState::CalculateLoadURIFlags() {
415 uint32_t oldLoadFlags = mLoadFlags;
416 mLoadFlags = 0;
418 if (mInheritPrincipal) {
419 MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(mPrincipalToInherit),
420 "Should not inherit SystemPrincipal");
421 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL;
424 if (!mSendReferrer) {
425 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
428 if (oldLoadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
429 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
432 if (oldLoadFlags & nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD) {
433 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_FIRST_LOAD;
436 if (oldLoadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CLASSIFIER) {
437 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER;
440 if (oldLoadFlags & nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_COOKIES) {
441 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
444 if (!mSrcdocData.IsVoid()) {
445 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC;
448 if (mForceAllowDataURI) {
449 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
452 if (mOriginalFrameSrc) {
453 mLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC;
457 DocShellLoadStateInit nsDocShellLoadState::Serialize() {
458 DocShellLoadStateInit loadState;
459 loadState.ResultPrincipalURIIsSome() = mResultPrincipalURIIsSome;
460 loadState.KeepResultPrincipalURIIfSet() = mKeepResultPrincipalURIIfSet;
461 loadState.LoadReplace() = mLoadReplace;
462 loadState.InheritPrincipal() = mInheritPrincipal;
463 loadState.PrincipalIsExplicit() = mPrincipalIsExplicit;
464 loadState.ForceAllowDataURI() = mForceAllowDataURI;
465 loadState.OriginalFrameSrc() = mOriginalFrameSrc;
466 loadState.SendReferrer() = mSendReferrer;
467 loadState.ReferrerPolicy() = mReferrerPolicy;
468 loadState.LoadType() = mLoadType;
469 loadState.Target() = mTarget;
470 loadState.LoadFlags() = mLoadFlags;
471 loadState.FirstParty() = mFirstParty;
472 loadState.TypeHint() = mTypeHint;
473 loadState.FileName() = mFileName;
474 loadState.IsFromProcessingFrameAttributes() =
475 mIsFromProcessingFrameAttributes;
476 loadState.Referrer() = mReferrer;
477 loadState.URI() = mURI;
478 loadState.OriginalURI() = mOriginalURI;
479 loadState.BaseURI() = mBaseURI;
480 loadState.TriggeringPrincipal() = mTriggeringPrincipal;
481 loadState.PrincipalToInherit() = mPrincipalToInherit;
482 return loadState;