From 188a11496279f211853a5e357b43df259b9d2895 Mon Sep 17 00:00:00 2001 From: Razvan Maries Date: Fri, 20 Dec 2019 01:56:55 +0200 Subject: [PATCH] Backed out 5 changesets (bug 1598520) for perma fails on test_enumerateDevices_navigation.html. CLOSED TREE Backed out changeset 583dac2feebc (bug 1598520) Backed out changeset c769e733f588 (bug 1598520) Backed out changeset 45287a2ec476 (bug 1598520) Backed out changeset 59cff6014447 (bug 1598520) Backed out changeset ddf722557c33 (bug 1598520) --- docshell/base/ChildProcessChannelListener.cpp | 2 +- docshell/base/ChildProcessChannelListener.h | 8 +-- docshell/base/nsDocShell.cpp | 31 +++++++---- docshell/base/nsDocShellLoadState.cpp | 15 ++++-- docshell/base/nsDocShellLoadState.h | 8 +-- dom/ipc/ContentChild.cpp | 48 +++++++---------- layout/style/crashtests/1541126.html | 20 ++++++++ layout/style/crashtests/crashtests.list | 1 + netwerk/ipc/DocumentChannelChild.cpp | 31 +++-------- netwerk/ipc/DocumentLoadListener.cpp | 10 ---- netwerk/ipc/DocumentLoadListener.h | 3 -- netwerk/ipc/NeckoChannelParams.ipdlh | 2 - uriloader/base/nsURILoader.cpp | 51 +++++++++---------- 13 files changed, 110 insertions(+), 120 deletions(-) create mode 100644 layout/style/crashtests/1541126.html diff --git a/docshell/base/ChildProcessChannelListener.cpp b/docshell/base/ChildProcessChannelListener.cpp index 8d20f46ef302..da91d4077d11 100644 --- a/docshell/base/ChildProcessChannelListener.cpp +++ b/docshell/base/ChildProcessChannelListener.cpp @@ -22,7 +22,7 @@ void ChildProcessChannelListener::RegisterCallback(uint64_t aIdentifier, } void ChildProcessChannelListener::OnChannelReady( - nsIChannel* aChannel, uint64_t aIdentifier, + nsIChildChannel* aChannel, uint64_t aIdentifier, nsTArray&& aRedirects, uint32_t aLoadStateLoadFlags) { if (auto callback = mCallbacks.GetAndRemove(aIdentifier)) { diff --git a/docshell/base/ChildProcessChannelListener.h b/docshell/base/ChildProcessChannelListener.h index 2393357f0a55..f544e326bc80 100644 --- a/docshell/base/ChildProcessChannelListener.h +++ b/docshell/base/ChildProcessChannelListener.h @@ -11,7 +11,7 @@ #include "mozilla/net/NeckoChannelParams.h" #include "nsDataHashtable.h" -#include "nsIChannel.h" +#include "nsIChildChannel.h" namespace mozilla { namespace dom { @@ -20,11 +20,11 @@ class ChildProcessChannelListener final { NS_INLINE_DECL_REFCOUNTING(ChildProcessChannelListener) using Callback = std::function&&, uint32_t)>; + nsIChildChannel*, nsTArray&&, uint32_t)>; void RegisterCallback(uint64_t aIdentifier, Callback&& aCallback); - void OnChannelReady(nsIChannel* aChannel, uint64_t aIdentifier, + void OnChannelReady(nsIChildChannel* aChannel, uint64_t aIdentifier, nsTArray&& aRedirects, uint32_t aLoadStateLoadFlags); @@ -34,7 +34,7 @@ class ChildProcessChannelListener final { ChildProcessChannelListener() = default; ~ChildProcessChannelListener() = default; struct CallbackArgs { - nsCOMPtr mChannel; + nsCOMPtr mChannel; nsTArray mRedirects; uint32_t mLoadStateLoadFlags; }; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index bbbf5b5c3515..6bd63b75241e 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -9338,7 +9338,7 @@ static bool SchemeUsesDocChannel(nsIURI* aURI) { } if (StaticPrefs::browser_tabs_documentchannel() && XRE_IsContentProcess() && - SchemeUsesDocChannel(aLoadState->URI())) { + SchemeUsesDocChannel(aLoadState->URI()) && !isSrcdoc) { RefPtr child = new DocumentChannelChild( aLoadState, aLoadInfo, aInitiatorType, aLoadFlags, aLoadType, aCacheKey, aIsActive, aIsTopLevelDoc, aHasNonEmptySandboxingFlags); @@ -9755,15 +9755,20 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState, } // open a channel for the url + nsCOMPtr channel; // If we have a pending channel, use the channel we've already created here. // We don't need to set up load flags for our channel, as it has already been // created. - nsCOMPtr channel = aLoadState->GetPendingRedirectedChannel(); - if (channel) { + nsCOMPtr pendingChannel = + aLoadState->GetPendingRedirectedChannel(); + if (pendingChannel) { MOZ_ASSERT(!aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_IS_SRCDOC), "pending channel for srcdoc load?"); + channel = do_QueryInterface(pendingChannel); + MOZ_ASSERT(channel, "nsIChildChannel isn't a nsIChannel?"); + // If we have a request outparameter, shove our channel into it. if (aRequest) { nsCOMPtr outRequest = channel; @@ -12764,11 +12769,14 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) { // Call into InternalLoad with the pending channel when it is received. cpcl->RegisterCallback( aIdentifier, - [self, aHistoryIndex](nsIChannel* aChannel, + [self, aHistoryIndex](nsIChildChannel* aChannel, nsTArray&& aRedirects, uint32_t aLoadStateLoadFlags) { if (NS_WARN_IF(self->mIsBeingDestroyed)) { - aChannel->Cancel(NS_BINDING_ABORTED); + nsCOMPtr request = do_QueryInterface(aChannel); + if (request) { + request->Cancel(NS_BINDING_ABORTED); + } return; } @@ -12780,11 +12788,14 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) { } loadState->SetLoadFlags(aLoadStateLoadFlags); - nsCOMPtr previousURI; - uint32_t previousFlags = 0; - ExtractLastVisit(aChannel, getter_AddRefs(previousURI), &previousFlags); - self->SavePreviousRedirectsAndLastVisit(aChannel, previousURI, - previousFlags, aRedirects); + if (nsCOMPtr channel = do_QueryInterface(aChannel)) { + nsCOMPtr previousURI; + uint32_t previousFlags = 0; + ExtractLastVisit(channel, getter_AddRefs(previousURI), + &previousFlags); + self->SavePreviousRedirectsAndLastVisit(channel, previousURI, + previousFlags, aRedirects); + } // If we're performing a history load, locate the correct history entry, // and set the relevant bits on our loadState. diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index b77cb38b77ba..d74a9c5c9cfd 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -10,7 +10,7 @@ #include "SHEntryChild.h" #include "nsISHEntry.h" #include "nsIWebNavigation.h" -#include "nsIChannel.h" +#include "nsIChildChannel.h" #include "ReferrerInfo.h" #include "mozilla/BasePrincipal.h" #include "mozilla/dom/BrowsingContext.h" @@ -90,11 +90,16 @@ nsDocShellLoadState::nsDocShellLoadState( nsDocShellLoadState::~nsDocShellLoadState() {} nsresult nsDocShellLoadState::CreateFromPendingChannel( - nsIChannel* aPendingChannel, nsDocShellLoadState** aResult) { + nsIChildChannel* aPendingChannel, nsDocShellLoadState** aResult) { + nsCOMPtr channel = do_QueryInterface(aPendingChannel); + if (NS_WARN_IF(!channel)) { + return NS_ERROR_UNEXPECTED; + } + // Create the nsDocShellLoadState object with default state pulled from the // passed-in channel. nsCOMPtr uri; - nsresult rv = aPendingChannel->GetURI(getter_AddRefs(uri)); + nsresult rv = channel->GetURI(getter_AddRefs(uri)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -105,13 +110,13 @@ nsresult nsDocShellLoadState::CreateFromPendingChannel( // Pull relevant state from the channel, and store it on the // nsDocShellLoadState. nsCOMPtr originalUri; - rv = aPendingChannel->GetOriginalURI(getter_AddRefs(originalUri)); + rv = channel->GetOriginalURI(getter_AddRefs(originalUri)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } loadState->SetOriginalURI(originalUri); - nsCOMPtr loadInfo = aPendingChannel->LoadInfo(); + nsCOMPtr loadInfo = channel->LoadInfo(); loadState->SetTriggeringPrincipal(loadInfo->TriggeringPrincipal()); // Return the newly created loadState. diff --git a/docshell/base/nsDocShellLoadState.h b/docshell/base/nsDocShellLoadState.h index 45b6055d2a74..d7571b0a9681 100644 --- a/docshell/base/nsDocShellLoadState.h +++ b/docshell/base/nsDocShellLoadState.h @@ -19,7 +19,7 @@ class nsIInputStream; class nsISHEntry; class nsIURI; class nsIDocShell; -class nsIChannel; +class nsIChildChannel; class nsIReferrerInfo; class OriginAttibutes; namespace mozilla { @@ -40,7 +40,7 @@ class nsDocShellLoadState final { explicit nsDocShellLoadState( const mozilla::dom::DocShellLoadStateInit& aLoadState); - static nsresult CreateFromPendingChannel(nsIChannel* aPendingChannel, + static nsresult CreateFromPendingChannel(nsIChildChannel* aPendingChannel, nsDocShellLoadState** aResult); static nsresult CreateFromLoadURIOptions( @@ -200,7 +200,7 @@ class nsDocShellLoadState final { return mIsFromProcessingFrameAttributes; } - nsIChannel* GetPendingRedirectedChannel() { + nsIChildChannel* GetPendingRedirectedChannel() { return mPendingRedirectedChannel; } @@ -365,7 +365,7 @@ class nsDocShellLoadState final { // If set, a pending cross-process redirected channel should be used to // perform the load. The channel will be stored in this value. - nsCOMPtr mPendingRedirectedChannel; + nsCOMPtr mPendingRedirectedChannel; // An optional string representation of mURI, before any // fixups were applied, so that we can send it to a search diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 26d5b3653dab..b8e5d3659ab7 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -114,7 +114,6 @@ #include "nsIConsoleService.h" #include "audio_thread_priority.h" #include "nsIURIMutator.h" -#include "nsIInputStreamChannel.h" #if !defined(XP_WIN) # include "mozilla/Omnijar.h" @@ -3694,24 +3693,11 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect( } nsCOMPtr newChannel; - if (aArgs.loadStateLoadFlags() & - nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_IS_SRCDOC) { - rv = NS_NewInputStreamChannelInternal( - getter_AddRefs(newChannel), aArgs.uri(), aArgs.srcdocData(), - NS_LITERAL_CSTRING("text/html"), loadInfo, true); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr isc = do_QueryInterface(newChannel); - MOZ_ASSERT(isc); - isc->SetBaseURI(aArgs.baseUri()); - } - } else { - rv = - NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, - nullptr, // PerformanceStorage - nullptr, // aLoadGroup - nullptr, // aCallbacks - aArgs.newLoadFlags()); - } + rv = NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, + nullptr, // PerformanceStorage + nullptr, // aLoadGroup + nullptr, // aCallbacks + aArgs.newLoadFlags()); // This is used to report any errors back to the parent by calling // CrossProcessRedirectFinished. @@ -3735,6 +3721,12 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect( return IPC_OK(); } + RefPtr childChannel = do_QueryObject(newChannel); + if (!childChannel) { + rv = NS_ERROR_UNEXPECTED; + return IPC_OK(); + } + if (httpChild) { rv = httpChild->SetChannelId(aArgs.channelId()); if (NS_FAILED(rv)) { @@ -3759,15 +3751,11 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect( HttpBaseChannel::ReplacementReason::DocumentChannel); } - if (nsCOMPtr childChannel = do_QueryInterface(newChannel)) { - // Connect to the parent if this is a remote channel. If it's entirely - // handled locally, then we'll call AsyncOpen from the docshell when - // we complete the setup - rv = childChannel->ConnectParent( - aArgs.registrarId()); // creates parent channel - if (NS_FAILED(rv)) { - return IPC_OK(); - } + // connect parent. + rv = childChannel->ConnectParent( + aArgs.registrarId()); // creates parent channel + if (NS_FAILED(rv)) { + return IPC_OK(); } // We need to copy the property bag before signaling that the channel @@ -3778,8 +3766,8 @@ mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect( RefPtr processListener = ChildProcessChannelListener::GetSingleton(); - // The listener will call completeRedirectSetup or asyncOpen on the channel. - processListener->OnChannelReady(newChannel, aArgs.redirectIdentifier(), + // The listener will call completeRedirectSetup on the channel. + processListener->OnChannelReady(childChannel, aArgs.redirectIdentifier(), std::move(aArgs.redirects()), aArgs.loadStateLoadFlags()); diff --git a/layout/style/crashtests/1541126.html b/layout/style/crashtests/1541126.html new file mode 100644 index 000000000000..3f6862514a13 --- /dev/null +++ b/layout/style/crashtests/1541126.html @@ -0,0 +1,20 @@ + + + + + +
diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index b9178a88beaa..e4488d6e23ab 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -301,6 +301,7 @@ load 1514086.html load 1533783.html load 1533891.html pref(gfx.omta.background-color,true) load 1533968.html +load 1541126.html load 1545177.html skip-if(geckoview&&webrender) skip-if(Android) load 1546255.html # Bug 1563020 for GV+WR & Bug 1553971 pref(layout.css.resizeobserver.enabled,true) load 1552911.html diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index 2d1619406cfc..27adad606747 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -22,7 +22,6 @@ #include "nsContentSecurityManager.h" #include "nsDocShellLoadState.h" #include "nsHttpHandler.h" -#include "nsIInputStreamChannel.h" #include "nsQueryObject.h" #include "nsSerializationHelper.h" #include "nsStreamListenerWrapper.h" @@ -321,26 +320,12 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel( mRedirectResolver = std::move(aResolve); nsCOMPtr newChannel; - nsresult rv; - if (aArgs.loadStateLoadFlags() & - nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_IS_SRCDOC) { - rv = NS_NewInputStreamChannelInternal( - getter_AddRefs(newChannel), aArgs.uri(), aArgs.srcdocData(), - NS_LITERAL_CSTRING("text/html"), loadInfo, true); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr isc = do_QueryInterface(newChannel); - MOZ_ASSERT(isc); - isc->SetBaseURI(aArgs.baseUri()); - newChannel->SetLoadGroup(mLoadGroup); - } - } else { - rv = - NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, - nullptr, // PerformanceStorage - mLoadGroup, // aLoadGroup - nullptr, // aCallbacks - aArgs.newLoadFlags()); - } + nsresult rv = + NS_NewChannelInternal(getter_AddRefs(newChannel), aArgs.uri(), loadInfo, + nullptr, // PerformanceStorage + mLoadGroup, // aLoadGroup + nullptr, // aCallbacks + aArgs.newLoadFlags()); // This is used to report any errors back to the parent by calling // CrossProcessRedirectFinished. @@ -429,10 +414,6 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel( NS_IMETHODIMP DocumentChannelChild::OnRedirectVerifyCallback(nsresult aStatusCode) { - LOG( - ("DocumentChannelChild OnRedirectVerifyCallback [this=%p, " - "aRv=0x%08" PRIx32 " ]", - this, static_cast(aStatusCode))); nsCOMPtr redirectChannel = std::move(mRedirectChannel); RedirectToRealChannelResolver redirectResolver = std::move(mRedirectResolver); diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index 8f5ddf0730e0..191fa581e74f 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -340,8 +340,6 @@ bool DocumentLoadListener::Open( mChannelCreationURI = aLoadState->URI(); mLoadStateLoadFlags = aLoadState->LoadFlags(); - mSrcdocData = aLoadState->SrcdocData(); - mBaseURI = aLoadState->BaseURI(); return true; } @@ -424,10 +422,6 @@ DocumentLoadListener::ReadyToVerify(nsresult aResultCode) { } void DocumentLoadListener::FinishReplacementChannelSetup(bool aSucceeded) { - LOG( - ("DocumentLoadListener FinishReplacementChannelSetup [this=%p, " - "aSucceeded=%d]", - this, aSucceeded)); nsresult rv; if (mDoingProcessSwitch) { @@ -540,7 +534,6 @@ void DocumentLoadListener::FinishReplacementChannelSetup(bool aSucceeded) { void DocumentLoadListener::ResumeSuspendedChannel( nsIStreamListener* aListener) { - LOG(("DocumentLoadListener ResumeSuspendedChannel [this=%p]", this)); RefPtr httpChannel = do_QueryObject(mChannel); if (httpChannel) { httpChannel->SetApplyConversion(mOldApplyConversion); @@ -729,9 +722,6 @@ void DocumentLoadListener::SerializeRedirectData( nsDocShell::ExtractLastVisit(mChannel, getter_AddRefs(previousURI), &previousFlags); aArgs.lastVisitInfo() = LastVisitInfo{previousURI, previousFlags}; - aArgs.srcdocData() = mSrcdocData; - aArgs.baseUri() = mBaseURI; - aArgs.loadStateLoadFlags() = mLoadStateLoadFlags; } void DocumentLoadListener::TriggerCrossProcessSwitch() { diff --git a/netwerk/ipc/DocumentLoadListener.h b/netwerk/ipc/DocumentLoadListener.h index 6d86cb0286ac..3a64875edcf1 100644 --- a/netwerk/ipc/DocumentLoadListener.h +++ b/netwerk/ipc/DocumentLoadListener.h @@ -322,9 +322,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor, nsTArray mRedirects; - nsString mSrcdocData; - nsCOMPtr mBaseURI; - // Flags from nsDocShellLoadState::LoadFlags that we want to make available // to the new docshell if we switch processes. uint32_t mLoadStateLoadFlags = 0; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index d8e0d7481938..5cda780f180b 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -441,8 +441,6 @@ struct RedirectToRealChannelArgs { nsIPropertyBag2 properties; LastVisitInfo lastVisitInfo; uint32_t loadStateLoadFlags; - nsString srcdocData; - nsIURI baseUri; }; struct TimingStructArgs { diff --git a/uriloader/base/nsURILoader.cpp b/uriloader/base/nsURILoader.cpp index 8efd36066013..3fbaf3623ad6 100644 --- a/uriloader/base/nsURILoader.cpp +++ b/uriloader/base/nsURILoader.cpp @@ -715,38 +715,37 @@ NS_IMETHODIMP nsURILoader::OpenURI(nsIChannel* channel, uint32_t aFlags, nsCOMPtr loader; nsresult rv = OpenChannel(channel, aFlags, aWindowContext, false, getter_AddRefs(loader)); - if (NS_FAILED(rv)) { - if (rv == NS_ERROR_WONT_HANDLE_CONTENT) { - // Not really an error, from this method's point of view - return NS_OK; - } - } - if (aFlags & nsIURILoader::REDIRECTED_CHANNEL) { - // Our channel was redirected from another process, so doesn't need to - // be opened again. However, it does need its listener hooked up - // correctly. - if (nsCOMPtr childChannel = do_QueryInterface(channel)) { + if (NS_SUCCEEDED(rv)) { + if (aFlags & nsIURILoader::REDIRECTED_CHANNEL) { + // Our channel was redirected from another process, so doesn't need to + // be opened again. However, it does need its listener hooked up + // correctly. + nsCOMPtr childChannel = do_QueryInterface(channel); + MOZ_ASSERT(childChannel); + if (!childChannel) { + return NS_ERROR_UNEXPECTED; + } + return childChannel->CompleteRedirectSetup(loader, nullptr); } - // It's possible for the redirected channel to not implement - // nsIChildChannel and be entirely local (like srcdoc). In that case we - // can just open the local instance and it will work. - } + // this method is not complete!!! Eventually, we should first go + // to the content listener and ask them for a protocol handler... + // if they don't give us one, we need to go to the registry and get + // the preferred protocol handler. - // This method is not complete. Eventually, we should first go - // to the content listener and ask them for a protocol handler... - // if they don't give us one, we need to go to the registry and get - // the preferred protocol handler. + // But for now, I'm going to let necko do the work for us.... + rv = channel->AsyncOpen(loader); - // But for now, I'm going to let necko do the work for us.... - rv = channel->AsyncOpen(loader); - - // no content from this load - that's OK. - if (rv == NS_ERROR_NO_CONTENT) { - LOG((" rv is NS_ERROR_NO_CONTENT -- doing nothing")); - return NS_OK; + // no content from this load - that's OK. + if (rv == NS_ERROR_NO_CONTENT) { + LOG((" rv is NS_ERROR_NO_CONTENT -- doing nothing")); + rv = NS_OK; + } + } else if (rv == NS_ERROR_WONT_HANDLE_CONTENT) { + // Not really an error, from this method's point of view + rv = NS_OK; } return rv; }