Bug 1578624 - P3: Move conversion from LoadURIOptions processing into a static constructor for nsDocShellLoadState. r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D44759

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2019-10-09 06:37:50 +00:00
parent 2b3ffb9596
commit a0e75a0df9
5 changed files with 165 additions and 125 deletions

View File

@ -704,6 +704,14 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState) {
}
}
PopupBlocker::PopupControlState popupState;
if (aLoadState->LoadFlags() & LOAD_FLAGS_ALLOW_POPUPS) {
popupState = PopupBlocker::openAllowed;
} else {
popupState = PopupBlocker::openOverridden;
}
AutoPopupStatePusher statePusher(popupState);
if (aLoadState->GetOriginalURIString().isSome()) {
// Save URI string in case it's needed later when
// sending to search engine service in EndPageLoad()
@ -3819,140 +3827,28 @@ nsDocShell::GotoIndex(int32_t aIndex) {
nsresult nsDocShell::LoadURI(const nsAString& aURI,
const LoadURIOptions& aLoadURIOptions) {
uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
NS_ASSERTION((loadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
"Unexpected flags");
if (!IsNavigationAllowed()) {
return NS_OK; // JS may not handle returning of an error code
}
auto cleanupIsNavigating = MakeScopeExit([&]() { mIsNavigating = false; });
mIsNavigating = true;
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIInputStream> postData(aLoadURIOptions.mPostData);
nsresult rv = NS_OK;
NS_ConvertUTF16toUTF8 uriString(aURI);
// Cleanup the empty spaces that might be on each end.
uriString.Trim(" ");
// Eliminate embedded newlines, which single-line text fields now allow:
uriString.StripCRLF();
NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
if (mUseStrictSecurityChecks && !aLoadURIOptions.mTriggeringPrincipal) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURIFixupInfo> fixupInfo;
if (sURIFixup) {
uint32_t fixupFlags;
rv = sURIFixup->WebNavigationFlagsToFixupFlags(uriString, loadFlags,
&fixupFlags);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
// If we don't allow keyword lookups for this URL string, make sure to
// update loadFlags to indicate this as well.
if (!(fixupFlags & nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) {
loadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
nsCOMPtr<nsIInputStream> fixupStream;
rv = sURIFixup->GetFixupURIInfo(uriString, fixupFlags,
getter_AddRefs(fixupStream),
getter_AddRefs(fixupInfo));
if (NS_SUCCEEDED(rv)) {
fixupInfo->GetPreferredURI(getter_AddRefs(uri));
fixupInfo->SetConsumer(GetAsSupports(this));
}
if (fixupStream) {
// GetFixupURIInfo only returns a post data stream if it succeeded
// and changed the URI, in which case we should override the
// passed-in post data.
postData = fixupStream;
}
if (loadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
if (serv) {
serv->NotifyObservers(fixupInfo, "keyword-uri-fixup",
PromiseFlatString(aURI).get());
}
}
} else {
// No fixup service so just create a URI and see what happens...
rv = NS_NewURI(getter_AddRefs(uri), uriString);
loadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
RefPtr<nsDocShellLoadState> loadState;
nsresult rv = nsDocShellLoadState::CreateFromLoadURIOptions(
GetAsSupports(this), sURIFixup, aURI, aLoadURIOptions,
getter_AddRefs(loadState));
uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
if (NS_ERROR_MALFORMED_URI == rv) {
if (DisplayLoadError(rv, uri, PromiseFlatString(aURI).get(), nullptr) &&
if (DisplayLoadError(rv, nullptr, PromiseFlatString(aURI).get(), nullptr) &&
(loadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) {
return NS_ERROR_LOAD_SHOWED_ERRORPAGE;
}
}
if (NS_FAILED(rv) || !uri) {
if (NS_FAILED(rv) || !loadState) {
return NS_ERROR_FAILURE;
}
PopupBlocker::PopupControlState popupState;
if (loadFlags & LOAD_FLAGS_ALLOW_POPUPS) {
popupState = PopupBlocker::openAllowed;
loadFlags &= ~LOAD_FLAGS_ALLOW_POPUPS;
} else {
popupState = PopupBlocker::openOverridden;
}
AutoPopupStatePusher statePusher(popupState);
bool forceAllowDataURI = loadFlags & LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
// Don't pass certain flags that aren't needed and end up confusing
// ConvertLoadTypeToDocShellInfoLoadType. We do need to ensure that they are
// passed to LoadURI though, since it uses them.
uint32_t extraFlags = (loadFlags & EXTRA_LOAD_FLAGS);
loadFlags &= ~EXTRA_LOAD_FLAGS;
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(uri);
loadState->SetReferrerInfo(aLoadURIOptions.mReferrerInfo);
/*
* If the user "Disables Protection on This Page", we have to make sure to
* remember the users decision when opening links in child tabs [Bug 906190]
*/
if (loadFlags & LOAD_FLAGS_ALLOW_MIXED_CONTENT) {
loadState->SetLoadType(
MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, loadFlags));
} else {
loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags));
}
loadState->SetLoadFlags(extraFlags);
loadState->SetFirstParty(true);
loadState->SetPostDataStream(postData);
loadState->SetHeadersStream(aLoadURIOptions.mHeaders);
loadState->SetBaseURI(aLoadURIOptions.mBaseURI);
loadState->SetTriggeringPrincipal(aLoadURIOptions.mTriggeringPrincipal);
loadState->SetCsp(aLoadURIOptions.mCsp);
loadState->SetForceAllowDataURI(forceAllowDataURI);
if (fixupInfo) {
nsAutoString searchProvider, keyword;
fixupInfo->GetKeywordProviderName(searchProvider);
fixupInfo->GetKeywordAsSent(keyword);
MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
}
rv = LoadURI(loadState);
// Save URI string in case it's needed later when
// sending to search engine service in EndPageLoad()
mOriginalUriString = uriString;
return rv;
}
@ -13505,6 +13401,7 @@ void nsDocShell::NotifyJSRunToCompletionStop() {
}
}
/* static */
void nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
const nsString& aKeyword) {
if (aProvider.IsEmpty()) {

View File

@ -486,6 +486,10 @@ class nsDocShell final : public nsDocLoader,
const nsString* aInitiatorType,
uint32_t aLoadType, uint32_t aCacheKey);
// Notify consumers of a search being loaded through the observer service:
static void MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
const nsString& aKeyword);
private: // member functions
friend class nsDSURIContentListener;
friend class FramingChecker;
@ -956,10 +960,6 @@ class nsDocShell final : public nsDocLoader,
// OriginAttributes.mPrivateBrowsingId
void AssertOriginAttributesMatchPrivateBrowsing();
// Notify consumers of a search being loaded through the observer service:
void MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
const nsString& aKeyword);
// Internal implementation of nsIDocShell::FirePageHideNotification.
// If aSkipCheckingDynEntries is true, it will not try to remove dynamic
// subframe entries. This is to avoid redundant RemoveDynEntries calls in all

View File

@ -11,6 +11,7 @@
#include "nsIWebNavigation.h"
#include "nsIChildChannel.h"
#include "ReferrerInfo.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/OriginAttributes.h"
#include "mozilla/NullPrincipal.h"
@ -109,6 +110,142 @@ nsresult nsDocShellLoadState::CreateFromPendingChannel(
return NS_OK;
}
nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
nsISupports* aConsumer, nsIURIFixup* aURIFixup, const nsAString& aURI,
const LoadURIOptions& aLoadURIOptions, nsDocShellLoadState** aResult) {
uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
NS_ASSERTION(
(loadFlags & nsDocShell::INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
"Unexpected flags");
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIInputStream> postData(aLoadURIOptions.mPostData);
nsresult rv = NS_OK;
NS_ConvertUTF16toUTF8 uriString(aURI);
// Cleanup the empty spaces that might be on each end.
uriString.Trim(" ");
// Eliminate embedded newlines, which single-line text fields now allow:
uriString.StripCRLF();
NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
nsCOMPtr<nsIURIFixupInfo> fixupInfo;
if (aURIFixup) {
uint32_t fixupFlags;
rv = aURIFixup->WebNavigationFlagsToFixupFlags(uriString, loadFlags,
&fixupFlags);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
// If we don't allow keyword lookups for this URL string, make sure to
// update loadFlags to indicate this as well.
if (!(fixupFlags & nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) {
loadFlags &= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
nsCOMPtr<nsIInputStream> fixupStream;
rv = aURIFixup->GetFixupURIInfo(uriString, fixupFlags,
getter_AddRefs(fixupStream),
getter_AddRefs(fixupInfo));
if (NS_SUCCEEDED(rv)) {
fixupInfo->GetPreferredURI(getter_AddRefs(uri));
fixupInfo->SetConsumer(aConsumer);
}
if (fixupStream) {
// GetFixupURIInfo only returns a post data stream if it succeeded
// and changed the URI, in which case we should override the
// passed-in post data.
postData = fixupStream;
}
if (loadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
if (serv) {
serv->NotifyObservers(fixupInfo, "keyword-uri-fixup",
PromiseFlatString(aURI).get());
}
}
} else {
// No fixup service so just create a URI and see what happens...
rv = NS_NewURI(getter_AddRefs(uri), uriString);
loadFlags &= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
if (rv == NS_ERROR_MALFORMED_URI) {
MOZ_ASSERT(!uri);
return rv;
}
if (NS_FAILED(rv) || !uri) {
return NS_ERROR_FAILURE;
}
uint64_t available;
if (postData) {
rv = postData->Available(&available);
NS_ENSURE_SUCCESS(rv, rv);
if (available == 0) {
return NS_ERROR_INVALID_ARG;
}
}
if (aLoadURIOptions.mHeaders) {
rv = aLoadURIOptions.mHeaders->Available(&available);
NS_ENSURE_SUCCESS(rv, rv);
if (available == 0) {
return NS_ERROR_INVALID_ARG;
}
}
bool forceAllowDataURI =
loadFlags & nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
// Don't pass certain flags that aren't needed and end up confusing
// ConvertLoadTypeToDocShellInfoLoadType. We do need to ensure that they are
// passed to LoadURI though, since it uses them.
uint32_t extraFlags = (loadFlags & EXTRA_LOAD_FLAGS);
loadFlags &= ~EXTRA_LOAD_FLAGS;
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(uri);
loadState->SetReferrerInfo(aLoadURIOptions.mReferrerInfo);
/*
* If the user "Disables Protection on This Page", we have to make sure to
* remember the users decision when opening links in child tabs [Bug 906190]
*/
if (loadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT) {
loadState->SetLoadType(
MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, loadFlags));
} else {
loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags));
}
loadState->SetLoadFlags(extraFlags);
loadState->SetFirstParty(true);
loadState->SetPostDataStream(postData);
loadState->SetHeadersStream(aLoadURIOptions.mHeaders);
loadState->SetBaseURI(aLoadURIOptions.mBaseURI);
loadState->SetTriggeringPrincipal(aLoadURIOptions.mTriggeringPrincipal);
loadState->SetCsp(aLoadURIOptions.mCsp);
loadState->SetForceAllowDataURI(forceAllowDataURI);
loadState->SetOriginalURIString(uriString);
if (aLoadURIOptions.mCancelContentJSEpoch) {
loadState->SetCancelContentJSEpoch(aLoadURIOptions.mCancelContentJSEpoch);
}
if (fixupInfo) {
nsAutoString searchProvider, keyword;
fixupInfo->GetKeywordProviderName(searchProvider);
fixupInfo->GetKeywordAsSent(keyword);
nsDocShell::MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
}
loadState.forget(aResult);
return NS_OK;
}
nsIReferrerInfo* nsDocShellLoadState::GetReferrerInfo() const {
return mReferrerInfo;
}

View File

@ -41,6 +41,11 @@ class nsDocShellLoadState final {
static nsresult CreateFromPendingChannel(nsIChildChannel* aPendingChannel,
nsDocShellLoadState** aResult);
static nsresult CreateFromLoadURIOptions(
nsISupports* aConsumer, nsIURIFixup* aURIFixup, const nsAString& aURI,
const mozilla::dom::LoadURIOptions& aLoadURIOptions,
nsDocShellLoadState** aResult);
// Getters and Setters
nsIReferrerInfo* GetReferrerInfo() const;

View File

@ -28,8 +28,9 @@
* above 0xffff (e.g. LOAD_FLAGS_BYPASS_CLASSIFIER), since MAKE_LOAD_TYPE would
* just shift them out anyway.
*/
# define EXTRA_LOAD_FLAGS \
(LOAD_FLAGS_FIRST_LOAD | LOAD_FLAGS_ALLOW_POPUPS | 0xffff0000)
# define EXTRA_LOAD_FLAGS \
(nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD | \
nsIWebNavigation::LOAD_FLAGS_ALLOW_POPUPS | 0xffff0000)
/* load types are legal combinations of load commands and flags
*