SessionHistoryEntry.cpp (61583B)
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/. */ 6 7 #include "SessionHistoryEntry.h" 8 #include "ipc/IPCMessageUtilsSpecializations.h" 9 #include "nsDocShell.h" 10 #include "nsDocShellLoadState.h" 11 #include "nsFrameLoader.h" 12 #include "nsIFormPOSTActionChannel.h" 13 #include "nsIHttpChannel.h" 14 #include "nsIUploadChannel2.h" 15 #include "nsIXULRuntime.h" 16 #include "nsSHEntryShared.h" 17 #include "nsSHistory.h" 18 #include "nsStreamUtils.h" 19 #include "nsStructuredCloneContainer.h" 20 #include "nsXULAppAPI.h" 21 #include "mozilla/PresState.h" 22 #include "mozilla/StaticPrefs_fission.h" 23 #include "mozilla/dom/BindingIPCUtils.h" 24 #include "mozilla/dom/BrowserParent.h" 25 #include "mozilla/dom/CanonicalBrowsingContext.h" 26 #include "mozilla/dom/ContentChild.h" 27 #include "mozilla/dom/ContentParent.h" 28 #include "mozilla/dom/CSPMessageUtils.h" 29 #include "mozilla/dom/PolicyContainerMessageUtils.h" 30 #include "mozilla/dom/DocumentBinding.h" 31 #include "mozilla/dom/DOMTypes.h" 32 #include "mozilla/dom/NavigationAPIIPCUtils.h" 33 #include "mozilla/dom/nsCSPContext.h" 34 #include "mozilla/dom/nsCSPUtils.h" 35 #include "mozilla/dom/PermissionMessageUtils.h" 36 #include "mozilla/dom/PolicyContainer.h" 37 #include "mozilla/dom/ReferrerInfoUtils.h" 38 #include "mozilla/ipc/ProtocolUtils.h" 39 #include "mozilla/ipc/URIUtils.h" 40 41 extern mozilla::LazyLogModule gSHLog; 42 43 namespace mozilla { 44 namespace dom { 45 46 SessionHistoryInfo::SessionHistoryInfo(nsDocShellLoadState* aLoadState, 47 nsIChannel* aChannel) 48 : mURI(aLoadState->URI()), 49 mOriginalURI(aLoadState->OriginalURI()), 50 mResultPrincipalURI(aLoadState->ResultPrincipalURI()), 51 mUnstrippedURI(aLoadState->GetUnstrippedURI()), 52 mLoadType(aLoadState->LoadType()), 53 mSrcdocData(aLoadState->SrcdocData().IsVoid() 54 ? Nothing() 55 : Some(aLoadState->SrcdocData())), 56 mBaseURI(aLoadState->BaseURI()), 57 mNavigationAPIState(static_cast<nsStructuredCloneContainer*>( 58 aLoadState->GetNavigationAPIState())), 59 mLoadReplace(aLoadState->LoadReplace()), 60 mHasUserActivation(aLoadState->HasValidUserGestureActivation()), 61 mSharedState(SharedState::Create( 62 aLoadState->TriggeringPrincipal(), aLoadState->PrincipalToInherit(), 63 aLoadState->PartitionedPrincipalToInherit(), 64 aLoadState->PolicyContainer(), 65 /* FIXME Is this correct? */ 66 aLoadState->TypeHint())) { 67 // Pull the upload stream off of the channel instead of the load state, as 68 // ownership has already been transferred from the load state to the channel. 69 if (nsCOMPtr<nsIUploadChannel2> postChannel = do_QueryInterface(aChannel)) { 70 int64_t contentLength; 71 MOZ_ALWAYS_SUCCEEDS(postChannel->CloneUploadStream( 72 &contentLength, getter_AddRefs(mPostData))); 73 MOZ_ASSERT_IF(mPostData, NS_InputStreamIsCloneable(mPostData)); 74 } 75 76 if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) { 77 mReferrerInfo = httpChannel->GetReferrerInfo(); 78 } 79 80 MaybeUpdateTitleFromURI(); 81 } 82 83 SessionHistoryInfo::SessionHistoryInfo( 84 const SessionHistoryInfo& aSharedStateFrom, nsIURI* aURI) 85 : mURI(aURI), mSharedState(aSharedStateFrom.mSharedState) { 86 MaybeUpdateTitleFromURI(); 87 mHasUserInteraction = aSharedStateFrom.mHasUserInteraction; 88 } 89 90 SessionHistoryInfo::SessionHistoryInfo( 91 nsIURI* aURI, nsIPrincipal* aTriggeringPrincipal, 92 nsIPrincipal* aPrincipalToInherit, 93 nsIPrincipal* aPartitionedPrincipalToInherit, 94 nsIPolicyContainer* aPolicyContainer, const nsACString& aContentType) 95 : mURI(aURI), 96 mSharedState(SharedState::Create( 97 aTriggeringPrincipal, aPrincipalToInherit, 98 aPartitionedPrincipalToInherit, aPolicyContainer, aContentType)) { 99 MaybeUpdateTitleFromURI(); 100 } 101 102 SessionHistoryInfo::SessionHistoryInfo( 103 nsIChannel* aChannel, uint32_t aLoadType, 104 nsIPrincipal* aPartitionedPrincipalToInherit, 105 nsIPolicyContainer* aPolicyContainer) { 106 if (NS_FAILED(NS_GetFinalChannelURI(aChannel, getter_AddRefs(mURI)))) { 107 NS_WARNING("NS_GetFinalChannelURI somehow failed in SessionHistoryInfo?"); 108 aChannel->GetURI(getter_AddRefs(mURI)); 109 } 110 mLoadType = aLoadType; 111 112 nsCOMPtr<nsILoadInfo> loadInfo; 113 aChannel->GetLoadInfo(getter_AddRefs(loadInfo)); 114 115 loadInfo->GetResultPrincipalURI(getter_AddRefs(mResultPrincipalURI)); 116 loadInfo->GetUnstrippedURI(getter_AddRefs(mUnstrippedURI)); 117 loadInfo->GetTriggeringPrincipal( 118 getter_AddRefs(mSharedState.Get()->mTriggeringPrincipal)); 119 loadInfo->GetPrincipalToInherit( 120 getter_AddRefs(mSharedState.Get()->mPrincipalToInherit)); 121 122 mSharedState.Get()->mPartitionedPrincipalToInherit = 123 aPartitionedPrincipalToInherit; 124 mSharedState.Get()->mPolicyContainer = aPolicyContainer; 125 aChannel->GetContentType(mSharedState.Get()->mContentType); 126 aChannel->GetOriginalURI(getter_AddRefs(mOriginalURI)); 127 128 uint32_t loadFlags; 129 aChannel->GetLoadFlags(&loadFlags); 130 mLoadReplace = !!(loadFlags & nsIChannel::LOAD_REPLACE); 131 132 MaybeUpdateTitleFromURI(); 133 134 if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) { 135 mReferrerInfo = httpChannel->GetReferrerInfo(); 136 } 137 } 138 139 void SessionHistoryInfo::Reset(nsIURI* aURI, const nsID& aDocShellID, 140 bool aDynamicCreation, 141 nsIPrincipal* aTriggeringPrincipal, 142 nsIPrincipal* aPrincipalToInherit, 143 nsIPrincipal* aPartitionedPrincipalToInherit, 144 nsIPolicyContainer* aPolicyContainer, 145 const nsACString& aContentType) { 146 mURI = aURI; 147 mOriginalURI = nullptr; 148 mResultPrincipalURI = nullptr; 149 mUnstrippedURI = nullptr; 150 mReferrerInfo = nullptr; 151 // Default title is the URL. 152 nsAutoCString spec; 153 if (NS_SUCCEEDED(mURI->GetSpec(spec))) { 154 CopyUTF8toUTF16(spec, mTitle); 155 } 156 mPostData = nullptr; 157 mLoadType = 0; 158 mScrollPositionX = 0; 159 mScrollPositionY = 0; 160 mStateData = nullptr; 161 mSrcdocData = Nothing(); 162 mBaseURI = nullptr; 163 mLoadReplace = false; 164 mURIWasModified = false; 165 mScrollRestorationIsManual = false; 166 mTransient = false; 167 mHasUserInteraction = false; 168 mHasUserActivation = false; 169 mNavigationAPIState = nullptr; 170 171 mSharedState.Get()->mTriggeringPrincipal = aTriggeringPrincipal; 172 mSharedState.Get()->mPrincipalToInherit = aPrincipalToInherit; 173 mSharedState.Get()->mPartitionedPrincipalToInherit = 174 aPartitionedPrincipalToInherit; 175 mSharedState.Get()->mPolicyContainer = aPolicyContainer; 176 mSharedState.Get()->mContentType = aContentType; 177 mSharedState.Get()->mLayoutHistoryState = nullptr; 178 } 179 180 void SessionHistoryInfo::MaybeUpdateTitleFromURI() { 181 if (mTitle.IsEmpty() && mURI) { 182 // Default title is the URL. 183 nsAutoCString spec; 184 if (NS_SUCCEEDED(mURI->GetSpec(spec))) { 185 AppendUTF8toUTF16(spec, mTitle); 186 } 187 } 188 } 189 190 already_AddRefed<nsIInputStream> SessionHistoryInfo::GetPostData() const { 191 // Return a clone of our post data stream. Our caller will either be 192 // transferring this stream to a different SessionHistoryInfo, or passing it 193 // off to necko/another process which will consume it, and we want to preserve 194 // our local instance. 195 nsCOMPtr<nsIInputStream> postData; 196 if (mPostData) { 197 MOZ_ALWAYS_SUCCEEDS( 198 NS_CloneInputStream(mPostData, getter_AddRefs(postData))); 199 } 200 return postData.forget(); 201 } 202 203 void SessionHistoryInfo::SetPostData(nsIInputStream* aPostData) { 204 MOZ_ASSERT_IF(aPostData, NS_InputStreamIsCloneable(aPostData)); 205 mPostData = aPostData; 206 } 207 208 uint64_t SessionHistoryInfo::SharedId() const { 209 return mSharedState.Get()->mId; 210 } 211 212 nsILayoutHistoryState* SessionHistoryInfo::GetLayoutHistoryState() { 213 return mSharedState.Get()->mLayoutHistoryState; 214 } 215 216 void SessionHistoryInfo::SetLayoutHistoryState(nsILayoutHistoryState* aState) { 217 mSharedState.Get()->mLayoutHistoryState = aState; 218 if (mSharedState.Get()->mLayoutHistoryState) { 219 mSharedState.Get()->mLayoutHistoryState->SetScrollPositionOnly( 220 !mSharedState.Get()->mSaveLayoutState); 221 } 222 } 223 224 nsIPrincipal* SessionHistoryInfo::GetTriggeringPrincipal() const { 225 return mSharedState.Get()->mTriggeringPrincipal; 226 } 227 228 nsIPrincipal* SessionHistoryInfo::GetPrincipalToInherit() const { 229 return mSharedState.Get()->mPrincipalToInherit; 230 } 231 232 nsIPrincipal* SessionHistoryInfo::GetPartitionedPrincipalToInherit() const { 233 return mSharedState.Get()->mPartitionedPrincipalToInherit; 234 } 235 236 void SessionHistoryInfo::SetPartitionedPrincipalToInherit( 237 nsIPrincipal* aPartitionedPrincipal) { 238 mSharedState.Get()->mPartitionedPrincipalToInherit = aPartitionedPrincipal; 239 } 240 241 nsIPolicyContainer* SessionHistoryInfo::GetPolicyContainer() const { 242 return mSharedState.Get()->mPolicyContainer; 243 } 244 245 uint32_t SessionHistoryInfo::GetCacheKey() const { 246 return mSharedState.Get()->mCacheKey; 247 } 248 249 void SessionHistoryInfo::SetCacheKey(uint32_t aCacheKey) { 250 mSharedState.Get()->mCacheKey = aCacheKey; 251 } 252 253 bool SessionHistoryInfo::IsSubFrame() const { 254 return mSharedState.Get()->mIsFrameNavigation; 255 } 256 257 nsIStructuredCloneContainer* SessionHistoryInfo::GetNavigationAPIState() const { 258 return mNavigationAPIState.get(); 259 } 260 261 void SessionHistoryInfo::SetNavigationAPIState( 262 nsIStructuredCloneContainer* aState) { 263 mNavigationAPIState = static_cast<nsStructuredCloneContainer*>(aState); 264 } 265 266 void SessionHistoryInfo::SetSaveLayoutStateFlag(bool aSaveLayoutStateFlag) { 267 MOZ_ASSERT(XRE_IsParentProcess()); 268 static_cast<SHEntrySharedParentState*>(mSharedState.Get())->mSaveLayoutState = 269 aSaveLayoutStateFlag; 270 } 271 272 void SessionHistoryInfo::FillLoadInfo(nsDocShellLoadState& aLoadState) const { 273 aLoadState.SetOriginalURI(mOriginalURI); 274 aLoadState.SetMaybeResultPrincipalURI(Some(mResultPrincipalURI)); 275 aLoadState.SetUnstrippedURI(mUnstrippedURI); 276 aLoadState.SetLoadReplace(mLoadReplace); 277 nsCOMPtr<nsIInputStream> postData = GetPostData(); 278 aLoadState.SetPostDataStream(postData); 279 aLoadState.SetReferrerInfo(mReferrerInfo); 280 281 aLoadState.SetTypeHint(mSharedState.Get()->mContentType); 282 aLoadState.SetTriggeringPrincipal(mSharedState.Get()->mTriggeringPrincipal); 283 aLoadState.SetPrincipalToInherit(mSharedState.Get()->mPrincipalToInherit); 284 aLoadState.SetPartitionedPrincipalToInherit( 285 mSharedState.Get()->mPartitionedPrincipalToInherit); 286 aLoadState.SetPolicyContainer(mSharedState.Get()->mPolicyContainer); 287 288 // Do not inherit principal from document (security-critical!); 289 uint32_t flags = nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_NONE; 290 291 // Passing nullptr as aSourceDocShell gives the same behaviour as before 292 // aSourceDocShell was introduced. According to spec we should be passing 293 // the source browsing context that was used when the history entry was 294 // first created. bug 947716 has been created to address this issue. 295 nsAutoString srcdoc; 296 nsCOMPtr<nsIURI> baseURI; 297 if (mSrcdocData) { 298 srcdoc = mSrcdocData.value(); 299 baseURI = mBaseURI; 300 flags |= nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_IS_SRCDOC; 301 } else { 302 srcdoc = VoidString(); 303 } 304 aLoadState.SetSrcdocData(srcdoc); 305 aLoadState.SetBaseURI(baseURI); 306 aLoadState.SetInternalLoadFlags(flags); 307 308 aLoadState.SetFirstParty(true); 309 310 // When we create a load state from the history info we already know if 311 // https-first was able to upgrade the request from http to https. There is no 312 // point in re-retrying to upgrade. On a reload we still want to check, 313 // because the exemptions set by the user could have changed. 314 if ((mLoadType & nsIDocShell::LOAD_CMD_RELOAD) == 0) { 315 aLoadState.SetIsExemptFromHTTPSFirstMode(true); 316 } 317 } 318 /* static */ 319 SessionHistoryInfo::SharedState SessionHistoryInfo::SharedState::Create( 320 nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, 321 nsIPrincipal* aPartitionedPrincipalToInherit, 322 nsIPolicyContainer* aPolicyContainer, const nsACString& aContentType) { 323 if (XRE_IsParentProcess()) { 324 return SharedState(new SHEntrySharedParentState( 325 aTriggeringPrincipal, aPrincipalToInherit, 326 aPartitionedPrincipalToInherit, aPolicyContainer, aContentType)); 327 } 328 329 return SharedState(MakeUnique<SHEntrySharedState>( 330 aTriggeringPrincipal, aPrincipalToInherit, aPartitionedPrincipalToInherit, 331 aPolicyContainer, aContentType)); 332 } 333 334 SessionHistoryInfo::SharedState::SharedState() { Init(); } 335 336 SessionHistoryInfo::SharedState::SharedState( 337 const SessionHistoryInfo::SharedState& aOther) { 338 Init(aOther); 339 } 340 341 SessionHistoryInfo::SharedState::SharedState( 342 const Maybe<const SessionHistoryInfo::SharedState&>& aOther) { 343 if (aOther.isSome()) { 344 Init(aOther.ref()); 345 } else { 346 Init(); 347 } 348 } 349 350 SessionHistoryInfo::SharedState::~SharedState() { 351 if (XRE_IsParentProcess()) { 352 mParent 353 .RefPtr<SHEntrySharedParentState>::~RefPtr<SHEntrySharedParentState>(); 354 } else { 355 mChild.UniquePtr<SHEntrySharedState>::~unique_ptr< 356 SHEntrySharedState, DefaultDelete<SHEntrySharedState>>(); 357 } 358 } 359 360 SessionHistoryInfo::SharedState& SessionHistoryInfo::SharedState::operator=( 361 const SessionHistoryInfo::SharedState& aOther) { 362 if (this != &aOther) { 363 if (XRE_IsParentProcess()) { 364 mParent = aOther.mParent; 365 } else { 366 mChild = MakeUnique<SHEntrySharedState>(*aOther.mChild); 367 } 368 } 369 return *this; 370 } 371 372 SHEntrySharedState* SessionHistoryInfo::SharedState::Get() const { 373 if (XRE_IsParentProcess()) { 374 return mParent; 375 } 376 377 return mChild.get(); 378 } 379 380 void SessionHistoryInfo::SharedState::ChangeId(uint64_t aId) { 381 if (XRE_IsParentProcess()) { 382 mParent->ChangeId(aId); 383 } else { 384 mChild->mId = aId; 385 } 386 } 387 388 void SessionHistoryInfo::SharedState::Init() { 389 if (XRE_IsParentProcess()) { 390 new (&mParent) 391 RefPtr<SHEntrySharedParentState>(new SHEntrySharedParentState()); 392 } else { 393 new (&mChild) 394 UniquePtr<SHEntrySharedState>(MakeUnique<SHEntrySharedState>()); 395 } 396 } 397 398 void SessionHistoryInfo::SharedState::Init( 399 const SessionHistoryInfo::SharedState& aOther) { 400 if (XRE_IsParentProcess()) { 401 new (&mParent) RefPtr<SHEntrySharedParentState>(aOther.mParent); 402 } else { 403 new (&mChild) UniquePtr<SHEntrySharedState>( 404 MakeUnique<SHEntrySharedState>(*aOther.mChild)); 405 } 406 } 407 408 static uint64_t gLoadingSessionHistoryInfoLoadId = 0; 409 410 nsTHashMap<nsUint64HashKey, SessionHistoryEntry::LoadingEntry>* 411 SessionHistoryEntry::sLoadIdToEntry = nullptr; 412 413 LoadingSessionHistoryInfo::LoadingSessionHistoryInfo( 414 SessionHistoryEntry* aEntry) 415 : mInfo(aEntry->Info()), mLoadId(++gLoadingSessionHistoryInfoLoadId) { 416 SessionHistoryEntry::SetByLoadId(mLoadId, aEntry); 417 } 418 419 LoadingSessionHistoryInfo::LoadingSessionHistoryInfo( 420 SessionHistoryEntry* aEntry, const LoadingSessionHistoryInfo* aInfo) 421 : mInfo(aEntry->Info()), 422 mTriggeringEntry(aInfo->mTriggeringEntry), 423 mTriggeringNavigationType(aInfo->mTriggeringNavigationType), 424 mLoadId(aInfo->mLoadId), 425 mLoadIsFromSessionHistory(aInfo->mLoadIsFromSessionHistory), 426 mOffset(aInfo->mOffset), 427 mLoadingCurrentEntry(aInfo->mLoadingCurrentEntry) { 428 MOZ_ASSERT(SessionHistoryEntry::GetByLoadId(mLoadId)->mEntry == aEntry); 429 } 430 431 LoadingSessionHistoryInfo::LoadingSessionHistoryInfo( 432 const SessionHistoryInfo& aInfo) 433 : mInfo(aInfo), mLoadId(UINT64_MAX) {} 434 435 already_AddRefed<nsDocShellLoadState> 436 LoadingSessionHistoryInfo::CreateLoadInfo() const { 437 RefPtr<nsDocShellLoadState> loadState( 438 new nsDocShellLoadState(mInfo.GetURI())); 439 440 mInfo.FillLoadInfo(*loadState); 441 442 loadState->SetLoadingSessionHistoryInfo(*this); 443 444 return loadState.forget(); 445 } 446 447 static uint32_t gEntryID; 448 449 SessionHistoryEntry::LoadingEntry* SessionHistoryEntry::GetByLoadId( 450 uint64_t aLoadId) { 451 MOZ_ASSERT(XRE_IsParentProcess()); 452 if (!sLoadIdToEntry) { 453 return nullptr; 454 } 455 456 return sLoadIdToEntry->Lookup(aLoadId).DataPtrOrNull(); 457 } 458 459 void SessionHistoryEntry::SetByLoadId(uint64_t aLoadId, 460 SessionHistoryEntry* aEntry) { 461 if (!sLoadIdToEntry) { 462 sLoadIdToEntry = new nsTHashMap<nsUint64HashKey, LoadingEntry>(); 463 } 464 465 MOZ_LOG( 466 gSHLog, LogLevel::Verbose, 467 ("SessionHistoryEntry::SetByLoadId(%" PRIu64 " - %p)", aLoadId, aEntry)); 468 sLoadIdToEntry->InsertOrUpdate( 469 aLoadId, LoadingEntry{ 470 .mEntry = aEntry, 471 .mInfoSnapshotForValidation = 472 MakeUnique<SessionHistoryInfo>(aEntry->Info()), 473 }); 474 } 475 476 void SessionHistoryEntry::RemoveLoadId(uint64_t aLoadId) { 477 MOZ_ASSERT(XRE_IsParentProcess()); 478 if (!sLoadIdToEntry) { 479 return; 480 } 481 482 MOZ_LOG(gSHLog, LogLevel::Verbose, 483 ("SHEntry::RemoveLoadId(%" PRIu64 ")", aLoadId)); 484 sLoadIdToEntry->Remove(aLoadId); 485 } 486 487 SessionHistoryEntry::SessionHistoryEntry() 488 : mInfo(new SessionHistoryInfo()), mID(++gEntryID) { 489 MOZ_ASSERT(mozilla::SessionHistoryInParent()); 490 } 491 492 SessionHistoryEntry::SessionHistoryEntry(nsDocShellLoadState* aLoadState, 493 nsIChannel* aChannel) 494 : mInfo(new SessionHistoryInfo(aLoadState, aChannel)), mID(++gEntryID) { 495 MOZ_ASSERT(mozilla::SessionHistoryInParent()); 496 } 497 498 SessionHistoryEntry::SessionHistoryEntry(SessionHistoryInfo* aInfo) 499 : mInfo(MakeUnique<SessionHistoryInfo>(*aInfo)), mID(++gEntryID) { 500 MOZ_ASSERT(mozilla::SessionHistoryInParent()); 501 } 502 503 SessionHistoryEntry::SessionHistoryEntry(const SessionHistoryEntry& aEntry) 504 : mInfo(MakeUnique<SessionHistoryInfo>(*aEntry.mInfo)), 505 mParent(aEntry.mParent), 506 mID(aEntry.mID), 507 mBCHistoryLength(aEntry.mBCHistoryLength) { 508 MOZ_ASSERT(mozilla::SessionHistoryInParent()); 509 } 510 511 SessionHistoryEntry::~SessionHistoryEntry() { 512 // Null out the mParent pointers on all our kids. 513 for (nsISHEntry* entry : mChildren) { 514 if (entry) { 515 entry->SetParent(nullptr); 516 } 517 } 518 519 if (sLoadIdToEntry) { 520 sLoadIdToEntry->RemoveIf( 521 [this](auto& aIter) { return aIter.Data().mEntry == this; }); 522 if (sLoadIdToEntry->IsEmpty()) { 523 delete sLoadIdToEntry; 524 sLoadIdToEntry = nullptr; 525 } 526 } 527 } 528 529 NS_IMPL_ISUPPORTS(SessionHistoryEntry, nsISHEntry, SessionHistoryEntry, 530 nsISupportsWeakReference) 531 532 NS_IMETHODIMP 533 SessionHistoryEntry::GetURI(nsIURI** aURI) { 534 nsCOMPtr<nsIURI> uri = mInfo->mURI; 535 uri.forget(aURI); 536 return NS_OK; 537 } 538 539 NS_IMETHODIMP 540 SessionHistoryEntry::SetURI(nsIURI* aURI) { 541 mInfo->mURI = aURI; 542 return NS_OK; 543 } 544 545 NS_IMETHODIMP 546 SessionHistoryEntry::GetOriginalURI(nsIURI** aOriginalURI) { 547 nsCOMPtr<nsIURI> originalURI = mInfo->mOriginalURI; 548 originalURI.forget(aOriginalURI); 549 return NS_OK; 550 } 551 552 NS_IMETHODIMP 553 SessionHistoryEntry::SetOriginalURI(nsIURI* aOriginalURI) { 554 mInfo->mOriginalURI = aOriginalURI; 555 return NS_OK; 556 } 557 558 NS_IMETHODIMP 559 SessionHistoryEntry::GetResultPrincipalURI(nsIURI** aResultPrincipalURI) { 560 nsCOMPtr<nsIURI> resultPrincipalURI = mInfo->mResultPrincipalURI; 561 resultPrincipalURI.forget(aResultPrincipalURI); 562 return NS_OK; 563 } 564 565 NS_IMETHODIMP 566 SessionHistoryEntry::SetResultPrincipalURI(nsIURI* aResultPrincipalURI) { 567 mInfo->mResultPrincipalURI = aResultPrincipalURI; 568 return NS_OK; 569 } 570 571 NS_IMETHODIMP 572 SessionHistoryEntry::GetUnstrippedURI(nsIURI** aUnstrippedURI) { 573 nsCOMPtr<nsIURI> unstrippedURI = mInfo->mUnstrippedURI; 574 unstrippedURI.forget(aUnstrippedURI); 575 return NS_OK; 576 } 577 578 NS_IMETHODIMP 579 SessionHistoryEntry::SetUnstrippedURI(nsIURI* aUnstrippedURI) { 580 mInfo->mUnstrippedURI = aUnstrippedURI; 581 return NS_OK; 582 } 583 584 NS_IMETHODIMP 585 SessionHistoryEntry::GetLoadReplace(bool* aLoadReplace) { 586 *aLoadReplace = mInfo->mLoadReplace; 587 return NS_OK; 588 } 589 590 NS_IMETHODIMP 591 SessionHistoryEntry::SetLoadReplace(bool aLoadReplace) { 592 mInfo->mLoadReplace = aLoadReplace; 593 return NS_OK; 594 } 595 596 NS_IMETHODIMP 597 SessionHistoryEntry::GetTitle(nsAString& aTitle) { 598 aTitle = mInfo->mTitle; 599 return NS_OK; 600 } 601 602 NS_IMETHODIMP 603 SessionHistoryEntry::SetTitle(const nsAString& aTitle) { 604 mInfo->SetTitle(aTitle); 605 return NS_OK; 606 } 607 608 NS_IMETHODIMP 609 SessionHistoryEntry::GetName(nsAString& aName) { 610 aName = mInfo->mName; 611 return NS_OK; 612 } 613 614 NS_IMETHODIMP 615 SessionHistoryEntry::SetName(const nsAString& aName) { 616 mInfo->mName = aName; 617 return NS_OK; 618 } 619 620 NS_IMETHODIMP 621 SessionHistoryEntry::GetIsSubFrame(bool* aIsSubFrame) { 622 *aIsSubFrame = SharedInfo()->mIsFrameNavigation; 623 return NS_OK; 624 } 625 626 NS_IMETHODIMP 627 SessionHistoryEntry::SetIsSubFrame(bool aIsSubFrame) { 628 SharedInfo()->mIsFrameNavigation = aIsSubFrame; 629 return NS_OK; 630 } 631 632 NS_IMETHODIMP 633 SessionHistoryEntry::GetHasUserInteraction(bool* aFlag) { 634 // The back button and menulist deal with root/top-level 635 // session history entries, thus we annotate only the root entry. 636 if (!mParent) { 637 *aFlag = mInfo->mHasUserInteraction; 638 } else { 639 nsCOMPtr<nsISHEntry> root = nsSHistory::GetRootSHEntry(this); 640 root->GetHasUserInteraction(aFlag); 641 } 642 return NS_OK; 643 } 644 645 NS_IMETHODIMP 646 SessionHistoryEntry::SetHasUserInteraction(bool aFlag) { 647 // The back button and menulist deal with root/top-level 648 // session history entries, thus we annotate only the root entry. 649 if (!mParent) { 650 mInfo->mHasUserInteraction = aFlag; 651 } else { 652 nsCOMPtr<nsISHEntry> root = nsSHistory::GetRootSHEntry(this); 653 root->SetHasUserInteraction(aFlag); 654 } 655 return NS_OK; 656 } 657 658 NS_IMETHODIMP 659 SessionHistoryEntry::GetHasUserActivation(bool* aFlag) { 660 *aFlag = mInfo->mHasUserActivation; 661 return NS_OK; 662 } 663 664 NS_IMETHODIMP 665 SessionHistoryEntry::SetHasUserActivation(bool aFlag) { 666 mInfo->mHasUserActivation = aFlag; 667 return NS_OK; 668 } 669 670 NS_IMETHODIMP 671 SessionHistoryEntry::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) { 672 nsCOMPtr<nsIReferrerInfo> referrerInfo = mInfo->mReferrerInfo; 673 referrerInfo.forget(aReferrerInfo); 674 return NS_OK; 675 } 676 677 NS_IMETHODIMP 678 SessionHistoryEntry::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) { 679 mInfo->mReferrerInfo = aReferrerInfo; 680 return NS_OK; 681 } 682 683 NS_IMETHODIMP 684 SessionHistoryEntry::GetDocumentViewer(nsIDocumentViewer** aDocumentViewer) { 685 *aDocumentViewer = nullptr; 686 return NS_OK; 687 } 688 689 NS_IMETHODIMP 690 SessionHistoryEntry::SetDocumentViewer(nsIDocumentViewer* aDocumentViewer) { 691 MOZ_CRASH("This lives in the child process"); 692 return NS_ERROR_FAILURE; 693 } 694 695 NS_IMETHODIMP 696 SessionHistoryEntry::GetIsInBFCache(bool* aResult) { 697 *aResult = !!SharedInfo()->mFrameLoader; 698 return NS_OK; 699 } 700 701 NS_IMETHODIMP 702 SessionHistoryEntry::GetSticky(bool* aSticky) { 703 *aSticky = SharedInfo()->mSticky; 704 return NS_OK; 705 } 706 707 NS_IMETHODIMP 708 SessionHistoryEntry::SetSticky(bool aSticky) { 709 SharedInfo()->mSticky = aSticky; 710 return NS_OK; 711 } 712 713 NS_IMETHODIMP 714 SessionHistoryEntry::GetWindowState(nsISupports** aWindowState) { 715 MOZ_CRASH("This lives in the child process"); 716 return NS_ERROR_FAILURE; 717 } 718 719 NS_IMETHODIMP 720 SessionHistoryEntry::SetWindowState(nsISupports* aWindowState) { 721 MOZ_CRASH("This lives in the child process"); 722 return NS_ERROR_FAILURE; 723 } 724 725 NS_IMETHODIMP 726 SessionHistoryEntry::GetRefreshURIList(nsIMutableArray** aRefreshURIList) { 727 MOZ_CRASH("This lives in the child process"); 728 return NS_ERROR_FAILURE; 729 } 730 731 NS_IMETHODIMP 732 SessionHistoryEntry::SetRefreshURIList(nsIMutableArray* aRefreshURIList) { 733 MOZ_CRASH("This lives in the child process"); 734 return NS_ERROR_FAILURE; 735 } 736 737 NS_IMETHODIMP 738 SessionHistoryEntry::GetPostData(nsIInputStream** aPostData) { 739 *aPostData = mInfo->GetPostData().take(); 740 return NS_OK; 741 } 742 743 NS_IMETHODIMP 744 SessionHistoryEntry::SetPostData(nsIInputStream* aPostData) { 745 mInfo->SetPostData(aPostData); 746 return NS_OK; 747 } 748 749 NS_IMETHODIMP 750 SessionHistoryEntry::GetHasPostData(bool* aResult) { 751 *aResult = mInfo->HasPostData(); 752 return NS_OK; 753 } 754 755 NS_IMETHODIMP 756 SessionHistoryEntry::GetLayoutHistoryState( 757 nsILayoutHistoryState** aLayoutHistoryState) { 758 nsCOMPtr<nsILayoutHistoryState> layoutHistoryState = 759 SharedInfo()->mLayoutHistoryState; 760 layoutHistoryState.forget(aLayoutHistoryState); 761 return NS_OK; 762 } 763 764 NS_IMETHODIMP 765 SessionHistoryEntry::SetLayoutHistoryState( 766 nsILayoutHistoryState* aLayoutHistoryState) { 767 SharedInfo()->mLayoutHistoryState = aLayoutHistoryState; 768 if (SharedInfo()->mLayoutHistoryState) { 769 SharedInfo()->mLayoutHistoryState->SetScrollPositionOnly( 770 !SharedInfo()->mSaveLayoutState); 771 } 772 return NS_OK; 773 } 774 775 NS_IMETHODIMP 776 SessionHistoryEntry::GetParent(nsISHEntry** aParent) { 777 nsCOMPtr<nsISHEntry> parent = do_QueryReferent(mParent); 778 parent.forget(aParent); 779 return NS_OK; 780 } 781 782 NS_IMETHODIMP 783 SessionHistoryEntry::SetParent(nsISHEntry* aParent) { 784 mParent = do_GetWeakReference(aParent); 785 return NS_OK; 786 } 787 788 NS_IMETHODIMP 789 SessionHistoryEntry::GetLoadType(uint32_t* aLoadType) { 790 *aLoadType = mInfo->mLoadType; 791 return NS_OK; 792 } 793 794 NS_IMETHODIMP 795 SessionHistoryEntry::SetLoadType(uint32_t aLoadType) { 796 mInfo->mLoadType = aLoadType; 797 return NS_OK; 798 } 799 800 NS_IMETHODIMP 801 SessionHistoryEntry::GetID(uint32_t* aID) { 802 *aID = mID; 803 return NS_OK; 804 } 805 806 NS_IMETHODIMP 807 SessionHistoryEntry::SetID(uint32_t aID) { 808 mID = aID; 809 return NS_OK; 810 } 811 812 NS_IMETHODIMP 813 SessionHistoryEntry::GetCacheKey(uint32_t* aCacheKey) { 814 *aCacheKey = SharedInfo()->mCacheKey; 815 return NS_OK; 816 } 817 818 NS_IMETHODIMP 819 SessionHistoryEntry::SetCacheKey(uint32_t aCacheKey) { 820 SharedInfo()->mCacheKey = aCacheKey; 821 return NS_OK; 822 } 823 824 NS_IMETHODIMP 825 SessionHistoryEntry::GetSaveLayoutStateFlag(bool* aSaveLayoutStateFlag) { 826 *aSaveLayoutStateFlag = SharedInfo()->mSaveLayoutState; 827 return NS_OK; 828 } 829 830 NS_IMETHODIMP 831 SessionHistoryEntry::SetSaveLayoutStateFlag(bool aSaveLayoutStateFlag) { 832 SharedInfo()->mSaveLayoutState = aSaveLayoutStateFlag; 833 return NS_OK; 834 } 835 836 NS_IMETHODIMP 837 SessionHistoryEntry::GetContentType(nsACString& aContentType) { 838 aContentType = SharedInfo()->mContentType; 839 return NS_OK; 840 } 841 842 NS_IMETHODIMP 843 SessionHistoryEntry::SetContentType(const nsACString& aContentType) { 844 SharedInfo()->mContentType = aContentType; 845 return NS_OK; 846 } 847 848 NS_IMETHODIMP 849 SessionHistoryEntry::GetURIWasModified(bool* aURIWasModified) { 850 *aURIWasModified = mInfo->mURIWasModified; 851 return NS_OK; 852 } 853 854 NS_IMETHODIMP 855 SessionHistoryEntry::SetURIWasModified(bool aURIWasModified) { 856 mInfo->mURIWasModified = aURIWasModified; 857 return NS_OK; 858 } 859 860 NS_IMETHODIMP 861 SessionHistoryEntry::GetTriggeringPrincipal( 862 nsIPrincipal** aTriggeringPrincipal) { 863 nsCOMPtr<nsIPrincipal> triggeringPrincipal = 864 SharedInfo()->mTriggeringPrincipal; 865 triggeringPrincipal.forget(aTriggeringPrincipal); 866 return NS_OK; 867 } 868 869 NS_IMETHODIMP 870 SessionHistoryEntry::SetTriggeringPrincipal( 871 nsIPrincipal* aTriggeringPrincipal) { 872 SharedInfo()->mTriggeringPrincipal = aTriggeringPrincipal; 873 return NS_OK; 874 } 875 876 NS_IMETHODIMP 877 SessionHistoryEntry::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit) { 878 nsCOMPtr<nsIPrincipal> principalToInherit = SharedInfo()->mPrincipalToInherit; 879 principalToInherit.forget(aPrincipalToInherit); 880 return NS_OK; 881 } 882 883 NS_IMETHODIMP 884 SessionHistoryEntry::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit) { 885 SharedInfo()->mPrincipalToInherit = aPrincipalToInherit; 886 return NS_OK; 887 } 888 889 NS_IMETHODIMP 890 SessionHistoryEntry::GetPartitionedPrincipalToInherit( 891 nsIPrincipal** aPartitionedPrincipalToInherit) { 892 nsCOMPtr<nsIPrincipal> partitionedPrincipalToInherit = 893 SharedInfo()->mPartitionedPrincipalToInherit; 894 partitionedPrincipalToInherit.forget(aPartitionedPrincipalToInherit); 895 return NS_OK; 896 } 897 898 NS_IMETHODIMP 899 SessionHistoryEntry::SetPartitionedPrincipalToInherit( 900 nsIPrincipal* aPartitionedPrincipalToInherit) { 901 SharedInfo()->mPartitionedPrincipalToInherit = aPartitionedPrincipalToInherit; 902 return NS_OK; 903 } 904 905 NS_IMETHODIMP 906 SessionHistoryEntry::GetPolicyContainer(nsIPolicyContainer** aPolicyContainer) { 907 nsCOMPtr<nsIPolicyContainer> policyContainer = SharedInfo()->mPolicyContainer; 908 policyContainer.forget(aPolicyContainer); 909 return NS_OK; 910 } 911 912 NS_IMETHODIMP 913 SessionHistoryEntry::SetPolicyContainer(nsIPolicyContainer* aPolicyContainer) { 914 nsCOMPtr<nsIURI> uri = mInfo->mURI; 915 if (CSP_ShouldURIInheritCSP(uri)) { 916 SharedInfo()->mPolicyContainer = aPolicyContainer; 917 } 918 return NS_OK; 919 } 920 921 NS_IMETHODIMP 922 SessionHistoryEntry::GetStateData(nsIStructuredCloneContainer** aStateData) { 923 RefPtr<nsStructuredCloneContainer> stateData = mInfo->mStateData; 924 stateData.forget(aStateData); 925 return NS_OK; 926 } 927 928 NS_IMETHODIMP 929 SessionHistoryEntry::SetStateData(nsIStructuredCloneContainer* aStateData) { 930 mInfo->mStateData = static_cast<nsStructuredCloneContainer*>(aStateData); 931 return NS_OK; 932 } 933 934 const nsID& SessionHistoryEntry::DocshellID() const { 935 return SharedInfo()->mDocShellID; 936 } 937 938 NS_IMETHODIMP 939 SessionHistoryEntry::GetDocshellID(nsID& aDocshellID) { 940 aDocshellID = DocshellID(); 941 return NS_OK; 942 } 943 944 NS_IMETHODIMP 945 SessionHistoryEntry::SetDocshellID(const nsID& aDocshellID) { 946 SharedInfo()->mDocShellID = aDocshellID; 947 return NS_OK; 948 } 949 950 NS_IMETHODIMP 951 SessionHistoryEntry::GetNavigationKey(nsID& aNavigationKey) { 952 aNavigationKey = mInfo->NavigationKey(); 953 return NS_OK; 954 } 955 956 NS_IMETHODIMP 957 SessionHistoryEntry::SetNavigationKey(const nsID& aNavigationKey) { 958 mInfo->mNavigationKey = aNavigationKey; 959 return NS_OK; 960 } 961 962 NS_IMETHODIMP 963 SessionHistoryEntry::GetNavigationId(nsID& aNavigationId) { 964 aNavigationId = mInfo->NavigationId(); 965 return NS_OK; 966 } 967 968 NS_IMETHODIMP 969 SessionHistoryEntry::SetNavigationId(const nsID& aNavigationId) { 970 mInfo->mNavigationId = aNavigationId; 971 return NS_OK; 972 } 973 974 NS_IMETHODIMP 975 SessionHistoryEntry::GetIsSrcdocEntry(bool* aIsSrcdocEntry) { 976 *aIsSrcdocEntry = mInfo->mSrcdocData.isSome(); 977 return NS_OK; 978 } 979 980 NS_IMETHODIMP 981 SessionHistoryEntry::GetSrcdocData(nsAString& aSrcdocData) { 982 aSrcdocData = mInfo->mSrcdocData.valueOr(EmptyString()); 983 return NS_OK; 984 } 985 986 NS_IMETHODIMP 987 SessionHistoryEntry::SetSrcdocData(const nsAString& aSrcdocData) { 988 mInfo->mSrcdocData = Some(nsString(aSrcdocData)); 989 return NS_OK; 990 } 991 992 NS_IMETHODIMP 993 SessionHistoryEntry::GetBaseURI(nsIURI** aBaseURI) { 994 nsCOMPtr<nsIURI> baseURI = mInfo->mBaseURI; 995 baseURI.forget(aBaseURI); 996 return NS_OK; 997 } 998 999 NS_IMETHODIMP 1000 SessionHistoryEntry::SetBaseURI(nsIURI* aBaseURI) { 1001 mInfo->mBaseURI = aBaseURI; 1002 return NS_OK; 1003 } 1004 1005 NS_IMETHODIMP 1006 SessionHistoryEntry::GetScrollRestorationIsManual( 1007 bool* aScrollRestorationIsManual) { 1008 *aScrollRestorationIsManual = mInfo->mScrollRestorationIsManual; 1009 return NS_OK; 1010 } 1011 1012 NS_IMETHODIMP 1013 SessionHistoryEntry::SetScrollRestorationIsManual( 1014 bool aScrollRestorationIsManual) { 1015 mInfo->mScrollRestorationIsManual = aScrollRestorationIsManual; 1016 return NS_OK; 1017 } 1018 1019 NS_IMETHODIMP 1020 SessionHistoryEntry::GetLoadedInThisProcess(bool* aLoadedInThisProcess) { 1021 // FIXME 1022 //*aLoadedInThisProcess = mInfo->mLoadedInThisProcess; 1023 return NS_OK; 1024 } 1025 1026 NS_IMETHODIMP 1027 SessionHistoryEntry::GetShistory(nsISHistory** aShistory) { 1028 nsCOMPtr<nsISHistory> sHistory = do_QueryReferent(SharedInfo()->mSHistory); 1029 sHistory.forget(aShistory); 1030 return NS_OK; 1031 } 1032 1033 NS_IMETHODIMP 1034 SessionHistoryEntry::SetShistory(nsISHistory* aShistory) { 1035 nsWeakPtr shistory = do_GetWeakReference(aShistory); 1036 // mSHistory can not be changed once it's set 1037 MOZ_ASSERT(!SharedInfo()->mSHistory || (SharedInfo()->mSHistory == shistory)); 1038 SharedInfo()->mSHistory = shistory; 1039 return NS_OK; 1040 } 1041 1042 NS_IMETHODIMP 1043 SessionHistoryEntry::GetLastTouched(uint32_t* aLastTouched) { 1044 *aLastTouched = SharedInfo()->mLastTouched; 1045 return NS_OK; 1046 } 1047 1048 NS_IMETHODIMP 1049 SessionHistoryEntry::SetLastTouched(uint32_t aLastTouched) { 1050 SharedInfo()->mLastTouched = aLastTouched; 1051 return NS_OK; 1052 } 1053 1054 NS_IMETHODIMP 1055 SessionHistoryEntry::GetChildCount(int32_t* aChildCount) { 1056 *aChildCount = mChildren.Length(); 1057 return NS_OK; 1058 } 1059 1060 NS_IMETHODIMP 1061 SessionHistoryEntry::IsTransient(bool* aIsTransient) { 1062 *aIsTransient = mInfo->IsTransient(); 1063 return NS_OK; 1064 } 1065 1066 NS_IMETHODIMP 1067 SessionHistoryEntry::SetTransient() { 1068 mInfo->SetTransient(); 1069 return NS_OK; 1070 } 1071 1072 NS_IMETHODIMP 1073 SessionHistoryEntry::GetScrollPosition(int32_t* aX, int32_t* aY) { 1074 *aX = mInfo->mScrollPositionX; 1075 *aY = mInfo->mScrollPositionY; 1076 return NS_OK; 1077 } 1078 1079 NS_IMETHODIMP 1080 SessionHistoryEntry::SetScrollPosition(int32_t aX, int32_t aY) { 1081 mInfo->mScrollPositionX = aX; 1082 mInfo->mScrollPositionY = aY; 1083 return NS_OK; 1084 } 1085 1086 NS_IMETHODIMP_(void) 1087 SessionHistoryEntry::GetViewerBounds(nsIntRect& bounds) { 1088 bounds = SharedInfo()->mViewerBounds; 1089 } 1090 1091 NS_IMETHODIMP_(void) 1092 SessionHistoryEntry::SetViewerBounds(const nsIntRect& bounds) { 1093 SharedInfo()->mViewerBounds = bounds; 1094 } 1095 1096 NS_IMETHODIMP_(void) 1097 SessionHistoryEntry::AddChildShell(nsIDocShellTreeItem* shell) { 1098 MOZ_CRASH("This lives in the child process"); 1099 } 1100 1101 NS_IMETHODIMP 1102 SessionHistoryEntry::ChildShellAt(int32_t index, 1103 nsIDocShellTreeItem** _retval) { 1104 MOZ_CRASH("This lives in the child process"); 1105 return NS_ERROR_FAILURE; 1106 } 1107 1108 NS_IMETHODIMP_(void) 1109 SessionHistoryEntry::ClearChildShells() { 1110 MOZ_CRASH("This lives in the child process"); 1111 } 1112 1113 NS_IMETHODIMP_(void) 1114 SessionHistoryEntry::SyncPresentationState() { 1115 MOZ_CRASH("This lives in the child process"); 1116 } 1117 1118 NS_IMETHODIMP 1119 SessionHistoryEntry::InitLayoutHistoryState( 1120 nsILayoutHistoryState** aLayoutHistoryState) { 1121 if (!SharedInfo()->mLayoutHistoryState) { 1122 nsCOMPtr<nsILayoutHistoryState> historyState; 1123 historyState = NS_NewLayoutHistoryState(); 1124 SetLayoutHistoryState(historyState); 1125 } 1126 1127 return GetLayoutHistoryState(aLayoutHistoryState); 1128 } 1129 1130 NS_IMETHODIMP 1131 SessionHistoryEntry::Create( 1132 nsIURI* aURI, const nsAString& aTitle, nsIInputStream* aInputStream, 1133 uint32_t aCacheKey, const nsACString& aContentType, 1134 nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, 1135 nsIPrincipal* aPartitionedPrincipalToInherit, 1136 nsIPolicyContainer* aPolicyContainer, const nsID& aDocshellID, 1137 bool aDynamicCreation, nsIURI* aOriginalURI, nsIURI* aResultPrincipalURI, 1138 nsIURI* aUnstrippedURI, bool aLoadReplace, nsIReferrerInfo* aReferrerInfo, 1139 const nsAString& aSrcdoc, bool aSrcdocEntry, nsIURI* aBaseURI, 1140 bool aSaveLayoutState, bool aExpired, bool aUserActivation) { 1141 MOZ_CRASH("Might need to implement this"); 1142 return NS_ERROR_NOT_IMPLEMENTED; 1143 } 1144 1145 NS_IMETHODIMP 1146 SessionHistoryEntry::Clone(nsISHEntry** aEntry) { 1147 RefPtr<SessionHistoryEntry> entry = new SessionHistoryEntry(*this); 1148 1149 // These are not copied for some reason, we're not sure why. 1150 entry->mInfo->mLoadType = 0; 1151 entry->mInfo->mScrollPositionX = 0; 1152 entry->mInfo->mScrollPositionY = 0; 1153 entry->mInfo->mScrollRestorationIsManual = false; 1154 1155 entry->mInfo->mHasUserInteraction = false; 1156 1157 entry.forget(aEntry); 1158 1159 return NS_OK; 1160 } 1161 1162 NS_IMETHODIMP_(nsDocShellEditorData*) 1163 SessionHistoryEntry::ForgetEditorData() { 1164 MOZ_CRASH("This lives in the child process"); 1165 return nullptr; 1166 } 1167 1168 NS_IMETHODIMP_(void) 1169 SessionHistoryEntry::SetEditorData(nsDocShellEditorData* aData) { 1170 NS_WARNING("This lives in the child process"); 1171 } 1172 1173 NS_IMETHODIMP_(bool) 1174 SessionHistoryEntry::HasDetachedEditor() { 1175 NS_WARNING("This lives in the child process"); 1176 return false; 1177 } 1178 1179 NS_IMETHODIMP_(bool) 1180 SessionHistoryEntry::IsDynamicallyAdded() { 1181 return SharedInfo()->mDynamicallyCreated; 1182 } 1183 1184 void SessionHistoryEntry::SetWireframe(const Maybe<Wireframe>& aWireframe) { 1185 mWireframe = aWireframe; 1186 } 1187 1188 void SessionHistoryEntry::SetIsDynamicallyAdded(bool aDynamic) { 1189 MOZ_ASSERT_IF(SharedInfo()->mDynamicallyCreated, aDynamic); 1190 SharedInfo()->mDynamicallyCreated = aDynamic; 1191 } 1192 1193 NS_IMETHODIMP 1194 SessionHistoryEntry::HasDynamicallyAddedChild(bool* aHasDynamicallyAddedChild) { 1195 for (const auto& child : mChildren) { 1196 if (child && child->IsDynamicallyAdded()) { 1197 *aHasDynamicallyAddedChild = true; 1198 return NS_OK; 1199 } 1200 } 1201 *aHasDynamicallyAddedChild = false; 1202 return NS_OK; 1203 } 1204 1205 NS_IMETHODIMP_(bool) 1206 SessionHistoryEntry::HasBFCacheEntry(SHEntrySharedParentState* aEntry) { 1207 return SharedInfo() == aEntry; 1208 } 1209 1210 NS_IMETHODIMP 1211 SessionHistoryEntry::AdoptBFCacheEntry(nsISHEntry* aEntry) { 1212 nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(aEntry); 1213 NS_ENSURE_STATE(she && she->mInfo->mSharedState.Get()); 1214 1215 mInfo->mSharedState = 1216 static_cast<SessionHistoryEntry*>(aEntry)->mInfo->mSharedState; 1217 1218 return NS_OK; 1219 } 1220 1221 NS_IMETHODIMP 1222 SessionHistoryEntry::AbandonBFCacheEntry() { 1223 MOZ_CRASH("This lives in the child process"); 1224 return NS_ERROR_FAILURE; 1225 } 1226 1227 NS_IMETHODIMP 1228 SessionHistoryEntry::SharesDocumentWith(nsISHEntry* aEntry, 1229 bool* aSharesDocumentWith) { 1230 SessionHistoryEntry* entry = static_cast<SessionHistoryEntry*>(aEntry); 1231 1232 MOZ_ASSERT_IF(entry->SharedInfo() != SharedInfo(), 1233 entry->SharedInfo()->GetId() != SharedInfo()->GetId()); 1234 1235 *aSharesDocumentWith = entry->SharedInfo() == SharedInfo(); 1236 return NS_OK; 1237 } 1238 1239 NS_IMETHODIMP 1240 SessionHistoryEntry::SetLoadTypeAsHistory() { 1241 mInfo->mLoadType = LOAD_HISTORY; 1242 return NS_OK; 1243 } 1244 1245 NS_IMETHODIMP 1246 SessionHistoryEntry::AddChild(nsISHEntry* aChild, int32_t aOffset, 1247 bool aUseRemoteSubframes) { 1248 nsCOMPtr<SessionHistoryEntry> child = do_QueryInterface(aChild); 1249 MOZ_ASSERT_IF(aChild, child); 1250 AddChild(child, aOffset, aUseRemoteSubframes); 1251 1252 return NS_OK; 1253 } 1254 1255 void SessionHistoryEntry::AddChild(SessionHistoryEntry* aChild, int32_t aOffset, 1256 bool aUseRemoteSubframes) { 1257 if (aChild) { 1258 aChild->SetParent(this); 1259 } 1260 1261 if (aOffset < 0) { 1262 mChildren.AppendElement(aChild); 1263 return; 1264 } 1265 1266 // 1267 // Bug 52670: Ensure children are added in order. 1268 // 1269 // Later frames in the child list may load faster and get appended 1270 // before earlier frames, causing session history to be scrambled. 1271 // By growing the list here, they are added to the right position. 1272 1273 int32_t length = mChildren.Length(); 1274 1275 // Assert that aOffset will not be so high as to grow us a lot. 1276 NS_ASSERTION(aOffset < length + 1023, "Large frames array!\n"); 1277 1278 // If the new child is dynamically added, try to add it to aOffset, but if 1279 // there are non-dynamically added children, the child must be after those. 1280 if (aChild && aChild->IsDynamicallyAdded()) { 1281 int32_t lastNonDyn = aOffset - 1; 1282 for (int32_t i = aOffset; i < length; ++i) { 1283 SessionHistoryEntry* entry = mChildren[i]; 1284 if (entry) { 1285 if (entry->IsDynamicallyAdded()) { 1286 break; 1287 } 1288 1289 lastNonDyn = i; 1290 } 1291 } 1292 1293 // If aOffset is larger than Length(), we must first truncate the array. 1294 if (aOffset > length) { 1295 mChildren.SetLength(aOffset); 1296 } 1297 1298 mChildren.InsertElementAt(lastNonDyn + 1, aChild); 1299 1300 return; 1301 } 1302 1303 // If the new child isn't dynamically added, it should be set to aOffset. 1304 // If there are dynamically added children before that, those must be moved 1305 // to be after aOffset. 1306 if (length > 0) { 1307 int32_t start = std::min(length - 1, aOffset); 1308 int32_t dynEntryIndex = -1; 1309 DebugOnly<SessionHistoryEntry*> dynEntry = nullptr; 1310 for (int32_t i = start; i >= 0; --i) { 1311 SessionHistoryEntry* entry = mChildren[i]; 1312 if (entry) { 1313 if (!entry->IsDynamicallyAdded()) { 1314 break; 1315 } 1316 1317 dynEntryIndex = i; 1318 dynEntry = entry; 1319 } 1320 } 1321 1322 if (dynEntryIndex >= 0) { 1323 mChildren.InsertElementsAt(dynEntryIndex, aOffset - dynEntryIndex + 1); 1324 NS_ASSERTION(mChildren[aOffset + 1] == dynEntry, "Whaat?"); 1325 } 1326 } 1327 1328 // Make sure there isn't anything at aOffset. 1329 if ((uint32_t)aOffset < mChildren.Length()) { 1330 SessionHistoryEntry* oldChild = mChildren[aOffset]; 1331 if (oldChild && oldChild != aChild) { 1332 // Under Fission, this can happen when a network-created iframe starts 1333 // out in-process, moves out-of-process, and then switches back. At that 1334 // point, we'll create a new network-created DocShell at the same index 1335 // where we already have an entry for the original network-created 1336 // DocShell. 1337 // 1338 // This should ideally stop being an issue once the Fission-aware 1339 // session history rewrite is complete. 1340 NS_ASSERTION( 1341 aUseRemoteSubframes || NS_IsAboutBlank(oldChild->Info().GetURI()), 1342 "Adding a child where we already have a child? This may misbehave"); 1343 oldChild->SetParent(nullptr); 1344 } 1345 } else { 1346 mChildren.SetLength(aOffset + 1); 1347 } 1348 1349 mChildren.ReplaceElementAt(aOffset, aChild); 1350 } 1351 1352 NS_IMETHODIMP 1353 SessionHistoryEntry::RemoveChild(nsISHEntry* aChild) { 1354 NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE); 1355 1356 nsCOMPtr<SessionHistoryEntry> child = do_QueryInterface(aChild); 1357 MOZ_ASSERT(child); 1358 RemoveChild(child); 1359 1360 return NS_OK; 1361 } 1362 1363 void SessionHistoryEntry::RemoveChild(SessionHistoryEntry* aChild) { 1364 bool childRemoved = false; 1365 if (aChild->IsDynamicallyAdded()) { 1366 childRemoved = mChildren.RemoveElement(aChild); 1367 } else { 1368 int32_t index = mChildren.IndexOf(aChild); 1369 if (index >= 0) { 1370 // Other alive non-dynamic child docshells still keep mChildOffset, 1371 // so we don't want to change the indices here. 1372 mChildren.ReplaceElementAt(index, nullptr); 1373 childRemoved = true; 1374 } 1375 } 1376 1377 if (childRemoved) { 1378 aChild->SetParent(nullptr); 1379 1380 // reduce the child count, i.e. remove empty children at the end 1381 for (int32_t i = mChildren.Length() - 1; i >= 0 && !mChildren[i]; --i) { 1382 mChildren.RemoveElementAt(i); 1383 } 1384 } 1385 } 1386 1387 NS_IMETHODIMP 1388 SessionHistoryEntry::GetChildAt(int32_t aIndex, nsISHEntry** aChild) { 1389 nsCOMPtr<nsISHEntry> child = mChildren.SafeElementAt(aIndex); 1390 child.forget(aChild); 1391 return NS_OK; 1392 } 1393 1394 NS_IMETHODIMP_(void) 1395 SessionHistoryEntry::GetChildSHEntryIfHasNoDynamicallyAddedChild( 1396 int32_t aChildOffset, nsISHEntry** aChild) { 1397 *aChild = nullptr; 1398 1399 bool dynamicallyAddedChild = false; 1400 HasDynamicallyAddedChild(&dynamicallyAddedChild); 1401 if (dynamicallyAddedChild) { 1402 return; 1403 } 1404 1405 // If the user did a shift-reload on this frameset page, 1406 // we don't want to load the subframes from history. 1407 if (IsForceReloadType(mInfo->mLoadType) || mInfo->mLoadType == LOAD_REFRESH) { 1408 return; 1409 } 1410 1411 /* Before looking for the subframe's url, check 1412 * the expiration status of the parent. If the parent 1413 * has expired from cache, then subframes will not be 1414 * loaded from history in certain situations. 1415 * If the user pressed reload and the parent frame has expired 1416 * from cache, we do not want to load the child frame from history. 1417 */ 1418 if (SharedInfo()->mExpired && (mInfo->mLoadType == LOAD_RELOAD_NORMAL)) { 1419 // The parent has expired. Return null. 1420 *aChild = nullptr; 1421 return; 1422 } 1423 // Get the child subframe from session history. 1424 GetChildAt(aChildOffset, aChild); 1425 if (*aChild) { 1426 // Set the parent's Load Type on the child 1427 (*aChild)->SetLoadType(mInfo->mLoadType); 1428 } 1429 } 1430 1431 NS_IMETHODIMP 1432 SessionHistoryEntry::ReplaceChild(nsISHEntry* aNewChild) { 1433 NS_ENSURE_STATE(aNewChild); 1434 1435 nsCOMPtr<SessionHistoryEntry> newChild = do_QueryInterface(aNewChild); 1436 MOZ_ASSERT(newChild); 1437 return ReplaceChild(newChild) ? NS_OK : NS_ERROR_FAILURE; 1438 } 1439 1440 bool SessionHistoryEntry::ReplaceChild(SessionHistoryEntry* aNewChild) { 1441 const nsID& docshellID = aNewChild->DocshellID(); 1442 1443 for (uint32_t i = 0; i < mChildren.Length(); ++i) { 1444 if (mChildren[i] && docshellID == mChildren[i]->DocshellID()) { 1445 mChildren[i]->SetParent(nullptr); 1446 mChildren.ReplaceElementAt(i, aNewChild); 1447 aNewChild->SetParent(this); 1448 1449 return true; 1450 } 1451 } 1452 1453 return false; 1454 } 1455 1456 NS_IMETHODIMP_(void) 1457 SessionHistoryEntry::ClearEntry() { 1458 int32_t childCount = GetChildCount(); 1459 // Remove all children of this entry 1460 for (int32_t i = childCount; i > 0; --i) { 1461 nsCOMPtr<nsISHEntry> child; 1462 GetChildAt(i - 1, getter_AddRefs(child)); 1463 RemoveChild(child); 1464 } 1465 } 1466 1467 NS_IMETHODIMP 1468 SessionHistoryEntry::CreateLoadInfo(nsDocShellLoadState** aLoadState) { 1469 NS_WARNING("We shouldn't be calling this!"); 1470 return NS_OK; 1471 } 1472 1473 NS_IMETHODIMP 1474 SessionHistoryEntry::GetBfcacheID(uint64_t* aBfcacheID) { 1475 *aBfcacheID = SharedInfo()->mId; 1476 return NS_OK; 1477 } 1478 1479 NS_IMETHODIMP 1480 SessionHistoryEntry::GetWireframe(JSContext* aCx, 1481 JS::MutableHandle<JS::Value> aOut) { 1482 if (mWireframe.isNothing()) { 1483 aOut.set(JS::NullValue()); 1484 } else if (NS_WARN_IF(!mWireframe->ToObjectInternal(aCx, aOut))) { 1485 return NS_ERROR_FAILURE; 1486 } 1487 return NS_OK; 1488 } 1489 1490 NS_IMETHODIMP 1491 SessionHistoryEntry::SetWireframe(JSContext* aCx, JS::Handle<JS::Value> aArg) { 1492 if (aArg.isNullOrUndefined()) { 1493 mWireframe = Nothing(); 1494 return NS_OK; 1495 } 1496 1497 Wireframe wireframe; 1498 if (aArg.isObject() && wireframe.Init(aCx, aArg)) { 1499 mWireframe = Some(std::move(wireframe)); 1500 return NS_OK; 1501 } 1502 1503 return NS_ERROR_INVALID_ARG; 1504 } 1505 1506 NS_IMETHODIMP_(void) 1507 SessionHistoryEntry::SyncTreesForSubframeNavigation( 1508 nsISHEntry* aEntry, mozilla::dom::BrowsingContext* aTopBC, 1509 mozilla::dom::BrowsingContext* aIgnoreBC) { 1510 // XXX Keep this in sync with nsSHEntry::SyncTreesForSubframeNavigation. 1511 // 1512 // We need to sync up the browsing context and session history trees for 1513 // subframe navigation. If the load was in a subframe, we forward up to 1514 // the top browsing context, which will then recursively sync up all browsing 1515 // contexts to their corresponding entries in the new session history tree. If 1516 // we don't do this, then we can cache a content viewer on the wrong cloned 1517 // entry, and subsequently restore it at the wrong time. 1518 nsCOMPtr<nsISHEntry> newRootEntry = nsSHistory::GetRootSHEntry(aEntry); 1519 if (newRootEntry) { 1520 // newRootEntry is now the new root entry. 1521 // Find the old root entry as well. 1522 1523 // Need a strong ref. on |oldRootEntry| so it isn't destroyed when 1524 // SetChildHistoryEntry() does SwapHistoryEntries() (bug 304639). 1525 nsCOMPtr<nsISHEntry> oldRootEntry = nsSHistory::GetRootSHEntry(this); 1526 1527 if (oldRootEntry) { 1528 nsSHistory::SwapEntriesData data = {aIgnoreBC, newRootEntry, nullptr}; 1529 nsSHistory::SetChildHistoryEntry(oldRootEntry, aTopBC, 0, &data); 1530 } 1531 } 1532 } 1533 1534 void SessionHistoryEntry::ReplaceWith(const SessionHistoryEntry& aSource) { 1535 mInfo = MakeUnique<SessionHistoryInfo>(*aSource.mInfo); 1536 mChildren.Clear(); 1537 } 1538 1539 SHEntrySharedParentState* SessionHistoryEntry::SharedInfo() const { 1540 return static_cast<SHEntrySharedParentState*>(mInfo->mSharedState.Get()); 1541 } 1542 1543 void SessionHistoryEntry::SetFrameLoader(nsFrameLoader* aFrameLoader) { 1544 MOZ_DIAGNOSTIC_ASSERT(!aFrameLoader || !SharedInfo()->mFrameLoader); 1545 // If the pref is disabled, we still allow evicting the existing entries. 1546 MOZ_RELEASE_ASSERT(!aFrameLoader || mozilla::BFCacheInParent()); 1547 SharedInfo()->SetFrameLoader(aFrameLoader); 1548 if (aFrameLoader) { 1549 if (BrowsingContext* bc = aFrameLoader->GetMaybePendingBrowsingContext()) { 1550 if (BrowserParent* bp = bc->Canonical()->GetBrowserParent()) { 1551 bp->VisitAll([&](BrowserParent* aBp) { aBp->Deactivated(); }); 1552 } 1553 } 1554 1555 // When a new frameloader is stored, try to evict some older 1556 // frameloaders. Non-SHIP session history has a similar call in 1557 // nsDocumentViewer::Show. 1558 nsCOMPtr<nsISHistory> shistory; 1559 GetShistory(getter_AddRefs(shistory)); 1560 if (shistory) { 1561 int32_t index = 0; 1562 shistory->GetIndex(&index); 1563 shistory->EvictOutOfRangeDocumentViewers(index); 1564 } 1565 } 1566 } 1567 1568 nsFrameLoader* SessionHistoryEntry::GetFrameLoader() { 1569 return SharedInfo()->mFrameLoader; 1570 } 1571 1572 void SessionHistoryEntry::SetInfo(SessionHistoryInfo* aInfo) { 1573 // FIXME Assert that we're not changing shared state! 1574 mInfo = MakeUnique<SessionHistoryInfo>(*aInfo); 1575 } 1576 1577 already_AddRefed<nsIURI> SessionHistoryInfo::GetURIOrInheritedForAboutBlank() 1578 const { 1579 if (mURI && NS_IsAboutBlankAllowQueryAndFragment(mURI)) { 1580 auto* principal = GetPrincipalToInherit(); 1581 if (principal) { 1582 return principal->GetURI(); 1583 } 1584 } 1585 return do_AddRef(mURI); 1586 } 1587 1588 already_AddRefed<nsIURI> SessionHistoryEntry::GetURIOrInheritedForAboutBlank() 1589 const { 1590 return mInfo->GetURIOrInheritedForAboutBlank(); 1591 } 1592 1593 } // namespace dom 1594 } // namespace mozilla 1595 1596 namespace IPC { 1597 1598 void ParamTraits<mozilla::dom::SessionHistoryInfo>::Write( 1599 IPC::MessageWriter* aWriter, 1600 const mozilla::dom::SessionHistoryInfo& aParam) { 1601 nsCOMPtr<nsIInputStream> postData = aParam.GetPostData(); 1602 1603 mozilla::Maybe<std::tuple<uint32_t, mozilla::dom::ClonedMessageData>> 1604 stateData; 1605 if (aParam.mStateData) { 1606 stateData.emplace(); 1607 // FIXME: We should fail more aggressively if this fails, as currently we'll 1608 // just early return and the deserialization will break. 1609 NS_ENSURE_SUCCESS_VOID( 1610 aParam.mStateData->GetFormatVersion(&std::get<0>(*stateData))); 1611 NS_ENSURE_TRUE_VOID( 1612 aParam.mStateData->BuildClonedMessageData(std::get<1>(*stateData))); 1613 } 1614 1615 mozilla::Maybe<std::tuple<uint32_t, mozilla::dom::ClonedMessageData>> 1616 navigationState; 1617 if (aParam.mNavigationAPIState) { 1618 navigationState.emplace(); 1619 NS_ENSURE_SUCCESS_VOID(aParam.mNavigationAPIState->GetFormatVersion( 1620 &std::get<0>(*navigationState))); 1621 NS_ENSURE_TRUE_VOID(aParam.mNavigationAPIState->BuildClonedMessageData( 1622 std::get<1>(*navigationState))); 1623 } 1624 1625 WriteParam(aWriter, aParam.mURI); 1626 WriteParam(aWriter, aParam.mOriginalURI); 1627 WriteParam(aWriter, aParam.mResultPrincipalURI); 1628 WriteParam(aWriter, aParam.mUnstrippedURI); 1629 WriteParam(aWriter, aParam.mReferrerInfo); 1630 WriteParam(aWriter, aParam.mTitle); 1631 WriteParam(aWriter, aParam.mName); 1632 WriteParam(aWriter, postData); 1633 WriteParam(aWriter, aParam.mLoadType); 1634 WriteParam(aWriter, aParam.mScrollPositionX); 1635 WriteParam(aWriter, aParam.mScrollPositionY); 1636 WriteParam(aWriter, stateData); 1637 WriteParam(aWriter, aParam.mSrcdocData); 1638 WriteParam(aWriter, aParam.mBaseURI); 1639 WriteParam(aWriter, aParam.mNavigationKey); 1640 WriteParam(aWriter, aParam.mNavigationId); 1641 WriteParam(aWriter, aParam.mLoadReplace); 1642 WriteParam(aWriter, aParam.mURIWasModified); 1643 WriteParam(aWriter, aParam.mScrollRestorationIsManual); 1644 WriteParam(aWriter, aParam.mTransient); 1645 WriteParam(aWriter, aParam.mHasUserInteraction); 1646 WriteParam(aWriter, aParam.mHasUserActivation); 1647 WriteParam(aWriter, aParam.mSharedState.Get()->mId); 1648 WriteParam(aWriter, aParam.mSharedState.Get()->mTriggeringPrincipal); 1649 WriteParam(aWriter, aParam.mSharedState.Get()->mPrincipalToInherit); 1650 WriteParam(aWriter, 1651 aParam.mSharedState.Get()->mPartitionedPrincipalToInherit); 1652 WriteParam(aWriter, aParam.mSharedState.Get()->mPolicyContainer); 1653 WriteParam(aWriter, aParam.mSharedState.Get()->mContentType); 1654 WriteParam(aWriter, aParam.mSharedState.Get()->mLayoutHistoryState); 1655 WriteParam(aWriter, aParam.mSharedState.Get()->mCacheKey); 1656 WriteParam(aWriter, aParam.mSharedState.Get()->mIsFrameNavigation); 1657 WriteParam(aWriter, aParam.mSharedState.Get()->mSaveLayoutState); 1658 WriteParam(aWriter, navigationState); 1659 } 1660 1661 bool ParamTraits<mozilla::dom::SessionHistoryInfo>::Read( 1662 IPC::MessageReader* aReader, mozilla::dom::SessionHistoryInfo* aResult) { 1663 mozilla::Maybe<std::tuple<uint32_t, mozilla::dom::ClonedMessageData>> 1664 stateData; 1665 uint64_t sharedId; 1666 if (!ReadParam(aReader, &aResult->mURI) || 1667 !ReadParam(aReader, &aResult->mOriginalURI) || 1668 !ReadParam(aReader, &aResult->mResultPrincipalURI) || 1669 !ReadParam(aReader, &aResult->mUnstrippedURI) || 1670 !ReadParam(aReader, &aResult->mReferrerInfo) || 1671 !ReadParam(aReader, &aResult->mTitle) || 1672 !ReadParam(aReader, &aResult->mName) || 1673 !ReadParam(aReader, &aResult->mPostData) || 1674 !ReadParam(aReader, &aResult->mLoadType) || 1675 !ReadParam(aReader, &aResult->mScrollPositionX) || 1676 !ReadParam(aReader, &aResult->mScrollPositionY) || 1677 !ReadParam(aReader, &stateData) || 1678 !ReadParam(aReader, &aResult->mSrcdocData) || 1679 !ReadParam(aReader, &aResult->mBaseURI) || 1680 !ReadParam(aReader, &aResult->mNavigationKey) || 1681 !ReadParam(aReader, &aResult->mNavigationId) || 1682 !ReadParam(aReader, &aResult->mLoadReplace) || 1683 !ReadParam(aReader, &aResult->mURIWasModified) || 1684 !ReadParam(aReader, &aResult->mScrollRestorationIsManual) || 1685 !ReadParam(aReader, &aResult->mTransient) || 1686 !ReadParam(aReader, &aResult->mHasUserInteraction) || 1687 !ReadParam(aReader, &aResult->mHasUserActivation) || 1688 !ReadParam(aReader, &sharedId)) { 1689 aReader->FatalError("Error reading fields for SessionHistoryInfo"); 1690 return false; 1691 } 1692 1693 nsCOMPtr<nsIPrincipal> triggeringPrincipal; 1694 nsCOMPtr<nsIPrincipal> principalToInherit; 1695 nsCOMPtr<nsIPrincipal> partitionedPrincipalToInherit; 1696 nsCOMPtr<nsIPolicyContainer> policyContainer; 1697 nsCString contentType; 1698 if (!ReadParam(aReader, &triggeringPrincipal) || 1699 !ReadParam(aReader, &principalToInherit) || 1700 !ReadParam(aReader, &partitionedPrincipalToInherit) || 1701 !ReadParam(aReader, &policyContainer) || 1702 !ReadParam(aReader, &contentType)) { 1703 aReader->FatalError("Error reading fields for SessionHistoryInfo"); 1704 return false; 1705 } 1706 1707 // We should always see a cloneable input stream passed to SessionHistoryInfo. 1708 // This is because it will be cloneable when first read in the parent process 1709 // from the nsHttpChannel (which forces streams to be cloneable), and future 1710 // streams in content will be wrapped in 1711 // nsMIMEInputStream(RemoteLazyInputStream) which is also cloneable. 1712 if (aResult->mPostData && !NS_InputStreamIsCloneable(aResult->mPostData)) { 1713 aReader->FatalError( 1714 "Unexpected non-cloneable postData for SessionHistoryInfo"); 1715 return false; 1716 } 1717 1718 mozilla::dom::SHEntrySharedParentState* sharedState = nullptr; 1719 if (XRE_IsParentProcess()) { 1720 sharedState = mozilla::dom::SHEntrySharedParentState::Lookup(sharedId); 1721 } 1722 1723 if (sharedState) { 1724 aResult->mSharedState.Set(sharedState); 1725 1726 MOZ_ASSERT(triggeringPrincipal 1727 ? triggeringPrincipal->Equals( 1728 aResult->mSharedState.Get()->mTriggeringPrincipal) 1729 : !aResult->mSharedState.Get()->mTriggeringPrincipal, 1730 "We don't expect this to change!"); 1731 MOZ_ASSERT(principalToInherit 1732 ? principalToInherit->Equals( 1733 aResult->mSharedState.Get()->mPrincipalToInherit) 1734 : !aResult->mSharedState.Get()->mPrincipalToInherit, 1735 "We don't expect this to change!"); 1736 MOZ_ASSERT( 1737 partitionedPrincipalToInherit 1738 ? partitionedPrincipalToInherit->Equals( 1739 aResult->mSharedState.Get()->mPartitionedPrincipalToInherit) 1740 : !aResult->mSharedState.Get()->mPartitionedPrincipalToInherit, 1741 "We don't expect this to change!"); 1742 1743 MOZ_ASSERT(policyContainer 1744 ? PolicyContainer::Equals( 1745 PolicyContainer::Cast(policyContainer), 1746 PolicyContainer::Cast( 1747 aResult->mSharedState.Get()->mPolicyContainer)) 1748 : !aResult->mSharedState.Get()->mPolicyContainer, 1749 "We don't expect this to change!"); 1750 MOZ_ASSERT(contentType.Equals(aResult->mSharedState.Get()->mContentType), 1751 "We don't expect this to change!"); 1752 } else { 1753 aResult->mSharedState.ChangeId(sharedId); 1754 aResult->mSharedState.Get()->mTriggeringPrincipal = 1755 triggeringPrincipal.forget(); 1756 aResult->mSharedState.Get()->mPrincipalToInherit = 1757 principalToInherit.forget(); 1758 aResult->mSharedState.Get()->mPartitionedPrincipalToInherit = 1759 partitionedPrincipalToInherit.forget(); 1760 aResult->mSharedState.Get()->mPolicyContainer = policyContainer.forget(); 1761 aResult->mSharedState.Get()->mContentType = contentType; 1762 } 1763 1764 mozilla::Maybe<std::tuple<uint32_t, mozilla::dom::ClonedMessageData>> 1765 navigationState; 1766 if (!ReadParam(aReader, &aResult->mSharedState.Get()->mLayoutHistoryState) || 1767 !ReadParam(aReader, &aResult->mSharedState.Get()->mCacheKey) || 1768 !ReadParam(aReader, &aResult->mSharedState.Get()->mIsFrameNavigation) || 1769 !ReadParam(aReader, &aResult->mSharedState.Get()->mSaveLayoutState) || 1770 !ReadParam(aReader, &navigationState)) { 1771 aReader->FatalError("Error reading fields for SessionHistoryInfo"); 1772 return false; 1773 } 1774 1775 if (stateData.isSome()) { 1776 uint32_t version = std::get<0>(*stateData); 1777 aResult->mStateData = new nsStructuredCloneContainer(version); 1778 aResult->mStateData->StealFromClonedMessageData(std::get<1>(*stateData)); 1779 } 1780 MOZ_ASSERT_IF(stateData.isNothing(), !aResult->mStateData); 1781 1782 if (navigationState.isSome()) { 1783 uint32_t version = std::get<0>(*navigationState); 1784 aResult->mNavigationAPIState = new nsStructuredCloneContainer(version); 1785 aResult->mNavigationAPIState->StealFromClonedMessageData( 1786 std::get<1>(*navigationState)); 1787 } 1788 MOZ_ASSERT_IF(navigationState.isNothing(), !aResult->mNavigationAPIState); 1789 1790 return true; 1791 } 1792 1793 void ParamTraits<mozilla::dom::LoadingSessionHistoryInfo>::Write( 1794 IPC::MessageWriter* aWriter, 1795 const mozilla::dom::LoadingSessionHistoryInfo& aParam) { 1796 WriteParam(aWriter, aParam.mInfo); 1797 WriteParam(aWriter, aParam.mContiguousEntries); 1798 WriteParam(aWriter, aParam.mTriggeringEntry); 1799 WriteParam(aWriter, aParam.mTriggeringNavigationType); 1800 WriteParam(aWriter, aParam.mLoadId); 1801 WriteParam(aWriter, aParam.mLoadIsFromSessionHistory); 1802 WriteParam(aWriter, aParam.mOffset); 1803 WriteParam(aWriter, aParam.mLoadingCurrentEntry); 1804 WriteParam(aWriter, aParam.mForceMaybeResetName); 1805 } 1806 1807 bool ParamTraits<mozilla::dom::LoadingSessionHistoryInfo>::Read( 1808 IPC::MessageReader* aReader, 1809 mozilla::dom::LoadingSessionHistoryInfo* aResult) { 1810 if (!ReadParam(aReader, &aResult->mInfo) || 1811 !ReadParam(aReader, &aResult->mContiguousEntries) || 1812 !ReadParam(aReader, &aResult->mTriggeringEntry) || 1813 !ReadParam(aReader, &aResult->mTriggeringNavigationType) || 1814 !ReadParam(aReader, &aResult->mLoadId) || 1815 !ReadParam(aReader, &aResult->mLoadIsFromSessionHistory) || 1816 !ReadParam(aReader, &aResult->mOffset) || 1817 !ReadParam(aReader, &aResult->mLoadingCurrentEntry) || 1818 !ReadParam(aReader, &aResult->mForceMaybeResetName)) { 1819 aReader->FatalError("Error reading fields for LoadingSessionHistoryInfo"); 1820 return false; 1821 } 1822 1823 return true; 1824 } 1825 1826 void ParamTraits<nsILayoutHistoryState*>::Write(IPC::MessageWriter* aWriter, 1827 nsILayoutHistoryState* aParam) { 1828 if (aParam) { 1829 WriteParam(aWriter, true); 1830 bool scrollPositionOnly = false; 1831 nsTArray<nsCString> keys; 1832 nsTArray<mozilla::PresState> states; 1833 aParam->GetContents(&scrollPositionOnly, keys, states); 1834 WriteParam(aWriter, scrollPositionOnly); 1835 WriteParam(aWriter, keys); 1836 WriteParam(aWriter, states); 1837 } else { 1838 WriteParam(aWriter, false); 1839 } 1840 } 1841 1842 bool ParamTraits<nsILayoutHistoryState*>::Read( 1843 IPC::MessageReader* aReader, RefPtr<nsILayoutHistoryState>* aResult) { 1844 bool hasLayoutHistoryState = false; 1845 if (!ReadParam(aReader, &hasLayoutHistoryState)) { 1846 aReader->FatalError("Error reading fields for nsILayoutHistoryState"); 1847 return false; 1848 } 1849 1850 if (hasLayoutHistoryState) { 1851 bool scrollPositionOnly = false; 1852 nsTArray<nsCString> keys; 1853 nsTArray<mozilla::PresState> states; 1854 if (!ReadParam(aReader, &scrollPositionOnly) || 1855 !ReadParam(aReader, &keys) || !ReadParam(aReader, &states)) { 1856 aReader->FatalError("Error reading fields for nsILayoutHistoryState"); 1857 } 1858 1859 if (keys.Length() != states.Length()) { 1860 aReader->FatalError("Error reading fields for nsILayoutHistoryState"); 1861 return false; 1862 } 1863 1864 *aResult = NS_NewLayoutHistoryState(); 1865 (*aResult)->SetScrollPositionOnly(scrollPositionOnly); 1866 for (uint32_t i = 0; i < keys.Length(); ++i) { 1867 mozilla::PresState& state = states[i]; 1868 auto newState = mozilla::MakeUnique<mozilla::PresState>(state); 1869 (*aResult)->AddState(keys[i], std::move(newState)); 1870 } 1871 } 1872 return true; 1873 } 1874 1875 void ParamTraits<mozilla::dom::Wireframe>::Write( 1876 IPC::MessageWriter* aWriter, const mozilla::dom::Wireframe& aParam) { 1877 WriteParam(aWriter, aParam.mCanvasBackground); 1878 WriteParam(aWriter, aParam.mRects); 1879 } 1880 1881 bool ParamTraits<mozilla::dom::Wireframe>::Read( 1882 IPC::MessageReader* aReader, mozilla::dom::Wireframe* aResult) { 1883 return ReadParam(aReader, &aResult->mCanvasBackground) && 1884 ReadParam(aReader, &aResult->mRects); 1885 } 1886 1887 // Allow sending mozilla::dom::WireframeRectType enums over IPC. 1888 template <> 1889 struct ParamTraits<mozilla::dom::WireframeRectType> 1890 : public mozilla::dom::WebIDLEnumSerializer< 1891 mozilla::dom::WireframeRectType> {}; 1892 1893 template <> 1894 struct ParamTraits<mozilla::dom::WireframeTaggedRect> { 1895 static void Write(MessageWriter* aWriter, 1896 const mozilla::dom::WireframeTaggedRect& aParam); 1897 static bool Read(MessageReader* aReader, 1898 mozilla::dom::WireframeTaggedRect* aResult); 1899 }; 1900 1901 void ParamTraits<mozilla::dom::WireframeTaggedRect>::Write( 1902 MessageWriter* aWriter, const mozilla::dom::WireframeTaggedRect& aParam) { 1903 WriteParam(aWriter, aParam.mColor); 1904 WriteParam(aWriter, aParam.mType); 1905 WriteParam(aWriter, aParam.mX); 1906 WriteParam(aWriter, aParam.mY); 1907 WriteParam(aWriter, aParam.mWidth); 1908 WriteParam(aWriter, aParam.mHeight); 1909 } 1910 1911 bool ParamTraits<mozilla::dom::WireframeTaggedRect>::Read( 1912 IPC::MessageReader* aReader, mozilla::dom::WireframeTaggedRect* aResult) { 1913 return ReadParam(aReader, &aResult->mColor) && 1914 ReadParam(aReader, &aResult->mType) && 1915 ReadParam(aReader, &aResult->mX) && ReadParam(aReader, &aResult->mY) && 1916 ReadParam(aReader, &aResult->mWidth) && 1917 ReadParam(aReader, &aResult->mHeight); 1918 } 1919 } // namespace IPC