guix-devel/gnu/packages/patches/icecat-CVE-2015-7207.patch

1141 lines
44 KiB
Diff
Raw Normal View History

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);
}