summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/icecat-CVE-2015-7207.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/icecat-CVE-2015-7207.patch')
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7207.patch1140
1 files changed, 1140 insertions, 0 deletions
diff --git a/gnu/packages/patches/icecat-CVE-2015-7207.patch b/gnu/packages/patches/icecat-CVE-2015-7207.patch
new file mode 100644
index 0000000000..db5fc6ce66
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7207.patch
@@ -0,0 +1,1140 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/532544c91db7
+
+# HG changeset patch
+# User Dragana Damjanovic <dd.mozilla@gmail.com>
+# Date 1456962626 28800
+# Node ID 532544c91db7f13c39be1b7b7c4461cd03126e9c
+# Parent f4220254d5bd0851a439467da39ba431e0ce2804
+Bug 1185256 - Save originURI to the history. r=bz ba=ritu
+
+MozReview-Commit-ID: Lvh9C84RQUc
+
+diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
+--- a/docshell/base/nsDocShell.cpp
++++ b/docshell/base/nsDocShell.cpp
+@@ -1020,16 +1020,17 @@ nsDocShell::DestroyChildren()
+ //*****************************************************************************
+ // nsDocShell::nsISupports
+ //*****************************************************************************
+
+ NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader)
+ NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader)
+
+ NS_INTERFACE_MAP_BEGIN(nsDocShell)
++ NS_INTERFACE_MAP_ENTRY(nsIDocShell_ESR38_2)
+ NS_INTERFACE_MAP_ENTRY(nsIDocShell_ESR38)
+ NS_INTERFACE_MAP_ENTRY(nsIDocShell)
+ NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
+ NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
+ NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
+ NS_INTERFACE_MAP_ENTRY(nsIScrollable)
+ NS_INTERFACE_MAP_ENTRY(nsITextScroll)
+ NS_INTERFACE_MAP_ENTRY(nsIDocCharset)
+@@ -1372,16 +1373,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
+ return NS_OK; // JS may not handle returning of an error code
+ }
+
+ if (DoAppRedirectIfNeeded(aURI, aLoadInfo, aFirstParty)) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIURI> referrer;
++ nsCOMPtr<nsIURI> originalURI;
+ nsCOMPtr<nsIInputStream> postStream;
+ nsCOMPtr<nsIInputStream> headersStream;
+ nsCOMPtr<nsISupports> owner;
+ bool inheritOwner = false;
+ bool ownerIsExplicit = false;
+ bool sendReferrer = true;
+ uint32_t referrerPolicy = mozilla::net::RP_Default;
+ bool isSrcdoc = false;
+@@ -1398,16 +1400,20 @@ nsDocShell::LoadURI(nsIURI* aURI,
+ if (!StartupTimeline::HasRecord(StartupTimeline::FIRST_LOAD_URI) &&
+ mItemType == typeContent && !NS_IsAboutBlank(aURI)) {
+ StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI);
+ }
+
+ // Extract the info from the DocShellLoadInfo struct...
+ if (aLoadInfo) {
+ aLoadInfo->GetReferrer(getter_AddRefs(referrer));
++ nsCOMPtr<nsIDocShellLoadInfo_ESR38> liESR38 = do_QueryInterface(aLoadInfo);
++ if (liESR38) {
++ liESR38->GetOriginalURI(getter_AddRefs(originalURI));
++ }
+
+ nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal;
+ aLoadInfo->GetLoadType(&lt);
+ // Get the appropriate loadType from nsIDocShellLoadInfo type
+ loadType = ConvertDocShellLoadInfoToLoadType(lt);
+
+ aLoadInfo->GetOwner(getter_AddRefs(owner));
+ aLoadInfo->GetInheritOwner(&inheritOwner);
+@@ -1652,34 +1658,35 @@ nsDocShell::LoadURI(nsIURI* aURI,
+ if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES) {
+ flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
+ }
+
+ if (isSrcdoc) {
+ flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
+ }
+
+- return InternalLoad(aURI,
+- referrer,
+- referrerPolicy,
+- owner,
+- flags,
+- target.get(),
+- nullptr, // No type hint
+- NullString(), // No forced download
+- postStream,
+- headersStream,
+- loadType,
+- nullptr, // No SHEntry
+- aFirstParty,
+- srcdoc,
+- sourceDocShell,
+- baseURI,
+- nullptr, // No nsIDocShell
+- nullptr); // No nsIRequest
++ return InternalLoad2(aURI,
++ originalURI,
++ referrer,
++ referrerPolicy,
++ owner,
++ flags,
++ target.get(),
++ nullptr, // No type hint
++ NullString(), // No forced download
++ postStream,
++ headersStream,
++ loadType,
++ nullptr, // No SHEntry
++ aFirstParty,
++ srcdoc,
++ sourceDocShell,
++ baseURI,
++ nullptr, // No nsIDocShell
++ nullptr); // No nsIRequest
+ }
+
+ NS_IMETHODIMP
+ nsDocShell::LoadStream(nsIInputStream* aStream, nsIURI* aURI,
+ const nsACString& aContentType,
+ const nsACString& aContentCharset,
+ nsIDocShellLoadInfo* aLoadInfo)
+ {
+@@ -5398,21 +5405,21 @@ nsDocShell::LoadErrorPage(nsIURI* aURI,
+ // end of the URL, so append it last.
+ errorPageUrl.AppendLiteral("&d=");
+ errorPageUrl.AppendASCII(escapedDescription.get());
+
+ nsCOMPtr<nsIURI> errorPageURI;
+ rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+- return InternalLoad(errorPageURI, nullptr, mozilla::net::RP_Default,
+- nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr,
+- nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
+- nullptr, true, NullString(), this, nullptr, nullptr,
+- nullptr);
++ return InternalLoad2(errorPageURI, nullptr, nullptr, mozilla::net::RP_Default,
++ nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr,
++ nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
++ nullptr, true, NullString(), this, nullptr, nullptr,
++ nullptr);
+ }
+
+ NS_IMETHODIMP
+ nsDocShell::Reload(uint32_t aReloadFlags)
+ {
+ if (!IsNavigationAllowed()) {
+ return NS_OK; // JS may not handle returning of an error code
+ }
+@@ -5448,44 +5455,54 @@ nsDocShell::Reload(uint32_t aReloadFlags
+ nsCOMPtr<nsIDocument> doc(GetDocument());
+
+ // Do not inherit owner from document
+ uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
+ nsAutoString srcdoc;
+ nsIPrincipal* principal = nullptr;
+ nsAutoString contentTypeHint;
+ nsCOMPtr<nsIURI> baseURI;
++ nsCOMPtr<nsIURI> originalURI;
+ if (doc) {
+ principal = doc->NodePrincipal();
+ doc->GetContentType(contentTypeHint);
+
+ if (doc->IsSrcdocDocument()) {
+ doc->GetSrcdocData(srcdoc);
+ flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
+ baseURI = doc->GetBaseURI();
+ }
+- }
+- rv = InternalLoad(mCurrentURI,
+- mReferrerURI,
+- mReferrerPolicy,
+- principal,
+- flags,
+- nullptr, // No window target
+- NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
+- NullString(), // No forced download
+- nullptr, // No post data
+- nullptr, // No headers data
+- loadType, // Load type
+- nullptr, // No SHEntry
+- true,
+- srcdoc, // srcdoc argument for iframe
+- this, // For reloads we are the source
+- baseURI,
+- nullptr, // No nsIDocShell
+- nullptr); // No nsIRequest
++ nsCOMPtr<nsIChannel> chan = doc->GetChannel();
++ if (chan) {
++ nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
++ if (httpChan) {
++ httpChan->GetOriginalURI(getter_AddRefs(originalURI));
++ }
++ }
++ }
++
++ rv = InternalLoad2(mCurrentURI,
++ originalURI,
++ mReferrerURI,
++ mReferrerPolicy,
++ principal,
++ flags,
++ nullptr, // No window target
++ NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
++ NullString(), // No forced download
++ nullptr, // No post data
++ nullptr, // No headers data
++ loadType, // Load type
++ nullptr, // No SHEntry
++ true,
++ srcdoc, // srcdoc argument for iframe
++ this, // For reloads we are the source
++ baseURI,
++ nullptr, // No nsIDocShell
++ nullptr); // No nsIRequest
+ }
+
+ return rv;
+ }
+
+ NS_IMETHODIMP
+ nsDocShell::Stop(uint32_t aStopFlags)
+ {
+@@ -9463,27 +9480,28 @@ CopyFavicon(nsIURI* aOldURI, nsIURI* aNe
+ #endif
+ }
+
+ } // anonymous namespace
+
+ class InternalLoadEvent : public nsRunnable
+ {
+ public:
+- InternalLoadEvent(nsDocShell* aDocShell, nsIURI* aURI,
++ InternalLoadEvent(nsDocShell* aDocShell, nsIURI* aURI, nsIURI* aOriginalURI,
+ nsIURI* aReferrer, uint32_t aReferrerPolicy,
+ nsISupports* aOwner, uint32_t aFlags,
+ const char* aTypeHint, nsIInputStream* aPostData,
+ nsIInputStream* aHeadersData, uint32_t aLoadType,
+ nsISHEntry* aSHEntry, bool aFirstParty,
+ const nsAString& aSrcdoc, nsIDocShell* aSourceDocShell,
+ nsIURI* aBaseURI)
+ : mSrcdoc(aSrcdoc)
+ , mDocShell(aDocShell)
+ , mURI(aURI)
++ , mOriginalURI(aOriginalURI)
+ , mReferrer(aReferrer)
+ , mReferrerPolicy(aReferrerPolicy)
+ , mOwner(aOwner)
+ , mPostData(aPostData)
+ , mHeadersData(aHeadersData)
+ , mSHEntry(aSHEntry)
+ , mFlags(aFlags)
+ , mLoadType(aLoadType)
+@@ -9494,34 +9512,36 @@ public:
+ // Make sure to keep null things null as needed
+ if (aTypeHint) {
+ mTypeHint = aTypeHint;
+ }
+ }
+
+ NS_IMETHOD Run()
+ {
+- return mDocShell->InternalLoad(mURI, mReferrer,
+- mReferrerPolicy,
+- mOwner, mFlags,
+- nullptr, mTypeHint.get(),
+- NullString(), mPostData, mHeadersData,
+- mLoadType, mSHEntry, mFirstParty,
+- mSrcdoc, mSourceDocShell, mBaseURI,
+- nullptr, nullptr);
++ return mDocShell->InternalLoad2(mURI, mOriginalURI,
++ mReferrer,
++ mReferrerPolicy,
++ mOwner, mFlags,
++ nullptr, mTypeHint.get(),
++ NullString(), mPostData, mHeadersData,
++ mLoadType, mSHEntry, mFirstParty,
++ mSrcdoc, mSourceDocShell, mBaseURI,
++ nullptr, nullptr);
+ }
+
+ private:
+ // Use IDL strings so .get() returns null by default
+ nsXPIDLString mWindowTarget;
+ nsXPIDLCString mTypeHint;
+ nsString mSrcdoc;
+
+ nsRefPtr<nsDocShell> mDocShell;
+ nsCOMPtr<nsIURI> mURI;
++ nsCOMPtr<nsIURI> mOriginalURI;
+ nsCOMPtr<nsIURI> mReferrer;
+ uint32_t mReferrerPolicy;
+ nsCOMPtr<nsISupports> mOwner;
+ nsCOMPtr<nsIInputStream> mPostData;
+ nsCOMPtr<nsIInputStream> mHeadersData;
+ nsCOMPtr<nsISHEntry> mSHEntry;
+ uint32_t mFlags;
+ uint32_t mLoadType;
+@@ -9584,16 +9604,43 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+ nsISHEntry* aSHEntry,
+ bool aFirstParty,
+ const nsAString& aSrcdoc,
+ nsIDocShell* aSourceDocShell,
+ nsIURI* aBaseURI,
+ nsIDocShell** aDocShell,
+ nsIRequest** aRequest)
+ {
++ return InternalLoad2(aURI, nullptr, aReferrer, aReferrerPolicy, aOwner,
++ aFlags, aWindowTarget, aTypeHint, aFileName, aPostData,
++ aHeadersData, aLoadType, aSHEntry, aFirstParty, aSrcdoc,
++ aSourceDocShell, aBaseURI, aDocShell, aRequest);
++}
++
++NS_IMETHODIMP
++nsDocShell::InternalLoad2(nsIURI* aURI,
++ nsIURI* aOriginalURI,
++ nsIURI* aReferrer,
++ uint32_t aReferrerPolicy,
++ nsISupports* aOwner,
++ uint32_t aFlags,
++ const char16_t* aWindowTarget,
++ const char* aTypeHint,
++ const nsAString& aFileName,
++ nsIInputStream* aPostData,
++ nsIInputStream* aHeadersData,
++ uint32_t aLoadType,
++ nsISHEntry* aSHEntry,
++ bool aFirstParty,
++ const nsAString& aSrcdoc,
++ nsIDocShell* aSourceDocShell,
++ nsIURI* aBaseURI,
++ nsIDocShell** aDocShell,
++ nsIRequest** aRequest)
++{
+ nsresult rv = NS_OK;
+ mOriginalUriString.Truncate();
+
+ #ifdef PR_LOGGING
+ if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) {
+ nsAutoCString spec;
+ if (aURI) {
+ aURI->GetSpec(spec);
+@@ -9831,34 +9878,58 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+ targetDocShell = do_QueryInterface(webNav);
+ }
+
+ //
+ // Transfer the load to the target DocShell... Pass nullptr as the
+ // window target name from to prevent recursive retargeting!
+ //
+ if (NS_SUCCEEDED(rv) && targetDocShell) {
+- rv = targetDocShell->InternalLoad(aURI,
+- aReferrer,
+- aReferrerPolicy,
+- owner,
+- aFlags,
+- nullptr, // No window target
+- aTypeHint,
+- NullString(), // No forced download
+- aPostData,
+- aHeadersData,
+- aLoadType,
+- aSHEntry,
+- aFirstParty,
+- aSrcdoc,
+- aSourceDocShell,
+- aBaseURI,
+- aDocShell,
+- aRequest);
++ nsCOMPtr<nsIDocShell_ESR38_2> dsESR38 = do_QueryInterface(targetDocShell);
++ if (dsESR38) {
++ rv = dsESR38->InternalLoad2(aURI,
++ aOriginalURI,
++ aReferrer,
++ aReferrerPolicy,
++ owner,
++ aFlags,
++ nullptr, // No window target
++ aTypeHint,
++ NullString(), // No forced download
++ aPostData,
++ aHeadersData,
++ aLoadType,
++ aSHEntry,
++ aFirstParty,
++ aSrcdoc,
++ aSourceDocShell,
++ aBaseURI,
++ aDocShell,
++ aRequest);
++ } else {
++ rv = targetDocShell->InternalLoad(aURI,
++ aReferrer,
++ aReferrerPolicy,
++ owner,
++ aFlags,
++ nullptr, // No window target
++ aTypeHint,
++ NullString(), // No forced download
++ aPostData,
++ aHeadersData,
++ aLoadType,
++ aSHEntry,
++ aFirstParty,
++ aSrcdoc,
++ aSourceDocShell,
++ aBaseURI,
++ aDocShell,
++ aRequest);
++ }
++
+ if (rv == NS_ERROR_NO_CONTENT) {
+ // XXXbz except we never reach this code!
+ if (isNewWindow) {
+ //
+ // At this point, a new window has been created, but the
+ // URI did not have any data associated with it...
+ //
+ // So, the best we can do, is to tear down the new window
+@@ -9913,17 +9984,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+ // the unload event also a replace load, so we don't
+ // create extra history entries.
+ if (LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY)) {
+ mLoadType = LOAD_NORMAL_REPLACE;
+ }
+
+ // Do this asynchronously
+ nsCOMPtr<nsIRunnable> ev =
+- new InternalLoadEvent(this, aURI, aReferrer,
++ new InternalLoadEvent(this, aURI, aOriginalURI, aReferrer,
+ aReferrerPolicy, aOwner, aFlags,
+ aTypeHint, aPostData, aHeadersData,
+ aLoadType, aSHEntry, aFirstParty, aSrcdoc,
+ aSourceDocShell, aBaseURI);
+ return NS_DispatchToCurrentThread(ev);
+ }
+
+ // Just ignore this load attempt
+@@ -10371,17 +10442,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+ }
+
+ net::PredictorLearn(aURI, nullptr,
+ nsINetworkPredictor::LEARN_LOAD_TOPLEVEL, this);
+ net::PredictorPredict(aURI, nullptr,
+ nsINetworkPredictor::PREDICT_LOAD, this, nullptr);
+
+ nsCOMPtr<nsIRequest> req;
+- rv = DoURILoad(aURI, aReferrer,
++ rv = DoURILoad(aURI, aOriginalURI, aReferrer,
+ !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
+ aReferrerPolicy,
+ owner, aTypeHint, aFileName, aPostData, aHeadersData,
+ aFirstParty, aDocShell, getter_AddRefs(req),
+ (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
+ (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
+ (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0,
+ srcdoc, aBaseURI, contentType);
+@@ -10445,16 +10516,17 @@ nsDocShell::GetInheritedPrincipal(bool a
+ return docPrincipal;
+ }
+
+ return nullptr;
+ }
+
+ nsresult
+ nsDocShell::DoURILoad(nsIURI* aURI,
++ nsIURI* aOriginalURI,
+ nsIURI* aReferrerURI,
+ bool aSendReferrer,
+ uint32_t aReferrerPolicy,
+ nsISupports* aOwner,
+ const char* aTypeHint,
+ const nsAString& aFileName,
+ nsIInputStream* aPostData,
+ nsIInputStream* aHeadersData,
+@@ -10652,17 +10724,22 @@ nsDocShell::DoURILoad(nsIURI* aURI,
+ }
+
+ // Make sure to give the caller a channel if we managed to create one
+ // This is important for correct error page/session history interaction
+ if (aRequest) {
+ NS_ADDREF(*aRequest = channel);
+ }
+
+- channel->SetOriginalURI(aURI);
++ if (aOriginalURI) {
++ channel->SetOriginalURI(aOriginalURI);
++ } else {
++ channel->SetOriginalURI(aURI);
++ }
++
+ if (aTypeHint && *aTypeHint) {
+ channel->SetContentType(nsDependentCString(aTypeHint));
+ mContentTypeHint = aTypeHint;
+ } else {
+ mContentTypeHint.Truncate();
+ }
+
+ if (!aFileName.IsVoid()) {
+@@ -11624,16 +11701,20 @@ nsDocShell::AddState(JS::Handle<JS::Valu
+
+ // AddToSessionHistory may not modify mOSHE. In case it doesn't,
+ // we'll just set mOSHE here.
+ mOSHE = newSHEntry;
+
+ } else {
+ newSHEntry = mOSHE;
+ newSHEntry->SetURI(newURI);
++ nsCOMPtr<nsISHEntry_ESR38> entryESR38 = do_QueryInterface(newSHEntry);
++ if (entryESR38) {
++ entryESR38->SetOriginalURI(newURI);
++ }
+ }
+
+ // Step 4: Modify new/original session history entry and clear its POST
+ // data, if there is any.
+ newSHEntry->SetStateData(scContainer);
+ newSHEntry->SetPostData(nullptr);
+
+ // If this push/replaceState changed the document's current URI and the new
+@@ -11816,16 +11897,17 @@ nsDocShell::AddToSessionHistory(nsIURI*
+
+ if (!entry) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ // Get the post data & referrer
+ nsCOMPtr<nsIInputStream> inputStream;
++ nsCOMPtr<nsIURI> originalURI;
+ nsCOMPtr<nsIURI> referrerURI;
+ uint32_t referrerPolicy = mozilla::net::RP_Default;
+ nsCOMPtr<nsISupports> cacheKey;
+ nsCOMPtr<nsISupports> owner = aOwner;
+ bool expired = false;
+ bool discardLayoutState = false;
+ nsCOMPtr<nsICachingChannel> cacheChannel;
+ if (aChannel) {
+@@ -11843,16 +11925,17 @@ nsDocShell::AddToSessionHistory(nsIURI*
+ if (!httpChannel) {
+ GetHttpChannel(aChannel, getter_AddRefs(httpChannel));
+ }
+ if (httpChannel) {
+ nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
+ if (uploadChannel) {
+ uploadChannel->GetUploadStream(getter_AddRefs(inputStream));
+ }
++ httpChannel->GetOriginalURI(getter_AddRefs(originalURI));
+ httpChannel->GetReferrer(getter_AddRefs(referrerURI));
+ httpChannel->GetReferrerPolicy(&referrerPolicy);
+
+ discardLayoutState = ShouldDiscardLayoutState(httpChannel);
+ }
+ aChannel->GetOwner(getter_AddRefs(owner));
+ if (!owner) {
+ nsCOMPtr<nsILoadInfo> loadInfo;
+@@ -11875,16 +11958,21 @@ nsDocShell::AddToSessionHistory(nsIURI*
+ EmptyString(), // Title
+ inputStream, // Post data stream
+ nullptr, // LayoutHistory state
+ cacheKey, // CacheKey
+ mContentTypeHint, // Content-type
+ owner, // Channel or provided owner
+ mHistoryID,
+ mDynamicallyCreated);
++
++ nsCOMPtr<nsISHEntry_ESR38> entryESR38 = do_QueryInterface(entry);
++ if (entryESR38) {
++ entryESR38->SetOriginalURI(originalURI);
++ }
+ entry->SetReferrerURI(referrerURI);
+ entry->SetReferrerPolicy(referrerPolicy);
+ nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(aChannel);
+ if (inStrmChan) {
+ bool isSrcdocChannel;
+ inStrmChan->GetIsSrcdocChannel(&isSrcdocChannel);
+ if (isSrcdocChannel) {
+ nsAutoString srcdoc;
+@@ -11976,25 +12064,32 @@ nsDocShell::AddToSessionHistory(nsIURI*
+ nsresult
+ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
+ {
+ if (!IsNavigationAllowed()) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIURI> uri;
++ nsCOMPtr<nsIURI> originalURI;
+ nsCOMPtr<nsIInputStream> postData;
+ nsCOMPtr<nsIURI> referrerURI;
+ uint32_t referrerPolicy;
+ nsAutoCString contentType;
+ nsCOMPtr<nsISupports> owner;
+
+ NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE);
+
+ NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
++
++ nsCOMPtr<nsISHEntry_ESR38> entryESR38 = do_QueryInterface(aEntry);
++ if (entryESR38) {
++ NS_ENSURE_SUCCESS(entryESR38->GetOriginalURI(getter_AddRefs(originalURI)),
++ NS_ERROR_FAILURE);
++ }
+ NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)),
+ NS_ERROR_FAILURE);
+ NS_ENSURE_SUCCESS(aEntry->GetReferrerPolicy(&referrerPolicy),
+ NS_ERROR_FAILURE);
+ NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
+ NS_ERROR_FAILURE);
+ NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
+ NS_ENSURE_SUCCESS(aEntry->GetOwner(getter_AddRefs(owner)), NS_ERROR_FAILURE);
+@@ -12064,34 +12159,35 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
+ } else {
+ srcdoc = NullString();
+ }
+
+ // Passing nullptr as aSourceDocShell gives the same behaviour as before
+ // aSourceDocShell was introduced. According to spec we should be passing
+ // the source browsing context that was used when the history entry was
+ // first created. bug 947716 has been created to address this issue.
+- rv = InternalLoad(uri,
+- referrerURI,
+- referrerPolicy,
+- owner,
+- flags,
+- nullptr, // No window target
+- contentType.get(), // Type hint
+- NullString(), // No forced file download
+- postData, // Post data stream
+- nullptr, // No headers stream
+- aLoadType, // Load type
+- aEntry, // SHEntry
+- true,
+- srcdoc,
+- nullptr, // Source docshell, see comment above
+- baseURI,
+- nullptr, // No nsIDocShell
+- nullptr); // No nsIRequest
++ rv = InternalLoad2(uri,
++ originalURI,
++ referrerURI,
++ referrerPolicy,
++ owner,
++ flags,
++ nullptr, // No window target
++ contentType.get(), // Type hint
++ NullString(), // No forced file download
++ postData, // Post data stream
++ nullptr, // No headers stream
++ aLoadType, // Load type
++ aEntry, // SHEntry
++ true,
++ srcdoc,
++ nullptr, // Source docshell, see comment above
++ baseURI,
++ nullptr, // No nsIDocShell
++ nullptr); // No nsIRequest
+ return rv;
+ }
+
+ NS_IMETHODIMP
+ nsDocShell::GetShouldSaveLayoutState(bool* aShould)
+ {
+ *aShould = false;
+ if (mOSHE) {
+@@ -13527,35 +13623,36 @@ nsDocShell::OnLinkClickSync(nsIContent*
+ // with it under InternalLoad; we do _not_ want to change the URI
+ // our caller passed in.
+ nsCOMPtr<nsIURI> clonedURI;
+ aURI->Clone(getter_AddRefs(clonedURI));
+ if (!clonedURI) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+- nsresult rv = InternalLoad(clonedURI, // New URI
+- referer, // Referer URI
+- refererPolicy, // Referer policy
+- aContent->NodePrincipal(), // Owner is our node's
+- // principal
+- flags,
+- target.get(), // Window target
+- NS_LossyConvertUTF16toASCII(typeHint).get(),
+- aFileName, // Download as file
+- aPostDataStream, // Post data stream
+- aHeadersDataStream, // Headers stream
+- LOAD_LINK, // Load type
+- nullptr, // No SHEntry
+- true, // first party site
+- NullString(), // No srcdoc
+- this, // We are the source
+- nullptr, // baseURI not needed
+- aDocShell, // DocShell out-param
+- aRequest); // Request out-param
++ nsresult rv = InternalLoad2(clonedURI, // New URI
++ nullptr, // Original URI
++ referer, // Referer URI
++ refererPolicy, // Referer policy
++ aContent->NodePrincipal(), // Owner is our node's
++ // principal
++ flags,
++ target.get(), // Window target
++ NS_LossyConvertUTF16toASCII(typeHint).get(),
++ aFileName, // Download as file
++ aPostDataStream, // Post data stream
++ aHeadersDataStream, // Headers stream
++ LOAD_LINK, // Load type
++ nullptr, // No SHEntry
++ true, // first party site
++ NullString(), // No srcdoc
++ this, // We are the source
++ nullptr, // baseURI not needed
++ aDocShell, // DocShell out-param
++ aRequest); // Request out-param
+ if (NS_SUCCEEDED(rv)) {
+ DispatchPings(aContent, aURI, referer, refererPolicy);
+ }
+ return rv;
+ }
+
+ NS_IMETHODIMP
+ nsDocShell::OnOverLink(nsIContent* aContent,
+diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
+--- a/docshell/base/nsDocShell.h
++++ b/docshell/base/nsDocShell.h
+@@ -132,17 +132,17 @@ enum eCharsetReloadState
+ };
+
+ //*****************************************************************************
+ //*** nsDocShell
+ //*****************************************************************************
+
+ class nsDocShell final
+ : public nsDocLoader
+- , public nsIDocShell_ESR38
++ , public nsIDocShell_ESR38_2
+ , public nsIWebNavigation
+ , public nsIBaseWindow
+ , public nsIScrollable
+ , public nsITextScroll
+ , public nsIDocCharset
+ , public nsIContentViewerContainer
+ , public nsIRefreshURI
+ , public nsIWebProgressListener
+@@ -164,16 +164,17 @@ public:
+ nsDocShell();
+
+ NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
+
+ virtual nsresult Init() override;
+
+ NS_DECL_ISUPPORTS_INHERITED
+
++ NS_DECL_NSIDOCSHELL_ESR38_2
+ NS_DECL_NSIDOCSHELL_ESR38
+ NS_DECL_NSIDOCSHELL
+ NS_DECL_NSIDOCSHELLTREEITEM
+ NS_DECL_NSIWEBNAVIGATION
+ NS_DECL_NSIBASEWINDOW
+ NS_DECL_NSISCROLLABLE
+ NS_DECL_NSITEXTSCROLL
+ NS_DECL_NSIDOCCHARSET
+@@ -312,17 +313,20 @@ protected:
+ // at the parent.
+ nsIPrincipal* GetInheritedPrincipal(bool aConsiderCurrentDocument);
+
+ // Actually open a channel and perform a URI load. Note: whatever owner is
+ // passed to this function will be set on the channel. Callers who wish to
+ // not have an owner on the channel should just pass null.
+ // If aSrcdoc is not void, the load will be considered as a srcdoc load,
+ // and the contents of aSrcdoc will be loaded instead of aURI.
++ // aOriginalURI will be set as the originalURI on the channel that does the
++ // load. If aOriginalURI is null, aURI will be set as the originalURI.
+ nsresult DoURILoad(nsIURI* aURI,
++ nsIURI* aOriginalURI,
+ nsIURI* aReferrer,
+ bool aSendReferrer,
+ uint32_t aReferrerPolicy,
+ nsISupports* aOwner,
+ const char* aTypeHint,
+ const nsAString& aFileName,
+ nsIInputStream* aPostData,
+ nsIInputStream* aHeadersData,
+diff --git a/docshell/base/nsDocShellLoadInfo.cpp b/docshell/base/nsDocShellLoadInfo.cpp
+--- a/docshell/base/nsDocShellLoadInfo.cpp
++++ b/docshell/base/nsDocShellLoadInfo.cpp
+@@ -34,16 +34,17 @@ nsDocShellLoadInfo::~nsDocShellLoadInfo(
+ // nsDocShellLoadInfo::nsISupports
+ //*****************************************************************************
+
+ NS_IMPL_ADDREF(nsDocShellLoadInfo)
+ NS_IMPL_RELEASE(nsDocShellLoadInfo)
+
+ NS_INTERFACE_MAP_BEGIN(nsDocShellLoadInfo)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellLoadInfo)
++ NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo_ESR38)
+ NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo)
+ NS_INTERFACE_MAP_END
+
+ //*****************************************************************************
+ // nsDocShellLoadInfo::nsIDocShellLoadInfo
+ //*****************************************************************************
+
+ NS_IMETHODIMP
+@@ -59,16 +60,33 @@ nsDocShellLoadInfo::GetReferrer(nsIURI**
+ NS_IMETHODIMP
+ nsDocShellLoadInfo::SetReferrer(nsIURI* aReferrer)
+ {
+ mReferrer = aReferrer;
+ return NS_OK;
+ }
+
+ NS_IMETHODIMP
++nsDocShellLoadInfo::GetOriginalURI(nsIURI** aOriginalURI)
++{
++ NS_ENSURE_ARG_POINTER(aOriginalURI);
++
++ *aOriginalURI = mOriginalURI;
++ NS_IF_ADDREF(*aOriginalURI);
++ return NS_OK;
++}
++
++NS_IMETHODIMP
++nsDocShellLoadInfo::SetOriginalURI(nsIURI* aOriginalURI)
++{
++ mOriginalURI = aOriginalURI;
++ return NS_OK;
++}
++
++NS_IMETHODIMP
+ nsDocShellLoadInfo::GetOwner(nsISupports** aOwner)
+ {
+ NS_ENSURE_ARG_POINTER(aOwner);
+
+ *aOwner = mOwner;
+ NS_IF_ADDREF(*aOwner);
+ return NS_OK;
+ }
+diff --git a/docshell/base/nsDocShellLoadInfo.h b/docshell/base/nsDocShellLoadInfo.h
+--- a/docshell/base/nsDocShellLoadInfo.h
++++ b/docshell/base/nsDocShellLoadInfo.h
+@@ -14,29 +14,31 @@
+ // Interfaces Needed
+ #include "nsIDocShellLoadInfo.h"
+
+ class nsIInputStream;
+ class nsISHEntry;
+ class nsIURI;
+ class nsIDocShell;
+
+-class nsDocShellLoadInfo : public nsIDocShellLoadInfo
++class nsDocShellLoadInfo : public nsIDocShellLoadInfo_ESR38
+ {
+ public:
+ nsDocShellLoadInfo();
+
+ NS_DECL_ISUPPORTS
++ NS_DECL_NSIDOCSHELLLOADINFO_ESR38
+ NS_DECL_NSIDOCSHELLLOADINFO
+
+ protected:
+ virtual ~nsDocShellLoadInfo();
+
+ protected:
+ nsCOMPtr<nsIURI> mReferrer;
++ nsCOMPtr<nsIURI> mOriginalURI;
+ nsCOMPtr<nsISupports> mOwner;
+ bool mInheritOwner;
+ bool mOwnerIsExplicit;
+ bool mSendReferrer;
+ nsDocShellInfoReferrerPolicy mReferrerPolicy;
+ nsDocShellInfoLoadType mLoadType;
+ nsCOMPtr<nsISHEntry> mSHEntry;
+ nsString mTarget;
+diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
+--- a/docshell/base/nsIDocShell.idl
++++ b/docshell/base/nsIDocShell.idl
+@@ -1059,8 +1059,66 @@ interface nsIDocShell : nsIDocShellTreeI
+ interface nsIDocShell_ESR38 : nsIDocShell
+ {
+ /**
+ * True if new child docshells should allow content retargeting.
+ * Setting allowContentRetargeting also overwrites this value.
+ */
+ [infallible] attribute boolean allowContentRetargetingOnChildren;
+ };
++
++[scriptable, builtinclass, uuid(607604b6-8fe0-4d2c-8a6c-44f5f31a6e02)]
++interface nsIDocShell_ESR38_2 : nsIDocShell_ESR38
++{
++ /**
++ * Loads the given URI. This method is identical to loadURI(...) except
++ * that its parameter list is broken out instead of being packaged inside
++ * of an nsIDocShellLoadInfo object...
++ *
++ * @param aURI - The URI to load.
++ * @param aOriginalURI - The URI to set as the originalURI on the channel
++ * that does the load. If null, aURI will be set as
++ * the originalURI.
++ * @param aReferrer - Referring URI
++ * @param aReferrerPolicy - Referrer policy
++ * @param aOwner - Owner (security principal)
++ * @param aInheritOwner - Flag indicating whether the owner of the current
++ * document should be inherited if aOwner is null.
++ * @param aStopActiveDoc - Flag indicating whether loading the current
++ * document should be stopped.
++ * @param aWindowTarget - Window target for the load.
++ * @param aTypeHint - A hint as to the content-type of the resulting
++ * data. May be null or empty if no hint.
++ * @param aFileName - Non-null when the link should be downloaded as
++ the given filename.
++ * @param aPostDataStream - Post data stream (if POSTing)
++ * @param aHeadersStream - Stream containing "extra" request headers...
++ * @param aLoadFlags - Flags to modify load behaviour. Flags are defined
++ * in nsIWebNavigation.
++ * @param aSHEntry - Active Session History entry (if loading from SH)
++ * @param aSrcdoc When INTERNAL_LOAD_FLAGS_IS_SRCDOC is set, the
++ * contents of this parameter will be loaded instead
++ * of aURI.
++ * @param aSourceDocShell - The source browsing context for the navigation.
++ * @param aBaseURI - The base URI to be used for the load. Set in
++ * srcdoc loads as it cannot otherwise be inferred
++ * in certain situations such as view-source.
++ */
++ [noscript]void internalLoad2(in nsIURI aURI,
++ in nsIURI aOriginalURI,
++ in nsIURI aReferrer,
++ in unsigned long aReferrerPolicy,
++ in nsISupports aOwner,
++ in uint32_t aFlags,
++ in wstring aWindowTarget,
++ in string aTypeHint,
++ in AString aFileName,
++ in nsIInputStream aPostDataStream,
++ in nsIInputStream aHeadersStream,
++ in unsigned long aLoadFlags,
++ in nsISHEntry aSHEntry,
++ in boolean firstParty,
++ in AString aSrcdoc,
++ in nsIDocShell aSourceDocShell,
++ in nsIURI aBaseURI,
++ out nsIDocShell aDocShell,
++ out nsIRequest aRequest);
++};
+diff --git a/docshell/base/nsIDocShellLoadInfo.idl b/docshell/base/nsIDocShellLoadInfo.idl
+--- a/docshell/base/nsIDocShellLoadInfo.idl
++++ b/docshell/base/nsIDocShellLoadInfo.idl
+@@ -106,8 +106,17 @@ interface nsIDocShellLoadInfo : nsISuppo
+ attribute nsIDocShell sourceDocShell;
+
+ /**
+ * Used for srcdoc loads to give view-source knowledge of the load's base
+ * URI as this information isn't embedded in the load's URI.
+ */
+ attribute nsIURI baseURI;
+ };
++
++[scriptable, uuid(9d3bc466-5efe-414d-ae8b-3830b45877bb)]
++interface nsIDocShellLoadInfo_ESR38 : nsIDocShellLoadInfo
++{
++ /**
++ * The originalURI to be passed to nsIDocShell.internalLoad. May be null.
++ */
++ attribute nsIURI originalURI;
++};
+diff --git a/docshell/shistory/public/nsISHEntry.idl b/docshell/shistory/public/nsISHEntry.idl
+--- a/docshell/shistory/public/nsISHEntry.idl
++++ b/docshell/shistory/public/nsISHEntry.idl
+@@ -319,8 +319,18 @@ interface nsISHEntryInternal : nsISuppor
+ #define NS_SHENTRY_CID \
+ {0xbfd1a791, 0xad9f, 0x11d3, {0xbd, 0xc7, 0x0, 0x50, 0x4, 0xa, 0x9b, 0x44}}
+
+ #define NS_SHENTRY_CONTRACTID \
+ "@mozilla.org/browser/session-history-entry;1"
+
+ %}
+
++[scriptable, uuid(e45ab6ef-3485-449c-b91c-0846b2bf6faf)]
++interface nsISHEntry_ESR38 : nsISHEntry
++{
++ /**
++ * A readonly property that returns the original URI of the current entry.
++ * If an entry is the result of a redirect this attribute holds original
++ * URI. The object returned is of type nsIURI
++ */
++ attribute nsIURI originalURI;
++};
+diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp
+--- a/docshell/shistory/src/nsSHEntry.cpp
++++ b/docshell/shistory/src/nsSHEntry.cpp
+@@ -38,16 +38,17 @@ nsSHEntry::nsSHEntry()
+ , mIsSrcdocEntry(false)
+ {
+ mShared = new nsSHEntryShared();
+ }
+
+ nsSHEntry::nsSHEntry(const nsSHEntry &other)
+ : mShared(other.mShared)
+ , mURI(other.mURI)
++ , mOriginalURI(other.mOriginalURI)
+ , mReferrerURI(other.mReferrerURI)
+ , mReferrerPolicy(other.mReferrerPolicy)
+ , mTitle(other.mTitle)
+ , mPostData(other.mPostData)
+ , mLoadType(0) // XXX why not copy?
+ , mID(other.mID)
+ , mScrollPositionX(0) // XXX why not copy?
+ , mScrollPositionY(0) // XXX why not copy?
+@@ -74,17 +75,17 @@ nsSHEntry::~nsSHEntry()
+ // Null out the mParent pointers on all our kids.
+ mChildren.EnumerateForwards(ClearParentPtr, nullptr);
+ }
+
+ //*****************************************************************************
+ // nsSHEntry: nsISupports
+ //*****************************************************************************
+
+-NS_IMPL_ISUPPORTS(nsSHEntry, nsISHContainer, nsISHEntry, nsISHEntryInternal)
++NS_IMPL_ISUPPORTS(nsSHEntry, nsISHContainer, nsISHEntry_ESR38, nsISHEntry, nsISHEntryInternal)
+
+ //*****************************************************************************
+ // nsSHEntry: nsISHEntry
+ //*****************************************************************************
+
+ NS_IMETHODIMP nsSHEntry::SetScrollPosition(int32_t x, int32_t y)
+ {
+ mScrollPositionX = x;
+@@ -119,16 +120,29 @@ NS_IMETHODIMP nsSHEntry::GetURI(nsIURI**
+ }
+
+ NS_IMETHODIMP nsSHEntry::SetURI(nsIURI* aURI)
+ {
+ mURI = aURI;
+ return NS_OK;
+ }
+
++NS_IMETHODIMP nsSHEntry::GetOriginalURI(nsIURI** aOriginalURI)
++{
++ *aOriginalURI = mOriginalURI;
++ NS_IF_ADDREF(*aOriginalURI);
++ return NS_OK;
++}
++
++NS_IMETHODIMP nsSHEntry::SetOriginalURI(nsIURI* aOriginalURI)
++{
++ mOriginalURI = aOriginalURI;
++ return NS_OK;
++}
++
+ NS_IMETHODIMP nsSHEntry::GetReferrerURI(nsIURI **aReferrerURI)
+ {
+ *aReferrerURI = mReferrerURI;
+ NS_IF_ADDREF(*aReferrerURI);
+ return NS_OK;
+ }
+
+ NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
+diff --git a/docshell/shistory/src/nsSHEntry.h b/docshell/shistory/src/nsSHEntry.h
+--- a/docshell/shistory/src/nsSHEntry.h
++++ b/docshell/shistory/src/nsSHEntry.h
+@@ -17,25 +17,26 @@
+ // Interfaces needed
+ #include "nsISHEntry.h"
+ #include "nsISHContainer.h"
+
+ class nsSHEntryShared;
+ class nsIInputStream;
+ class nsIURI;
+
+-class nsSHEntry final : public nsISHEntry,
++class nsSHEntry final : public nsISHEntry_ESR38,
+ public nsISHContainer,
+ public nsISHEntryInternal
+ {
+ public:
+ nsSHEntry();
+ nsSHEntry(const nsSHEntry &other);
+
+ NS_DECL_ISUPPORTS
++ NS_DECL_NSISHENTRY_ESR38
+ NS_DECL_NSISHENTRY
+ NS_DECL_NSISHENTRYINTERNAL
+ NS_DECL_NSISHCONTAINER
+
+ void DropPresentationState();
+
+ static nsresult Startup();
+ static void Shutdown();
+@@ -44,16 +45,17 @@ private:
+ ~nsSHEntry();
+
+ // We share the state in here with other SHEntries which correspond to the
+ // same document.
+ nsRefPtr<nsSHEntryShared> mShared;
+
+ // See nsSHEntry.idl for comments on these members.
+ nsCOMPtr<nsIURI> mURI;
++ nsCOMPtr<nsIURI> mOriginalURI;
+ nsCOMPtr<nsIURI> mReferrerURI;
+ uint32_t mReferrerPolicy;
+ nsString mTitle;
+ nsCOMPtr<nsIInputStream> mPostData;
+ uint32_t mLoadType;
+ uint32_t mID;
+ int32_t mScrollPositionX;
+ int32_t mScrollPositionY;
+diff --git a/docshell/shistory/src/nsSHistory.cpp b/docshell/shistory/src/nsSHistory.cpp
+--- a/docshell/shistory/src/nsSHistory.cpp
++++ b/docshell/shistory/src/nsSHistory.cpp
+@@ -1779,16 +1779,26 @@ nsSHistory::InitiateLoad(nsISHEntry * aF
+ * so that proper loadType is maintained through out a frameset
+ */
+ aFrameEntry->SetLoadType(aLoadType);
+ aFrameDS->CreateLoadInfo (getter_AddRefs(loadInfo));
+
+ loadInfo->SetLoadType(aLoadType);
+ loadInfo->SetSHEntry(aFrameEntry);
+
++ nsCOMPtr<nsIURI> originalURI;
++ nsCOMPtr<nsISHEntry_ESR38> feESR38 = do_QueryInterface(aFrameEntry);
++ if (feESR38) {
++ feESR38->GetOriginalURI(getter_AddRefs(originalURI));
++ }
++ nsCOMPtr<nsIDocShellLoadInfo_ESR38> liESR38 = do_QueryInterface(loadInfo);
++ if (liESR38) {
++ liESR38->SetOriginalURI(originalURI);
++ }
++
+ nsCOMPtr<nsIURI> nextURI;
+ aFrameEntry->GetURI(getter_AddRefs(nextURI));
+ // Time to initiate a document load
+ return aFrameDS->LoadURI(nextURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, false);
+
+ }
+
+
+