From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- docshell/base/IHistory.h | 144 + docshell/base/LoadContext.cpp | 229 + docshell/base/LoadContext.h | 123 + docshell/base/SerializedLoadContext.cpp | 77 + docshell/base/SerializedLoadContext.h | 92 + docshell/base/crashtests/1257730-1.html | 25 + docshell/base/crashtests/1331295.html | 25 + docshell/base/crashtests/1341657.html | 14 + docshell/base/crashtests/369126-1.html | 16 + docshell/base/crashtests/403574-1.xhtml | 23 + docshell/base/crashtests/40929-1-inner.html | 14 + docshell/base/crashtests/40929-1.html | 6 + docshell/base/crashtests/430124-1.html | 5 + docshell/base/crashtests/430628-1.html | 8 + docshell/base/crashtests/432114-1.html | 8 + docshell/base/crashtests/432114-2.html | 16 + docshell/base/crashtests/436900-1-inner.html | 21 + docshell/base/crashtests/436900-1.html | 8 + docshell/base/crashtests/436900-2-inner.html | 21 + docshell/base/crashtests/436900-2.html | 8 + docshell/base/crashtests/500328-1.html | 17 + docshell/base/crashtests/514779-1.xhtml | 9 + docshell/base/crashtests/614499-1.html | 20 + docshell/base/crashtests/678872-1.html | 36 + docshell/base/crashtests/914521.html | 33 + docshell/base/crashtests/crashtests.list | 16 + docshell/base/moz.build | 88 + docshell/base/nsAboutRedirector.cpp | 224 + docshell/base/nsAboutRedirector.h | 32 + docshell/base/nsCDefaultURIFixup.idl | 13 + docshell/base/nsDSURIContentListener.cpp | 539 + docshell/base/nsDSURIContentListener.h | 74 + docshell/base/nsDefaultURIFixup.cpp | 1152 ++ docshell/base/nsDefaultURIFixup.h | 69 + docshell/base/nsDocShell.cpp | 14853 +++++++++++++++++++ docshell/base/nsDocShell.h | 1083 ++ docshell/base/nsDocShellEditorData.cpp | 192 + docshell/base/nsDocShellEditorData.h | 63 + docshell/base/nsDocShellEnumerator.cpp | 205 + docshell/base/nsDocShellEnumerator.h | 107 + docshell/base/nsDocShellLoadInfo.cpp | 297 + docshell/base/nsDocShellLoadInfo.h | 53 + docshell/base/nsDocShellLoadTypes.h | 117 + docshell/base/nsDocShellTransferableHooks.cpp | 54 + docshell/base/nsDocShellTransferableHooks.h | 28 + docshell/base/nsDownloadHistory.cpp | 52 + docshell/base/nsDownloadHistory.h | 28 + docshell/base/nsIClipboardCommands.idl | 111 + docshell/base/nsIContentViewer.idl | 280 + docshell/base/nsIContentViewerContainer.idl | 20 + docshell/base/nsIContentViewerEdit.idl | 36 + docshell/base/nsIContentViewerFile.idl | 31 + docshell/base/nsIDocCharset.idl | 19 + docshell/base/nsIDocShell.idl | 1186 ++ docshell/base/nsIDocShellLoadInfo.idl | 125 + docshell/base/nsIDocShellTreeItem.idl | 184 + docshell/base/nsIDocShellTreeOwner.idl | 109 + docshell/base/nsIDocumentLoaderFactory.idl | 46 + docshell/base/nsIDownloadHistory.idl | 58 + docshell/base/nsIGlobalHistory2.idl | 59 + docshell/base/nsILinkHandler.h | 94 + docshell/base/nsILoadContext.idl | 155 + docshell/base/nsIPrivacyTransitionObserver.idl | 11 + docshell/base/nsIReflowObserver.idl | 31 + docshell/base/nsIRefreshURI.idl | 91 + docshell/base/nsIScrollObserver.h | 42 + docshell/base/nsIScrollable.idl | 55 + docshell/base/nsITextScroll.idl | 33 + docshell/base/nsIURIFixup.idl | 166 + docshell/base/nsIWebNavigation.idl | 367 + docshell/base/nsIWebNavigationInfo.idl | 63 + docshell/base/nsIWebPageDescriptor.idl | 30 + docshell/base/nsIWebShellServices.h | 34 + docshell/base/nsWebNavigationInfo.cpp | 134 + docshell/base/nsWebNavigationInfo.h | 42 + docshell/base/timeline/AbstractTimelineMarker.cpp | 90 + docshell/base/timeline/AbstractTimelineMarker.h | 73 + .../base/timeline/AutoGlobalTimelineMarker.cpp | 43 + docshell/base/timeline/AutoGlobalTimelineMarker.h | 51 + docshell/base/timeline/AutoTimelineMarker.cpp | 51 + docshell/base/timeline/AutoTimelineMarker.h | 51 + docshell/base/timeline/CompositeTimelineMarker.h | 33 + docshell/base/timeline/ConsoleTimelineMarker.h | 58 + docshell/base/timeline/DocLoadingTimelineMarker.h | 40 + docshell/base/timeline/EventTimelineMarker.h | 43 + docshell/base/timeline/JavascriptTimelineMarker.h | 95 + docshell/base/timeline/LayerTimelineMarker.h | 43 + docshell/base/timeline/MarkersStorage.cpp | 29 + docshell/base/timeline/MarkersStorage.h | 48 + docshell/base/timeline/MessagePortTimelineMarker.h | 47 + docshell/base/timeline/ObservedDocShell.cpp | 171 + docshell/base/timeline/ObservedDocShell.h | 52 + docshell/base/timeline/RestyleTimelineMarker.h | 42 + docshell/base/timeline/TimelineConsumers.cpp | 312 + docshell/base/timeline/TimelineConsumers.h | 135 + docshell/base/timeline/TimelineMarker.cpp | 71 + docshell/base/timeline/TimelineMarker.h | 49 + docshell/base/timeline/TimelineMarkerEnums.h | 26 + docshell/base/timeline/TimestampTimelineMarker.h | 38 + docshell/base/timeline/WorkerTimelineMarker.h | 46 + docshell/base/timeline/moz.build | 42 + docshell/base/timeline/readme.md | 97 + 102 files changed, 25825 insertions(+) create mode 100644 docshell/base/IHistory.h create mode 100644 docshell/base/LoadContext.cpp create mode 100644 docshell/base/LoadContext.h create mode 100644 docshell/base/SerializedLoadContext.cpp create mode 100644 docshell/base/SerializedLoadContext.h create mode 100644 docshell/base/crashtests/1257730-1.html create mode 100644 docshell/base/crashtests/1331295.html create mode 100644 docshell/base/crashtests/1341657.html create mode 100644 docshell/base/crashtests/369126-1.html create mode 100644 docshell/base/crashtests/403574-1.xhtml create mode 100644 docshell/base/crashtests/40929-1-inner.html create mode 100644 docshell/base/crashtests/40929-1.html create mode 100644 docshell/base/crashtests/430124-1.html create mode 100644 docshell/base/crashtests/430628-1.html create mode 100644 docshell/base/crashtests/432114-1.html create mode 100644 docshell/base/crashtests/432114-2.html create mode 100644 docshell/base/crashtests/436900-1-inner.html create mode 100644 docshell/base/crashtests/436900-1.html create mode 100644 docshell/base/crashtests/436900-2-inner.html create mode 100644 docshell/base/crashtests/436900-2.html create mode 100644 docshell/base/crashtests/500328-1.html create mode 100644 docshell/base/crashtests/514779-1.xhtml create mode 100644 docshell/base/crashtests/614499-1.html create mode 100644 docshell/base/crashtests/678872-1.html create mode 100644 docshell/base/crashtests/914521.html create mode 100644 docshell/base/crashtests/crashtests.list create mode 100644 docshell/base/moz.build create mode 100644 docshell/base/nsAboutRedirector.cpp create mode 100644 docshell/base/nsAboutRedirector.h create mode 100644 docshell/base/nsCDefaultURIFixup.idl create mode 100644 docshell/base/nsDSURIContentListener.cpp create mode 100644 docshell/base/nsDSURIContentListener.h create mode 100644 docshell/base/nsDefaultURIFixup.cpp create mode 100644 docshell/base/nsDefaultURIFixup.h create mode 100644 docshell/base/nsDocShell.cpp create mode 100644 docshell/base/nsDocShell.h create mode 100644 docshell/base/nsDocShellEditorData.cpp create mode 100644 docshell/base/nsDocShellEditorData.h create mode 100644 docshell/base/nsDocShellEnumerator.cpp create mode 100644 docshell/base/nsDocShellEnumerator.h create mode 100644 docshell/base/nsDocShellLoadInfo.cpp create mode 100644 docshell/base/nsDocShellLoadInfo.h create mode 100644 docshell/base/nsDocShellLoadTypes.h create mode 100644 docshell/base/nsDocShellTransferableHooks.cpp create mode 100644 docshell/base/nsDocShellTransferableHooks.h create mode 100644 docshell/base/nsDownloadHistory.cpp create mode 100644 docshell/base/nsDownloadHistory.h create mode 100644 docshell/base/nsIClipboardCommands.idl create mode 100644 docshell/base/nsIContentViewer.idl create mode 100644 docshell/base/nsIContentViewerContainer.idl create mode 100644 docshell/base/nsIContentViewerEdit.idl create mode 100644 docshell/base/nsIContentViewerFile.idl create mode 100644 docshell/base/nsIDocCharset.idl create mode 100644 docshell/base/nsIDocShell.idl create mode 100644 docshell/base/nsIDocShellLoadInfo.idl create mode 100644 docshell/base/nsIDocShellTreeItem.idl create mode 100644 docshell/base/nsIDocShellTreeOwner.idl create mode 100644 docshell/base/nsIDocumentLoaderFactory.idl create mode 100644 docshell/base/nsIDownloadHistory.idl create mode 100644 docshell/base/nsIGlobalHistory2.idl create mode 100644 docshell/base/nsILinkHandler.h create mode 100644 docshell/base/nsILoadContext.idl create mode 100644 docshell/base/nsIPrivacyTransitionObserver.idl create mode 100644 docshell/base/nsIReflowObserver.idl create mode 100644 docshell/base/nsIRefreshURI.idl create mode 100644 docshell/base/nsIScrollObserver.h create mode 100644 docshell/base/nsIScrollable.idl create mode 100644 docshell/base/nsITextScroll.idl create mode 100644 docshell/base/nsIURIFixup.idl create mode 100644 docshell/base/nsIWebNavigation.idl create mode 100644 docshell/base/nsIWebNavigationInfo.idl create mode 100644 docshell/base/nsIWebPageDescriptor.idl create mode 100644 docshell/base/nsIWebShellServices.h create mode 100644 docshell/base/nsWebNavigationInfo.cpp create mode 100644 docshell/base/nsWebNavigationInfo.h create mode 100644 docshell/base/timeline/AbstractTimelineMarker.cpp create mode 100644 docshell/base/timeline/AbstractTimelineMarker.h create mode 100644 docshell/base/timeline/AutoGlobalTimelineMarker.cpp create mode 100644 docshell/base/timeline/AutoGlobalTimelineMarker.h create mode 100644 docshell/base/timeline/AutoTimelineMarker.cpp create mode 100644 docshell/base/timeline/AutoTimelineMarker.h create mode 100644 docshell/base/timeline/CompositeTimelineMarker.h create mode 100644 docshell/base/timeline/ConsoleTimelineMarker.h create mode 100644 docshell/base/timeline/DocLoadingTimelineMarker.h create mode 100644 docshell/base/timeline/EventTimelineMarker.h create mode 100644 docshell/base/timeline/JavascriptTimelineMarker.h create mode 100644 docshell/base/timeline/LayerTimelineMarker.h create mode 100644 docshell/base/timeline/MarkersStorage.cpp create mode 100644 docshell/base/timeline/MarkersStorage.h create mode 100644 docshell/base/timeline/MessagePortTimelineMarker.h create mode 100644 docshell/base/timeline/ObservedDocShell.cpp create mode 100644 docshell/base/timeline/ObservedDocShell.h create mode 100644 docshell/base/timeline/RestyleTimelineMarker.h create mode 100644 docshell/base/timeline/TimelineConsumers.cpp create mode 100644 docshell/base/timeline/TimelineConsumers.h create mode 100644 docshell/base/timeline/TimelineMarker.cpp create mode 100644 docshell/base/timeline/TimelineMarker.h create mode 100644 docshell/base/timeline/TimelineMarkerEnums.h create mode 100644 docshell/base/timeline/TimestampTimelineMarker.h create mode 100644 docshell/base/timeline/WorkerTimelineMarker.h create mode 100644 docshell/base/timeline/moz.build create mode 100644 docshell/base/timeline/readme.md (limited to 'docshell/base') diff --git a/docshell/base/IHistory.h b/docshell/base/IHistory.h new file mode 100644 index 000000000..b1f5bb983 --- /dev/null +++ b/docshell/base/IHistory.h @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_IHistory_h_ +#define mozilla_IHistory_h_ + +#include "nsISupports.h" + +class nsIURI; + +namespace mozilla { + +namespace dom { +class Link; +} // namespace dom + +// 0057c9d3-b98e-4933-bdc5-0275d06705e1 +#define IHISTORY_IID \ + {0x0057c9d3, 0xb98e, 0x4933, {0xbd, 0xc5, 0x02, 0x75, 0xd0, 0x67, 0x05, 0xe1}} + +class IHistory : public nsISupports +{ +public: + NS_DECLARE_STATIC_IID_ACCESSOR(IHISTORY_IID) + + /** + * Registers the Link for notifications about the visited-ness of aURI. + * Consumers should assume that the URI is unvisited after calling this, and + * they will be notified if that state (unvisited) changes by having + * SetLinkState called on themselves. This function is guaranteed to run to + * completion before aLink is notified. After the node is notified, it will + * be unregistered. + * + * @note SetLinkState must not call RegisterVisitedCallback or + * UnregisterVisitedCallback. + * + * @pre aURI must not be null. + * @pre aLink may be null only in the parent (chrome) process. + * + * @param aURI + * The URI to check. + * @param aLink + * The link to update whenever the history status changes. The + * implementation will only hold onto a raw pointer, so if this + * object should be destroyed, be sure to call + * UnregisterVistedCallback first. + */ + NS_IMETHOD RegisterVisitedCallback(nsIURI* aURI, dom::Link* aLink) = 0; + + /** + * Unregisters a previously registered Link object. This must be called + * before destroying the registered object. + * + * @pre aURI must not be null. + * @pre aLink must not be null. + * + * @param aURI + * The URI that aLink was registered for. + * @param aLink + * The link object to unregister for aURI. + */ + NS_IMETHOD UnregisterVisitedCallback(nsIURI* aURI, dom::Link* aLink) = 0; + + enum VisitFlags + { + /** + * Indicates whether the URI was loaded in a top-level window. + */ + TOP_LEVEL = 1 << 0, + /** + * Indicates whether the URI was loaded as part of a permanent redirect. + */ + REDIRECT_PERMANENT = 1 << 1, + /** + * Indicates whether the URI was loaded as part of a temporary redirect. + */ + REDIRECT_TEMPORARY = 1 << 2, + /** + * Indicates the URI is redirecting (Response code 3xx). + */ + REDIRECT_SOURCE = 1 << 3, + /** + * Indicates the URI caused an error that is unlikely fixable by a + * retry, like a not found or unfetchable page. + */ + UNRECOVERABLE_ERROR = 1 << 4 + }; + + /** + * Adds a history visit for the URI. + * + * @pre aURI must not be null. + * + * @param aURI + * The URI of the page being visited. + * @param aLastVisitedURI + * The URI of the last visit in the chain. + * @param aFlags + * The VisitFlags describing this visit. + */ + NS_IMETHOD VisitURI(nsIURI* aURI, + nsIURI* aLastVisitedURI, + uint32_t aFlags) = 0; + + /** + * Set the title of the URI. + * + * @pre aURI must not be null. + * + * @param aURI + * The URI to set the title for. + * @param aTitle + * The title string. + */ + NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) = 0; + + /** + * Notifies about the visited status of a given URI. + * + * @param aURI + * The URI to notify about. + */ + NS_IMETHOD NotifyVisited(nsIURI* aURI) = 0; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(IHistory, IHISTORY_IID) + +#define NS_DECL_IHISTORY \ + NS_IMETHOD RegisterVisitedCallback(nsIURI* aURI, \ + mozilla::dom::Link* aContent) override; \ + NS_IMETHOD UnregisterVisitedCallback(nsIURI* aURI, \ + mozilla::dom::Link* aContent) override; \ + NS_IMETHOD VisitURI(nsIURI* aURI, \ + nsIURI* aLastVisitedURI, \ + uint32_t aFlags) override; \ + NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) override; \ + NS_IMETHOD NotifyVisited(nsIURI* aURI) override; + +} // namespace mozilla + +#endif // mozilla_IHistory_h_ diff --git a/docshell/base/LoadContext.cpp b/docshell/base/LoadContext.cpp new file mode 100644 index 000000000..c4095a951 --- /dev/null +++ b/docshell/base/LoadContext.cpp @@ -0,0 +1,229 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/Assertions.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/LoadContext.h" +#include "mozilla/Preferences.h" +#include "mozilla/dom/ScriptSettings.h" // for AutoJSAPI +#include "nsContentUtils.h" +#include "xpcpublic.h" + +bool +nsILoadContext::GetOriginAttributes(mozilla::DocShellOriginAttributes& aAttrs) +{ + mozilla::dom::AutoJSAPI jsapi; + bool ok = jsapi.Init(xpc::PrivilegedJunkScope()); + NS_ENSURE_TRUE(ok, false); + JS::Rooted v(jsapi.cx()); + nsresult rv = GetOriginAttributes(&v); + NS_ENSURE_SUCCESS(rv, false); + NS_ENSURE_TRUE(v.isObject(), false); + JS::Rooted obj(jsapi.cx(), &v.toObject()); + + // If we're JS-implemented, the object will be left in a different (System-Principaled) + // scope, so we may need to enter its compartment. + MOZ_ASSERT(nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj))); + JSAutoCompartment ac(jsapi.cx(), obj); + + mozilla::DocShellOriginAttributes attrs; + ok = attrs.Init(jsapi.cx(), v); + NS_ENSURE_TRUE(ok, false); + aAttrs = attrs; + return true; +} + +namespace mozilla { + +NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor) + +LoadContext::LoadContext(nsIPrincipal* aPrincipal, + nsILoadContext* aOptionalBase) + : mTopFrameElement(nullptr) + , mNestedFrameId(0) + , mIsContent(true) + , mUseRemoteTabs(false) +#ifdef DEBUG + , mIsNotNull(true) +#endif +{ + PrincipalOriginAttributes poa = BasePrincipal::Cast(aPrincipal)->OriginAttributesRef(); + mOriginAttributes.InheritFromDocToChildDocShell(poa); + if (!aOptionalBase) { + return; + } + + MOZ_ALWAYS_SUCCEEDS(aOptionalBase->GetIsContent(&mIsContent)); + MOZ_ALWAYS_SUCCEEDS(aOptionalBase->GetUseRemoteTabs(&mUseRemoteTabs)); +} + +//----------------------------------------------------------------------------- +// LoadContext::nsILoadContext +//----------------------------------------------------------------------------- + +NS_IMETHODIMP +LoadContext::GetAssociatedWindow(mozIDOMWindowProxy**) +{ + MOZ_ASSERT(mIsNotNull); + + // can't support this in the parent process + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP +LoadContext::GetTopWindow(mozIDOMWindowProxy**) +{ + MOZ_ASSERT(mIsNotNull); + + // can't support this in the parent process + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP +LoadContext::GetTopFrameElement(nsIDOMElement** aElement) +{ + nsCOMPtr element = do_QueryReferent(mTopFrameElement); + element.forget(aElement); + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::GetNestedFrameId(uint64_t* aId) +{ + NS_ENSURE_ARG(aId); + *aId = mNestedFrameId; + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::GetIsContent(bool* aIsContent) +{ + MOZ_ASSERT(mIsNotNull); + + NS_ENSURE_ARG_POINTER(aIsContent); + + *aIsContent = mIsContent; + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) +{ + MOZ_ASSERT(mIsNotNull); + + NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing); + + *aUsePrivateBrowsing = mOriginAttributes.mPrivateBrowsingId > 0; + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) +{ + MOZ_ASSERT(mIsNotNull); + + // We shouldn't need this on parent... + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP +LoadContext::SetPrivateBrowsing(bool aUsePrivateBrowsing) +{ + MOZ_ASSERT(mIsNotNull); + + // We shouldn't need this on parent... + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP +LoadContext::GetUseRemoteTabs(bool* aUseRemoteTabs) +{ + MOZ_ASSERT(mIsNotNull); + + NS_ENSURE_ARG_POINTER(aUseRemoteTabs); + + *aUseRemoteTabs = mUseRemoteTabs; + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::SetRemoteTabs(bool aUseRemoteTabs) +{ + MOZ_ASSERT(mIsNotNull); + + // We shouldn't need this on parent... + return NS_ERROR_UNEXPECTED; +} + +NS_IMETHODIMP +LoadContext::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement) +{ + MOZ_ASSERT(mIsNotNull); + + NS_ENSURE_ARG_POINTER(aIsInIsolatedMozBrowserElement); + + *aIsInIsolatedMozBrowserElement = mOriginAttributes.mInIsolatedMozBrowser; + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::GetAppId(uint32_t* aAppId) +{ + MOZ_ASSERT(mIsNotNull); + + NS_ENSURE_ARG_POINTER(aAppId); + + *aAppId = mOriginAttributes.mAppId; + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::GetOriginAttributes(JS::MutableHandleValue aAttrs) +{ + JSContext* cx = nsContentUtils::GetCurrentJSContext(); + MOZ_ASSERT(cx); + + bool ok = ToJSValue(cx, mOriginAttributes, aAttrs); + NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); + return NS_OK; +} + +NS_IMETHODIMP +LoadContext::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn) +{ + MOZ_ASSERT(mIsNotNull); + + if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) { + *aIsTrackingProtectionOn = true; + } else if ((mOriginAttributes.mPrivateBrowsingId > 0) && + Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) { + *aIsTrackingProtectionOn = true; + } else { + *aIsTrackingProtectionOn = false; + } + + return NS_OK; +} + +//----------------------------------------------------------------------------- +// LoadContext::nsIInterfaceRequestor +//----------------------------------------------------------------------------- +NS_IMETHODIMP +LoadContext::GetInterface(const nsIID& aIID, void** aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = nullptr; + + if (aIID.Equals(NS_GET_IID(nsILoadContext))) { + *aResult = static_cast(this); + NS_ADDREF_THIS(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + +} // namespace mozilla diff --git a/docshell/base/LoadContext.h b/docshell/base/LoadContext.h new file mode 100644 index 000000000..966e7b47f --- /dev/null +++ b/docshell/base/LoadContext.h @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef LoadContext_h +#define LoadContext_h + +#include "SerializedLoadContext.h" +#include "mozilla/Attributes.h" +#include "mozilla/BasePrincipal.h" +#include "nsIWeakReferenceUtils.h" +#include "mozilla/dom/Element.h" +#include "nsIInterfaceRequestor.h" +#include "nsILoadContext.h" + +namespace mozilla { + +/** + * Class that provides nsILoadContext info in Parent process. Typically copied + * from Child via SerializedLoadContext. + * + * Note: this is not the "normal" or "original" nsILoadContext. That is + * typically provided by nsDocShell. This is only used when the original + * docshell is in a different process and we need to copy certain values from + * it. + * + * Note: we also generate a new nsILoadContext using LoadContext(uint32_t aAppId) + * to separate the safebrowsing cookie. + */ + +class LoadContext final + : public nsILoadContext + , public nsIInterfaceRequestor +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSILOADCONTEXT + NS_DECL_NSIINTERFACEREQUESTOR + + // appId/inIsolatedMozBrowser arguments override those in SerializedLoadContext + // provided by child process. + LoadContext(const IPC::SerializedLoadContext& aToCopy, + dom::Element* aTopFrameElement, + DocShellOriginAttributes& aAttrs) + : mTopFrameElement(do_GetWeakReference(aTopFrameElement)) + , mNestedFrameId(0) + , mIsContent(aToCopy.mIsContent) + , mUseRemoteTabs(aToCopy.mUseRemoteTabs) + , mOriginAttributes(aAttrs) +#ifdef DEBUG + , mIsNotNull(aToCopy.mIsNotNull) +#endif + { + } + + // appId/inIsolatedMozBrowser arguments override those in SerializedLoadContext + // provided by child process. + LoadContext(const IPC::SerializedLoadContext& aToCopy, + uint64_t aNestedFrameId, + DocShellOriginAttributes& aAttrs) + : mTopFrameElement(nullptr) + , mNestedFrameId(aNestedFrameId) + , mIsContent(aToCopy.mIsContent) + , mUseRemoteTabs(aToCopy.mUseRemoteTabs) + , mOriginAttributes(aAttrs) +#ifdef DEBUG + , mIsNotNull(aToCopy.mIsNotNull) +#endif + { + } + + LoadContext(dom::Element* aTopFrameElement, + bool aIsContent, + bool aUsePrivateBrowsing, + bool aUseRemoteTabs, + const DocShellOriginAttributes& aAttrs) + : mTopFrameElement(do_GetWeakReference(aTopFrameElement)) + , mNestedFrameId(0) + , mIsContent(aIsContent) + , mUseRemoteTabs(aUseRemoteTabs) + , mOriginAttributes(aAttrs) +#ifdef DEBUG + , mIsNotNull(true) +#endif + { + } + + // Constructor taking reserved origin attributes. + explicit LoadContext(DocShellOriginAttributes& aAttrs) + : mTopFrameElement(nullptr) + , mNestedFrameId(0) + , mIsContent(false) + , mUseRemoteTabs(false) + , mOriginAttributes(aAttrs) +#ifdef DEBUG + , mIsNotNull(true) +#endif + { + } + + // Constructor for creating a LoadContext with a given principal's appId and + // browser flag. + explicit LoadContext(nsIPrincipal* aPrincipal, + nsILoadContext* aOptionalBase = nullptr); + +private: + ~LoadContext() {} + + nsWeakPtr mTopFrameElement; + uint64_t mNestedFrameId; + bool mIsContent; + bool mUseRemoteTabs; + DocShellOriginAttributes mOriginAttributes; +#ifdef DEBUG + bool mIsNotNull; +#endif +}; + +} // namespace mozilla + +#endif // LoadContext_h diff --git a/docshell/base/SerializedLoadContext.cpp b/docshell/base/SerializedLoadContext.cpp new file mode 100644 index 000000000..b8e3eb929 --- /dev/null +++ b/docshell/base/SerializedLoadContext.cpp @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SerializedLoadContext.h" +#include "nsNetUtil.h" +#include "nsIChannel.h" +#include "nsIPrivateBrowsingChannel.h" +#include "nsIWebSocketChannel.h" + +namespace IPC { + +SerializedLoadContext::SerializedLoadContext(nsILoadContext* aLoadContext) +{ + Init(aLoadContext); +} + +SerializedLoadContext::SerializedLoadContext(nsIChannel* aChannel) +{ + if (!aChannel) { + Init(nullptr); + return; + } + + nsCOMPtr loadContext; + NS_QueryNotificationCallbacks(aChannel, loadContext); + Init(loadContext); + + if (!loadContext) { + // Attempt to retrieve the private bit from the channel if it has been + // overriden. + bool isPrivate = false; + bool isOverriden = false; + nsCOMPtr pbChannel = do_QueryInterface(aChannel); + if (pbChannel && + NS_SUCCEEDED(pbChannel->IsPrivateModeOverriden(&isPrivate, + &isOverriden)) && + isOverriden) { + mIsPrivateBitValid = true; + } + mOriginAttributes.SyncAttributesWithPrivateBrowsing(isPrivate); + } +} + +SerializedLoadContext::SerializedLoadContext(nsIWebSocketChannel* aChannel) +{ + nsCOMPtr loadContext; + if (aChannel) { + NS_QueryNotificationCallbacks(aChannel, loadContext); + } + Init(loadContext); +} + +void +SerializedLoadContext::Init(nsILoadContext* aLoadContext) +{ + if (aLoadContext) { + mIsNotNull = true; + mIsPrivateBitValid = true; + aLoadContext->GetIsContent(&mIsContent); + aLoadContext->GetUseRemoteTabs(&mUseRemoteTabs); + if (!aLoadContext->GetOriginAttributes(mOriginAttributes)) { + NS_WARNING("GetOriginAttributes failed"); + } + } else { + mIsNotNull = false; + mIsPrivateBitValid = false; + // none of below values really matter when mIsNotNull == false: + // we won't be GetInterfaced to nsILoadContext + mIsContent = true; + mUseRemoteTabs = false; + } +} + +} // namespace IPC diff --git a/docshell/base/SerializedLoadContext.h b/docshell/base/SerializedLoadContext.h new file mode 100644 index 000000000..c81b39853 --- /dev/null +++ b/docshell/base/SerializedLoadContext.h @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef SerializedLoadContext_h +#define SerializedLoadContext_h + +#include "base/basictypes.h" +#include "ipc/IPCMessageUtils.h" +#include "mozilla/BasePrincipal.h" + +class nsILoadContext; + +/* + * This file contains the IPC::SerializedLoadContext class, which is used to + * copy data across IPDL from Child process contexts so it is available in the + * Parent. + */ + +class nsIChannel; +class nsIWebSocketChannel; + +namespace IPC { + +class SerializedLoadContext +{ +public: + SerializedLoadContext() + : mIsNotNull(false) + , mIsPrivateBitValid(false) + , mIsContent(false) + , mUseRemoteTabs(false) + { + Init(nullptr); + } + + explicit SerializedLoadContext(nsILoadContext* aLoadContext); + explicit SerializedLoadContext(nsIChannel* aChannel); + explicit SerializedLoadContext(nsIWebSocketChannel* aChannel); + + void Init(nsILoadContext* aLoadContext); + + bool IsNotNull() const { return mIsNotNull; } + bool IsPrivateBitValid() const { return mIsPrivateBitValid; } + + // used to indicate if child-side LoadContext * was null. + bool mIsNotNull; + // used to indicate if child-side mUsePrivateBrowsing flag is valid, even if + // mIsNotNull is false, i.e., child LoadContext was null. + bool mIsPrivateBitValid; + bool mIsContent; + bool mUseRemoteTabs; + mozilla::DocShellOriginAttributes mOriginAttributes; +}; + +// Function to serialize over IPDL +template<> +struct ParamTraits +{ + typedef SerializedLoadContext paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + nsAutoCString suffix; + aParam.mOriginAttributes.CreateSuffix(suffix); + + WriteParam(aMsg, aParam.mIsNotNull); + WriteParam(aMsg, aParam.mIsContent); + WriteParam(aMsg, aParam.mIsPrivateBitValid); + WriteParam(aMsg, aParam.mUseRemoteTabs); + WriteParam(aMsg, suffix); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) + { + nsAutoCString suffix; + if (!ReadParam(aMsg, aIter, &aResult->mIsNotNull) || + !ReadParam(aMsg, aIter, &aResult->mIsContent) || + !ReadParam(aMsg, aIter, &aResult->mIsPrivateBitValid) || + !ReadParam(aMsg, aIter, &aResult->mUseRemoteTabs) || + !ReadParam(aMsg, aIter, &suffix)) { + return false; + } + return aResult->mOriginAttributes.PopulateFromSuffix(suffix); + } +}; + +} // namespace IPC + +#endif // SerializedLoadContext_h diff --git a/docshell/base/crashtests/1257730-1.html b/docshell/base/crashtests/1257730-1.html new file mode 100644 index 000000000..028a1adb8 --- /dev/null +++ b/docshell/base/crashtests/1257730-1.html @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/docshell/base/crashtests/1331295.html b/docshell/base/crashtests/1331295.html new file mode 100644 index 000000000..cdcb29e7f --- /dev/null +++ b/docshell/base/crashtests/1331295.html @@ -0,0 +1,25 @@ + + + + + + + +
+ + + + diff --git a/docshell/base/crashtests/1341657.html b/docshell/base/crashtests/1341657.html new file mode 100644 index 000000000..852b8cc80 --- /dev/null +++ b/docshell/base/crashtests/1341657.html @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/docshell/base/crashtests/369126-1.html b/docshell/base/crashtests/369126-1.html new file mode 100644 index 000000000..e9dacec30 --- /dev/null +++ b/docshell/base/crashtests/369126-1.html @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/docshell/base/crashtests/403574-1.xhtml b/docshell/base/crashtests/403574-1.xhtml new file mode 100644 index 000000000..cdf7d43a4 --- /dev/null +++ b/docshell/base/crashtests/403574-1.xhtml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/docshell/base/crashtests/40929-1-inner.html b/docshell/base/crashtests/40929-1-inner.html new file mode 100644 index 000000000..313046a34 --- /dev/null +++ b/docshell/base/crashtests/40929-1-inner.html @@ -0,0 +1,14 @@ +Infinite Loop + + + + + diff --git a/docshell/base/crashtests/40929-1.html b/docshell/base/crashtests/40929-1.html new file mode 100644 index 000000000..90685d9f1 --- /dev/null +++ b/docshell/base/crashtests/40929-1.html @@ -0,0 +1,6 @@ + +Infinite Loop + + + + diff --git a/docshell/base/crashtests/430124-1.html b/docshell/base/crashtests/430124-1.html new file mode 100644 index 000000000..8cdbc1d07 --- /dev/null +++ b/docshell/base/crashtests/430124-1.html @@ -0,0 +1,5 @@ + + + +
+ diff --git a/docshell/base/crashtests/430628-1.html b/docshell/base/crashtests/430628-1.html new file mode 100644 index 000000000..4a68a5a01 --- /dev/null +++ b/docshell/base/crashtests/430628-1.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docshell/base/crashtests/432114-1.html b/docshell/base/crashtests/432114-1.html new file mode 100644 index 000000000..8878d6605 --- /dev/null +++ b/docshell/base/crashtests/432114-1.html @@ -0,0 +1,8 @@ + + +Bug - Crash [@ PL_DHashTableOperate] with DOMNodeInserted event listener removing window and frameset contenteditable + + + + + diff --git a/docshell/base/crashtests/432114-2.html b/docshell/base/crashtests/432114-2.html new file mode 100644 index 000000000..f8a101946 --- /dev/null +++ b/docshell/base/crashtests/432114-2.html @@ -0,0 +1,16 @@ + + +testcase2 Bug 432114 – Crash [@ PL_DHashTableOperate] with DOMNodeInserted event listener removing window and frameset contenteditable + + + + + + + diff --git a/docshell/base/crashtests/436900-1-inner.html b/docshell/base/crashtests/436900-1-inner.html new file mode 100644 index 000000000..6fe35ccb1 --- /dev/null +++ b/docshell/base/crashtests/436900-1-inner.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/docshell/base/crashtests/436900-1.html b/docshell/base/crashtests/436900-1.html new file mode 100644 index 000000000..582d1919d --- /dev/null +++ b/docshell/base/crashtests/436900-1.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docshell/base/crashtests/436900-2-inner.html b/docshell/base/crashtests/436900-2-inner.html new file mode 100644 index 000000000..ea79f75e8 --- /dev/null +++ b/docshell/base/crashtests/436900-2-inner.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/docshell/base/crashtests/436900-2.html b/docshell/base/crashtests/436900-2.html new file mode 100644 index 000000000..2e1f0c1de --- /dev/null +++ b/docshell/base/crashtests/436900-2.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docshell/base/crashtests/500328-1.html b/docshell/base/crashtests/500328-1.html new file mode 100644 index 000000000..fd97f84ae --- /dev/null +++ b/docshell/base/crashtests/500328-1.html @@ -0,0 +1,17 @@ + + + + + + diff --git a/docshell/base/crashtests/514779-1.xhtml b/docshell/base/crashtests/514779-1.xhtml new file mode 100644 index 000000000..16ac3d9d6 --- /dev/null +++ b/docshell/base/crashtests/514779-1.xhtml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/docshell/base/crashtests/678872-1.html b/docshell/base/crashtests/678872-1.html new file mode 100644 index 000000000..9853bbdae --- /dev/null +++ b/docshell/base/crashtests/678872-1.html @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + diff --git a/docshell/base/crashtests/914521.html b/docshell/base/crashtests/914521.html new file mode 100644 index 000000000..9ae18b860 --- /dev/null +++ b/docshell/base/crashtests/914521.html @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/docshell/base/crashtests/crashtests.list b/docshell/base/crashtests/crashtests.list new file mode 100644 index 000000000..bb3a709b9 --- /dev/null +++ b/docshell/base/crashtests/crashtests.list @@ -0,0 +1,16 @@ +load 40929-1.html +load 369126-1.html +load 403574-1.xhtml +load 430124-1.html +load 430628-1.html +load 432114-1.html +load 432114-2.html +load 436900-1.html +asserts(0-1) load 436900-2.html # bug 566159 +load 500328-1.html +load 514779-1.xhtml +load 614499-1.html +load 678872-1.html +skip-if(Android) pref(dom.disable_open_during_load,false) load 914521.html +pref(browser.send_pings,true) load 1257730-1.html +load 1341657.html diff --git a/docshell/base/moz.build b/docshell/base/moz.build new file mode 100644 index 000000000..1eb04c227 --- /dev/null +++ b/docshell/base/moz.build @@ -0,0 +1,88 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [ + 'timeline', +] + +XPIDL_SOURCES += [ + 'nsCDefaultURIFixup.idl', + 'nsIClipboardCommands.idl', + 'nsIContentViewer.idl', + 'nsIContentViewerContainer.idl', + 'nsIContentViewerEdit.idl', + 'nsIContentViewerFile.idl', + 'nsIDocCharset.idl', + 'nsIDocShell.idl', + 'nsIDocShellLoadInfo.idl', + 'nsIDocShellTreeItem.idl', + 'nsIDocShellTreeOwner.idl', + 'nsIDocumentLoaderFactory.idl', + 'nsIDownloadHistory.idl', + 'nsIGlobalHistory2.idl', + 'nsILoadContext.idl', + 'nsIPrivacyTransitionObserver.idl', + 'nsIReflowObserver.idl', + 'nsIRefreshURI.idl', + 'nsIScrollable.idl', + 'nsITextScroll.idl', + 'nsIURIFixup.idl', + 'nsIWebNavigation.idl', + 'nsIWebNavigationInfo.idl', + 'nsIWebPageDescriptor.idl', +] + +XPIDL_MODULE = 'docshell' + +EXPORTS += [ + 'nsDocShellLoadTypes.h', + 'nsILinkHandler.h', + 'nsIScrollObserver.h', + 'nsIWebShellServices.h', + 'SerializedLoadContext.h', +] + +EXPORTS.mozilla += [ + 'IHistory.h', + 'LoadContext.h', +] + +UNIFIED_SOURCES += [ + 'LoadContext.cpp', + 'nsAboutRedirector.cpp', + 'nsDefaultURIFixup.cpp', + 'nsDocShell.cpp', + 'nsDocShellEditorData.cpp', + 'nsDocShellEnumerator.cpp', + 'nsDocShellLoadInfo.cpp', + 'nsDocShellTransferableHooks.cpp', + 'nsDownloadHistory.cpp', + 'nsDSURIContentListener.cpp', + 'nsWebNavigationInfo.cpp', + 'SerializedLoadContext.cpp', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '/docshell/shistory', + '/dom/base', + '/layout/base', + '/layout/generic', + '/layout/xul', + '/netwerk/protocol/viewsource', + '/tools/profiler', +] + +if CONFIG['MOZ_TOOLKIT_SEARCH']: + DEFINES['MOZ_TOOLKIT_SEARCH'] = True + +if CONFIG['MOZ_DEVTOOLS'] == 'all': + DEFINES['MOZ_DEVTOOLS_ALL'] = True + +if CONFIG['GNU_CXX']: + CXXFLAGS += ['-Wno-error=shadow'] diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp new file mode 100644 index 000000000..f300e0ce2 --- /dev/null +++ b/docshell/base/nsAboutRedirector.cpp @@ -0,0 +1,224 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsAboutRedirector.h" +#include "nsNetUtil.h" +#include "nsAboutProtocolUtils.h" +#include "mozilla/ArrayUtils.h" +#include "nsIProtocolHandler.h" + +NS_IMPL_ISUPPORTS(nsAboutRedirector, nsIAboutModule) + +struct RedirEntry +{ + const char* id; + const char* url; + uint32_t flags; +}; + +/* + Entries which do not have URI_SAFE_FOR_UNTRUSTED_CONTENT will run with chrome + privileges. This is potentially dangerous. Please use + URI_SAFE_FOR_UNTRUSTED_CONTENT in the third argument to each map item below + unless your about: page really needs chrome privileges. Security review is + required before adding new map entries without + URI_SAFE_FOR_UNTRUSTED_CONTENT. Also note, however, that adding + URI_SAFE_FOR_UNTRUSTED_CONTENT will allow random web sites to link to that + URI. Perhaps we should separate the two concepts out... + */ +static RedirEntry kRedirMap[] = { + { + "", "chrome://global/content/about.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { "about", "chrome://global/content/aboutAbout.xhtml", 0 }, + { + "addons", "chrome://mozapps/content/extensions/extensions.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "buildconfig", "chrome://global/content/buildconfig.html", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, + { + "checkerboard", "chrome://global/content/aboutCheckerboard.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::ALLOW_SCRIPT + }, + { "config", "chrome://global/content/config.xul", 0 }, +#ifdef MOZ_CRASHREPORTER + { "crashes", "chrome://global/content/crashes.xhtml", 0 }, +#endif + { + "credits", "https://www.mozilla.org/credits/", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, +#ifdef MOZ_DEVTOOLS_ALL + { + "debugging", "chrome://devtools/content/aboutdebugging/aboutdebugging.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, +#endif + { + "license", "chrome://global/content/license.html", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::MAKE_LINKABLE + }, + { + "logo", "chrome://branding/content/about.png", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + // Linkable for testing reasons. + nsIAboutModule::MAKE_LINKABLE + }, + { + "memory", "chrome://global/content/aboutMemory.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "mozilla", "chrome://global/content/mozilla.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, + { + "neterror", "chrome://global/content/netError.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::URI_CAN_LOAD_IN_CHILD | + nsIAboutModule::ALLOW_SCRIPT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "networking", "chrome://global/content/aboutNetworking.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "newaddon", "chrome://mozapps/content/extensions/newaddon.xul", + nsIAboutModule::ALLOW_SCRIPT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "performance", "chrome://global/content/aboutPerformance.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "plugins", "chrome://global/content/plugins.html", + nsIAboutModule::URI_MUST_LOAD_IN_CHILD + }, + { + "serviceworkers", "chrome://global/content/aboutServiceWorkers.xhtml", + nsIAboutModule::URI_CAN_LOAD_IN_CHILD | + nsIAboutModule::URI_MUST_LOAD_IN_CHILD | + nsIAboutModule::ALLOW_SCRIPT + }, +#ifndef ANDROID + { + "profiles", "chrome://global/content/aboutProfiles.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, +#endif + // about:srcdoc is unresolvable by specification. It is included here + // because the security manager would disallow srcdoc iframes otherwise. + { + "srcdoc", "about:blank", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT | + // Needs to be linkable so content can touch its own srcdoc frames + nsIAboutModule::MAKE_LINKABLE | + nsIAboutModule::URI_CAN_LOAD_IN_CHILD + }, + { + "support", "chrome://global/content/aboutSupport.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "telemetry", "chrome://global/content/aboutTelemetry.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.html", + nsIAboutModule::ALLOW_SCRIPT + } +}; +static const int kRedirTotal = mozilla::ArrayLength(kRedirMap); + +NS_IMETHODIMP +nsAboutRedirector::NewChannel(nsIURI* aURI, + nsILoadInfo* aLoadInfo, + nsIChannel** aResult) +{ + NS_ENSURE_ARG_POINTER(aURI); + NS_ASSERTION(aResult, "must not be null"); + + nsAutoCString path; + nsresult rv = NS_GetAboutModuleName(aURI, path); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr ioService = do_GetIOService(&rv); + NS_ENSURE_SUCCESS(rv, rv); + + for (int i = 0; i < kRedirTotal; i++) { + if (!strcmp(path.get(), kRedirMap[i].id)) { + nsCOMPtr tempChannel; + nsCOMPtr tempURI; + rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url); + NS_ENSURE_SUCCESS(rv, rv); + + // If tempURI links to an external URI (i.e. something other than + // chrome:// or resource://) then set the LOAD_REPLACE flag on the + // channel which forces the channel owner to reflect the displayed + // URL rather then being the systemPrincipal. + bool isUIResource = false; + rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE, + &isUIResource); + NS_ENSURE_SUCCESS(rv, rv); + + nsLoadFlags loadFlags = + isUIResource ? static_cast(nsIChannel::LOAD_NORMAL) + : static_cast(nsIChannel::LOAD_REPLACE); + + rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), + tempURI, + aLoadInfo, + nullptr, // aLoadGroup + nullptr, // aCallbacks + loadFlags); + NS_ENSURE_SUCCESS(rv, rv); + + tempChannel->SetOriginalURI(aURI); + + tempChannel.forget(aResult); + return rv; + } + } + + NS_ERROR("nsAboutRedirector called for unknown case"); + return NS_ERROR_ILLEGAL_VALUE; +} + +NS_IMETHODIMP +nsAboutRedirector::GetURIFlags(nsIURI* aURI, uint32_t* aResult) +{ + NS_ENSURE_ARG_POINTER(aURI); + + nsAutoCString name; + nsresult rv = NS_GetAboutModuleName(aURI, name); + NS_ENSURE_SUCCESS(rv, rv); + + for (int i = 0; i < kRedirTotal; i++) { + if (name.EqualsASCII(kRedirMap[i].id)) { + *aResult = kRedirMap[i].flags; + return NS_OK; + } + } + + NS_ERROR("nsAboutRedirector called for unknown case"); + return NS_ERROR_ILLEGAL_VALUE; +} + +nsresult +nsAboutRedirector::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) +{ + RefPtr about = new nsAboutRedirector(); + return about->QueryInterface(aIID, aResult); +} diff --git a/docshell/base/nsAboutRedirector.h b/docshell/base/nsAboutRedirector.h new file mode 100644 index 000000000..f8e6b2558 --- /dev/null +++ b/docshell/base/nsAboutRedirector.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsAboutRedirector_h__ +#define nsAboutRedirector_h__ + +#include "nsIAboutModule.h" + +class nsAboutRedirector : public nsIAboutModule +{ +public: + NS_DECL_ISUPPORTS + + NS_DECL_NSIABOUTMODULE + + nsAboutRedirector() {} + + static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); + +protected: + virtual ~nsAboutRedirector() {} +}; + +/* 56ebedd4-6ccf-48e8-bdae-adc77f044567 */ +#define NS_ABOUT_REDIRECTOR_MODULE_CID \ +{ 0x56ebedd4, 0x6ccf, 0x48e8, \ + { 0xbd, 0xae, 0xad, 0xc7, 0x7f, 0x04, 0x45, 0x67 } } + +#endif // nsAboutRedirector_h__ diff --git a/docshell/base/nsCDefaultURIFixup.idl b/docshell/base/nsCDefaultURIFixup.idl new file mode 100644 index 000000000..60fffdf21 --- /dev/null +++ b/docshell/base/nsCDefaultURIFixup.idl @@ -0,0 +1,13 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +%{ C++ +// {214C48A0-B57F-11d4-959C-0020183BF181} +#define NS_DEFAULTURIFIXUP_CID \ +{ 0x214c48a0, 0xb57f, 0x11d4, { 0x95, 0x9c, 0x0, 0x20, 0x18, 0x3b, 0xf1, 0x81 } } +#define NS_URIFIXUP_CONTRACTID \ +"@mozilla.org/docshell/urifixup;1" +%} diff --git a/docshell/base/nsDSURIContentListener.cpp b/docshell/base/nsDSURIContentListener.cpp new file mode 100644 index 000000000..cfac54f7f --- /dev/null +++ b/docshell/base/nsDSURIContentListener.cpp @@ -0,0 +1,539 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsDocShell.h" +#include "nsDSURIContentListener.h" +#include "nsIChannel.h" +#include "nsServiceManagerUtils.h" +#include "nsDocShellCID.h" +#include "nsIWebNavigationInfo.h" +#include "nsIDocument.h" +#include "nsIDOMWindow.h" +#include "nsNetUtil.h" +#include "nsQueryObject.h" +#include "nsIHttpChannel.h" +#include "nsIScriptSecurityManager.h" +#include "nsError.h" +#include "nsCharSeparatedTokenizer.h" +#include "nsIConsoleService.h" +#include "nsIScriptError.h" +#include "nsDocShellLoadTypes.h" +#include "nsIMultiPartChannel.h" + +using namespace mozilla; + +nsDSURIContentListener::nsDSURIContentListener(nsDocShell* aDocShell) + : mDocShell(aDocShell) + , mExistingJPEGRequest(nullptr) + , mParentContentListener(nullptr) +{ +} + +nsDSURIContentListener::~nsDSURIContentListener() +{ +} + +nsresult +nsDSURIContentListener::Init() +{ + nsresult rv; + mNavInfo = do_GetService(NS_WEBNAVIGATION_INFO_CONTRACTID, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get webnav info"); + return rv; +} + +NS_IMPL_ADDREF(nsDSURIContentListener) +NS_IMPL_RELEASE(nsDSURIContentListener) + +NS_INTERFACE_MAP_BEGIN(nsDSURIContentListener) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener) + NS_INTERFACE_MAP_ENTRY(nsIURIContentListener) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) +NS_INTERFACE_MAP_END + +NS_IMETHODIMP +nsDSURIContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen) +{ + // If mDocShell is null here, that means someone's starting a load in our + // docshell after it's already been destroyed. Don't let that happen. + if (!mDocShell) { + *aAbortOpen = true; + return NS_OK; + } + + nsCOMPtr parentListener; + GetParentContentListener(getter_AddRefs(parentListener)); + if (parentListener) { + return parentListener->OnStartURIOpen(aURI, aAbortOpen); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDSURIContentListener::DoContent(const nsACString& aContentType, + bool aIsContentPreferred, + nsIRequest* aRequest, + nsIStreamListener** aContentHandler, + bool* aAbortProcess) +{ + nsresult rv; + NS_ENSURE_ARG_POINTER(aContentHandler); + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + + // Check whether X-Frame-Options permits us to load this content in an + // iframe and abort the load (unless we've disabled x-frame-options + // checking). + if (!CheckFrameOptions(aRequest)) { + *aAbortProcess = true; + return NS_OK; + } + + *aAbortProcess = false; + + // determine if the channel has just been retargeted to us... + nsLoadFlags loadFlags = 0; + nsCOMPtr aOpenedChannel = do_QueryInterface(aRequest); + + if (aOpenedChannel) { + aOpenedChannel->GetLoadFlags(&loadFlags); + } + + if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { + // XXX: Why does this not stop the content too? + mDocShell->Stop(nsIWebNavigation::STOP_NETWORK); + + mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL); + } + + // In case of multipart jpeg request (mjpeg) we don't really want to + // create new viewer since the one we already have is capable of + // rendering multipart jpeg correctly (see bug 625012) + nsCOMPtr baseChannel; + if (nsCOMPtr mpchan = do_QueryInterface(aRequest)) { + mpchan->GetBaseChannel(getter_AddRefs(baseChannel)); + } + + bool reuseCV = baseChannel && baseChannel == mExistingJPEGRequest && + aContentType.EqualsLiteral("image/jpeg"); + + if (mExistingJPEGStreamListener && reuseCV) { + RefPtr copy(mExistingJPEGStreamListener); + copy.forget(aContentHandler); + rv = NS_OK; + } else { + rv = mDocShell->CreateContentViewer(aContentType, aRequest, aContentHandler); + if (NS_SUCCEEDED(rv) && reuseCV) { + mExistingJPEGStreamListener = *aContentHandler; + } else { + mExistingJPEGStreamListener = nullptr; + } + mExistingJPEGRequest = baseChannel; + } + + if (rv == NS_ERROR_REMOTE_XUL) { + aRequest->Cancel(rv); + *aAbortProcess = true; + return NS_OK; + } + + if (NS_FAILED(rv)) { + // we don't know how to handle the content + *aContentHandler = nullptr; + return rv; + } + + if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { + nsCOMPtr domWindow = + mDocShell ? mDocShell->GetWindow() : nullptr; + NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); + domWindow->Focus(); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDSURIContentListener::IsPreferred(const char* aContentType, + char** aDesiredContentType, + bool* aCanHandle) +{ + NS_ENSURE_ARG_POINTER(aCanHandle); + NS_ENSURE_ARG_POINTER(aDesiredContentType); + + // the docshell has no idea if it is the preferred content provider or not. + // It needs to ask its parent if it is the preferred content handler or not... + + nsCOMPtr parentListener; + GetParentContentListener(getter_AddRefs(parentListener)); + if (parentListener) { + return parentListener->IsPreferred(aContentType, + aDesiredContentType, + aCanHandle); + } + // we used to return false here if we didn't have a parent properly registered + // at the top of the docshell hierarchy to dictate what content types this + // docshell should be a preferred handler for. But this really makes it hard + // for developers using iframe or browser tags because then they need to make + // sure they implement nsIURIContentListener otherwise all link clicks would + // get sent to another window because we said we weren't the preferred handler + // type. I'm going to change the default now... if we can handle the content, + // and someone didn't EXPLICITLY set a nsIURIContentListener at the top of our + // docshell chain, then we'll now always attempt to process the content + // ourselves... + return CanHandleContent(aContentType, true, aDesiredContentType, aCanHandle); +} + +NS_IMETHODIMP +nsDSURIContentListener::CanHandleContent(const char* aContentType, + bool aIsContentPreferred, + char** aDesiredContentType, + bool* aCanHandleContent) +{ + NS_PRECONDITION(aCanHandleContent, "Null out param?"); + NS_ENSURE_ARG_POINTER(aDesiredContentType); + + *aCanHandleContent = false; + *aDesiredContentType = nullptr; + + nsresult rv = NS_OK; + if (aContentType) { + uint32_t canHandle = nsIWebNavigationInfo::UNSUPPORTED; + rv = mNavInfo->IsTypeSupported(nsDependentCString(aContentType), + mDocShell, + &canHandle); + *aCanHandleContent = (canHandle != nsIWebNavigationInfo::UNSUPPORTED); + } + + return rv; +} + +NS_IMETHODIMP +nsDSURIContentListener::GetLoadCookie(nsISupports** aLoadCookie) +{ + NS_IF_ADDREF(*aLoadCookie = nsDocShell::GetAsSupports(mDocShell)); + return NS_OK; +} + +NS_IMETHODIMP +nsDSURIContentListener::SetLoadCookie(nsISupports* aLoadCookie) +{ +#ifdef DEBUG + RefPtr cookieAsDocLoader = + nsDocLoader::GetAsDocLoader(aLoadCookie); + NS_ASSERTION(cookieAsDocLoader && cookieAsDocLoader == mDocShell, + "Invalid load cookie being set!"); +#endif + return NS_OK; +} + +NS_IMETHODIMP +nsDSURIContentListener::GetParentContentListener( + nsIURIContentListener** aParentListener) +{ + if (mWeakParentContentListener) { + nsCOMPtr tempListener = + do_QueryReferent(mWeakParentContentListener); + *aParentListener = tempListener; + NS_IF_ADDREF(*aParentListener); + } else { + *aParentListener = mParentContentListener; + NS_IF_ADDREF(*aParentListener); + } + return NS_OK; +} + +NS_IMETHODIMP +nsDSURIContentListener::SetParentContentListener( + nsIURIContentListener* aParentListener) +{ + if (aParentListener) { + // Store the parent listener as a weak ref. Parents not supporting + // nsISupportsWeakReference assert but may still be used. + mParentContentListener = nullptr; + mWeakParentContentListener = do_GetWeakReference(aParentListener); + if (!mWeakParentContentListener) { + mParentContentListener = aParentListener; + } + } else { + mWeakParentContentListener = nullptr; + mParentContentListener = nullptr; + } + return NS_OK; +} + +bool +nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, + const nsAString& aPolicy) +{ + static const char allowFrom[] = "allow-from"; + const uint32_t allowFromLen = ArrayLength(allowFrom) - 1; + bool isAllowFrom = + StringHead(aPolicy, allowFromLen).LowerCaseEqualsLiteral(allowFrom); + + // return early if header does not have one of the values with meaning + if (!aPolicy.LowerCaseEqualsLiteral("deny") && + !aPolicy.LowerCaseEqualsLiteral("sameorigin") && + !isAllowFrom) { + return true; + } + + nsCOMPtr uri; + aHttpChannel->GetURI(getter_AddRefs(uri)); + + // XXXkhuey when does this happen? Is returning true safe here? + if (!mDocShell) { + return true; + } + + // We need to check the location of this window and the location of the top + // window, if we're not the top. X-F-O: SAMEORIGIN requires that the + // document must be same-origin with top window. X-F-O: DENY requires that + // the document must never be framed. + nsCOMPtr thisWindow = mDocShell->GetWindow(); + // If we don't have DOMWindow there is no risk of clickjacking + if (!thisWindow) { + return true; + } + + // GetScriptableTop, not GetTop, because we want this to respect + //