Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp
Warning:line 3424, column 9
Value stored to 'error' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_docshell_base0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/docshell/base -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/docshell/base -resource-dir /usr/lib/llvm-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/docshell/base -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/docshell/base -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/docshell/shistory -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/bindings -I /var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src -I /var/lib/jenkins/workspace/firefox-scan-build/layout/base -I /var/lib/jenkins/workspace/firefox-scan-build/layout/generic -I /var/lib/jenkins/workspace/firefox-scan-build/layout/style -I /var/lib/jenkins/workspace/firefox-scan-build/layout/xul -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/viewsource -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/browser -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/find -I /var/lib/jenkins/workspace/firefox-scan-build/tools/profiler -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-16-034744-15991-1 -x c++ Unified_cpp_docshell_base0.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "nsDocShell.h"
8
9#include <algorithm>
10
11#ifdef XP_WIN
12# include <process.h>
13# define getpid _getpid
14#else
15# include <unistd.h> // for getpid()
16#endif
17
18#include "mozilla/ArrayUtils.h"
19#include "mozilla/Attributes.h"
20#include "mozilla/AutoRestore.h"
21#include "mozilla/BasePrincipal.h"
22#include "mozilla/Casting.h"
23#include "mozilla/CheckedInt.h"
24#include "mozilla/Components.h"
25#include "mozilla/DebugOnly.h"
26#include "mozilla/Encoding.h"
27#include "mozilla/EventStateManager.h"
28#include "mozilla/HTMLEditor.h"
29#include "mozilla/InputTaskManager.h"
30#include "mozilla/LoadInfo.h"
31#include "mozilla/Logging.h"
32#include "mozilla/MediaFeatureChange.h"
33#include "mozilla/Preferences.h"
34#include "mozilla/PresShell.h"
35#include "mozilla/ResultExtensions.h"
36#include "mozilla/SchedulerGroup.h"
37#include "mozilla/ScopeExit.h"
38#include "mozilla/ScrollTypes.h"
39#include "mozilla/SimpleEnumerator.h"
40#include "mozilla/StaticPrefs_browser.h"
41#include "mozilla/StaticPrefs_docshell.h"
42#include "mozilla/StaticPrefs_dom.h"
43#include "mozilla/StaticPrefs_extensions.h"
44#include "mozilla/StaticPrefs_privacy.h"
45#include "mozilla/StaticPrefs_security.h"
46#include "mozilla/StaticPrefs_ui.h"
47#include "mozilla/StaticPrefs_fission.h"
48#include "mozilla/StartupTimeline.h"
49#include "mozilla/StorageAccess.h"
50#include "mozilla/StoragePrincipalHelper.h"
51#include "mozilla/Telemetry.h"
52
53#include "mozilla/Unused.h"
54#include "mozilla/WidgetUtils.h"
55
56#include "mozilla/dom/AutoEntryScript.h"
57#include "mozilla/dom/ChildProcessChannelListener.h"
58#include "mozilla/dom/ClientChannelHelper.h"
59#include "mozilla/dom/ClientHandle.h"
60#include "mozilla/dom/ClientInfo.h"
61#include "mozilla/dom/ClientManager.h"
62#include "mozilla/dom/ClientSource.h"
63#include "mozilla/dom/ContentChild.h"
64#include "mozilla/dom/ContentFrameMessageManager.h"
65#include "mozilla/dom/DocGroup.h"
66#include "mozilla/dom/Element.h"
67#include "mozilla/dom/HTMLAnchorElement.h"
68#include "mozilla/dom/HTMLIFrameElement.h"
69#include "mozilla/dom/PerformanceNavigation.h"
70#include "mozilla/dom/PermissionMessageUtils.h"
71#include "mozilla/dom/PopupBlocker.h"
72#include "mozilla/dom/ScreenOrientation.h"
73#include "mozilla/dom/ScriptSettings.h"
74#include "mozilla/dom/ServiceWorkerInterceptController.h"
75#include "mozilla/dom/ServiceWorkerUtils.h"
76#include "mozilla/dom/SessionHistoryEntry.h"
77#include "mozilla/dom/SessionStorageManager.h"
78#include "mozilla/dom/SessionStoreChangeListener.h"
79#include "mozilla/dom/SessionStoreChild.h"
80#include "mozilla/dom/SessionStoreUtils.h"
81#include "mozilla/dom/BrowserChild.h"
82#include "mozilla/dom/ToJSValue.h"
83#include "mozilla/dom/UserActivation.h"
84#include "mozilla/dom/ChildSHistory.h"
85#include "mozilla/dom/nsCSPContext.h"
86#include "mozilla/dom/nsHTTPSOnlyUtils.h"
87#include "mozilla/dom/LoadURIOptionsBinding.h"
88#include "mozilla/dom/JSWindowActorChild.h"
89#include "mozilla/dom/DocumentBinding.h"
90#include "mozilla/ipc/ProtocolUtils.h"
91#include "mozilla/net/DocumentChannel.h"
92#include "mozilla/net/DocumentChannelChild.h"
93#include "mozilla/net/ParentChannelWrapper.h"
94#include "mozilla/net/UrlClassifierFeatureFactory.h"
95#include "ReferrerInfo.h"
96
97#include "nsIAuthPrompt.h"
98#include "nsIAuthPrompt2.h"
99#include "nsICachingChannel.h"
100#include "nsICaptivePortalService.h"
101#include "nsIChannel.h"
102#include "nsIChannelEventSink.h"
103#include "nsIClassOfService.h"
104#include "nsIConsoleReportCollector.h"
105#include "nsIContent.h"
106#include "nsIContentInlines.h"
107#include "nsIContentSecurityPolicy.h"
108#include "nsIController.h"
109#include "nsIDocShellTreeItem.h"
110#include "nsIDocShellTreeOwner.h"
111#include "nsIDocumentViewer.h"
112#include "mozilla/dom/Document.h"
113#include "nsHTMLDocument.h"
114#include "nsIDocumentLoaderFactory.h"
115#include "nsIDOMWindow.h"
116#include "nsIEditingSession.h"
117#include "nsIEffectiveTLDService.h"
118#include "nsIExternalProtocolService.h"
119#include "nsIFormPOSTActionChannel.h"
120#include "nsIFrame.h"
121#include "nsIGlobalObject.h"
122#include "nsIHttpChannel.h"
123#include "nsIHttpChannelInternal.h"
124#include "nsIIDNService.h"
125#include "nsIInputStreamChannel.h"
126#include "nsIInterfaceRequestorUtils.h"
127#include "nsILayoutHistoryState.h"
128#include "nsILoadInfo.h"
129#include "nsILoadURIDelegate.h"
130#include "nsIMultiPartChannel.h"
131#include "nsINestedURI.h"
132#include "nsINetworkPredictor.h"
133#include "nsINode.h"
134#include "nsINSSErrorsService.h"
135#include "nsIObserverService.h"
136#include "nsIOService.h"
137#include "nsIPrincipal.h"
138#include "nsIPrivacyTransitionObserver.h"
139#include "nsIPrompt.h"
140#include "nsIPromptCollection.h"
141#include "nsIPromptFactory.h"
142#include "nsIPublicKeyPinningService.h"
143#include "nsIReflowObserver.h"
144#include "nsIScriptChannel.h"
145#include "nsIScriptObjectPrincipal.h"
146#include "nsIScriptSecurityManager.h"
147#include "nsScriptSecurityManager.h"
148#include "nsIScrollableFrame.h"
149#include "nsIScrollObserver.h"
150#include "nsISupportsPrimitives.h"
151#include "nsISecureBrowserUI.h"
152#include "nsISeekableStream.h"
153#include "nsISelectionDisplay.h"
154#include "nsISHEntry.h"
155#include "nsISiteSecurityService.h"
156#include "nsISocketProvider.h"
157#include "nsIStringBundle.h"
158#include "nsIStructuredCloneContainer.h"
159#include "nsIBrowserChild.h"
160#include "nsITextToSubURI.h"
161#include "nsITimedChannel.h"
162#include "nsITimer.h"
163#include "nsITransportSecurityInfo.h"
164#include "nsIUploadChannel.h"
165#include "nsIURIFixup.h"
166#include "nsIURIMutator.h"
167#include "nsIURILoader.h"
168#include "nsIViewSourceChannel.h"
169#include "nsIWebBrowserChrome.h"
170#include "nsIWebBrowserFind.h"
171#include "nsIWebProgress.h"
172#include "nsIWidget.h"
173#include "nsIWindowWatcher.h"
174#include "nsIWritablePropertyBag2.h"
175#include "nsIX509Cert.h"
176#include "nsIXULRuntime.h"
177
178#include "nsCommandManager.h"
179#include "nsPIDOMWindow.h"
180#include "nsPIWindowRoot.h"
181
182#include "IHistory.h"
183#include "IUrlClassifierUITelemetry.h"
184
185#include "nsArray.h"
186#include "nsArrayUtils.h"
187#include "nsCExternalHandlerService.h"
188#include "nsContentDLF.h"
189#include "nsContentPolicyUtils.h" // NS_CheckContentLoadPolicy(...)
190#include "nsContentSecurityManager.h"
191#include "nsContentSecurityUtils.h"
192#include "nsContentUtils.h"
193#include "nsCURILoader.h"
194#include "nsDocShellCID.h"
195#include "nsDocShellEditorData.h"
196#include "nsDocShellEnumerator.h"
197#include "nsDocShellLoadState.h"
198#include "nsDocShellLoadTypes.h"
199#include "nsDOMCID.h"
200#include "nsDOMNavigationTiming.h"
201#include "nsDSURIContentListener.h"
202#include "nsEditingSession.h"
203#include "nsError.h"
204#include "nsEscape.h"
205#include "nsFocusManager.h"
206#include "nsGlobalWindowInner.h"
207#include "nsGlobalWindowOuter.h"
208#include "nsJSEnvironment.h"
209#include "nsNetCID.h"
210#include "nsNetUtil.h"
211#include "nsObjectLoadingContent.h"
212#include "nsPingListener.h"
213#include "nsPoint.h"
214#include "nsQueryObject.h"
215#include "nsQueryActor.h"
216#include "nsRect.h"
217#include "nsRefreshTimer.h"
218#include "nsSandboxFlags.h"
219#include "nsSHEntry.h"
220#include "nsSHistory.h"
221#include "nsSHEntry.h"
222#include "nsStructuredCloneContainer.h"
223#include "nsSubDocumentFrame.h"
224#include "nsURILoader.h"
225#include "nsURLHelper.h"
226#include "nsView.h"
227#include "nsViewManager.h"
228#include "nsViewSourceHandler.h"
229#include "nsWebBrowserFind.h"
230#include "nsWhitespaceTokenizer.h"
231#include "nsWidgetsCID.h"
232#include "nsXULAppAPI.h"
233
234#include "ThirdPartyUtil.h"
235#include "GeckoProfiler.h"
236#include "mozilla/NullPrincipal.h"
237#include "Navigator.h"
238#include "prenv.h"
239#include "mozilla/ipc/URIUtils.h"
240#include "sslerr.h"
241#include "mozpkix/pkix.h"
242#include "NSSErrorsService.h"
243
244#include "nsDocShellTelemetryUtils.h"
245
246#ifdef MOZ_PLACES1
247# include "nsIFaviconService.h"
248# include "mozIPlacesPendingOperation.h"
249#endif
250
251#if NS_PRINT_PREVIEW1
252# include "nsIDocumentViewerPrint.h"
253# include "nsIWebBrowserPrint.h"
254#endif
255
256using namespace mozilla;
257using namespace mozilla::dom;
258using namespace mozilla::net;
259
260using mozilla::ipc::Endpoint;
261
262// Threshold value in ms for META refresh based redirects
263#define REFRESH_REDIRECT_TIMER15000 15000
264
265static mozilla::LazyLogModule gCharsetMenuLog("CharsetMenu");
266
267#define LOGCHARSETMENU(args)do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS
args); } } while (0)
\
268 MOZ_LOG(gCharsetMenuLog, mozilla::LogLevel::Debug, args)do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS
args); } } while (0)
269
270#ifdef DEBUG1
271unsigned long nsDocShell::gNumberOfDocShells = 0;
272static uint64_t gDocshellIDCounter = 0;
273
274static mozilla::LazyLogModule gDocShellLog("nsDocShell");
275static mozilla::LazyLogModule gDocShellAndDOMWindowLeakLogging(
276 "DocShellAndDOMWindowLeak");
277#endif
278static mozilla::LazyLogModule gDocShellLeakLog("nsDocShellLeak");
279extern mozilla::LazyLogModule gPageCacheLog;
280mozilla::LazyLogModule gSHLog("SessionHistory");
281extern mozilla::LazyLogModule gSHIPBFCacheLog;
282
283const char kAppstringsBundleURL[] =
284 "chrome://global/locale/appstrings.properties";
285
286static bool IsTopLevelDoc(BrowsingContext* aBrowsingContext,
287 nsILoadInfo* aLoadInfo) {
288 MOZ_ASSERT(aBrowsingContext)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aBrowsingContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aBrowsingContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aBrowsingContext"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 288); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBrowsingContext"
")"); do { *((volatile int*)__null) = 288; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
289 MOZ_ASSERT(aLoadInfo)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadInfo))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aLoadInfo", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 289); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadInfo" ")"
); do { *((volatile int*)__null) = 289; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
290
291 if (aLoadInfo->GetExternalContentPolicyType() !=
292 ExtContentPolicy::TYPE_DOCUMENT) {
293 return false;
294 }
295
296 return aBrowsingContext->IsTopContent();
297}
298
299// True if loading for top level document loading in active tab.
300static bool IsUrgentStart(BrowsingContext* aBrowsingContext,
301 nsILoadInfo* aLoadInfo, uint32_t aLoadType) {
302 MOZ_ASSERT(aBrowsingContext)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aBrowsingContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aBrowsingContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aBrowsingContext"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 302); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBrowsingContext"
")"); do { *((volatile int*)__null) = 302; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
303 MOZ_ASSERT(aLoadInfo)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadInfo))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aLoadInfo", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 303); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadInfo" ")"
); do { *((volatile int*)__null) = 303; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
304
305 if (!IsTopLevelDoc(aBrowsingContext, aLoadInfo)) {
306 return false;
307 }
308
309 if (aLoadType &
310 (nsIDocShell::LOAD_CMD_NORMAL | nsIDocShell::LOAD_CMD_HISTORY)) {
311 return true;
312 }
313
314 return aBrowsingContext->IsActive();
315}
316
317nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
318 uint64_t aContentWindowID)
319 : nsDocLoader(true),
320 mContentWindowID(aContentWindowID),
321 mBrowsingContext(aBrowsingContext),
322 mParentCharset(nullptr),
323 mTreeOwner(nullptr),
324 mScrollbarPref(ScrollbarPreference::Auto),
325 mCharsetReloadState(eCharsetReloadInit),
326 mParentCharsetSource(0),
327 mFrameMargins(-1, -1),
328 mItemType(aBrowsingContext->IsContent() ? typeContent : typeChrome),
329 mPreviousEntryIndex(-1),
330 mLoadedEntryIndex(-1),
331 mBusyFlags(BUSY_FLAGS_NONE),
332 mAppType(nsIDocShell::APP_TYPE_UNKNOWN),
333 mLoadType(0),
334 mFailedLoadType(0),
335 mChannelToDisconnectOnPageHide(0),
336 mCreatingDocument(false),
337#ifdef DEBUG1
338 mInEnsureScriptEnv(false),
339#endif
340 mInitialized(false),
341 mAllowSubframes(true),
342 mAllowMetaRedirects(true),
343 mAllowImages(true),
344 mAllowMedia(true),
345 mAllowDNSPrefetch(true),
346 mAllowWindowControl(true),
347 mCSSErrorReportingEnabled(false),
348 mAllowAuth(mItemType == typeContent),
349 mAllowKeywordFixup(false),
350 mDisableMetaRefreshWhenInactive(false),
351 mWindowDraggingAllowed(false),
352 mInFrameSwap(false),
353 mFiredUnloadEvent(false),
354 mEODForCurrentDocument(false),
355 mURIResultedInDocument(false),
356 mIsBeingDestroyed(false),
357 mIsExecutingOnLoadHandler(false),
358 mSavingOldViewer(false),
359 mInvisible(false),
360 mHasLoadedNonBlankURI(false),
361 mBlankTiming(false),
362 mTitleValidForCurrentURI(false),
363 mWillChangeProcess(false),
364 mIsNavigating(false),
365 mForcedAutodetection(false),
366 mCheckingSessionHistory(false),
367 mNeedToReportActiveAfterLoadingBecomesActive(false) {
368 // If no outer window ID was provided, generate a new one.
369 if (aContentWindowID == 0) {
370 mContentWindowID = nsContentUtils::GenerateWindowId();
371 }
372
373 MOZ_LOG(gDocShellLeakLog, LogLevel::Debug, ("DOCSHELL %p created\n", this))do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p created\n", this); } } while (
0)
;
374
375#ifdef DEBUG1
376 mDocShellID = gDocshellIDCounter++;
377 // We're counting the number of |nsDocShells| to help find leaks
378 ++gNumberOfDocShells;
379 MOZ_LOG(gDocShellAndDOMWindowLeakLogging, LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOCSHELL %p == %ld [pid = %d] [id = %" "l"
"u" "]\n", (void*)this, gNumberOfDocShells, getpid(), mDocShellID
); } } while (0)
380 ("++DOCSHELL %p == %ld [pid = %d] [id = %" PRIu64 "]\n", (void*)this,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOCSHELL %p == %ld [pid = %d] [id = %" "l"
"u" "]\n", (void*)this, gNumberOfDocShells, getpid(), mDocShellID
); } } while (0)
381 gNumberOfDocShells, getpid(), mDocShellID))do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "++DOCSHELL %p == %ld [pid = %d] [id = %" "l"
"u" "]\n", (void*)this, gNumberOfDocShells, getpid(), mDocShellID
); } } while (0)
;
382#endif
383}
384
385nsDocShell::~nsDocShell() {
386 // Avoid notifying observers while we're in the dtor.
387 mIsBeingDestroyed = true;
388
389 Destroy();
390
391 if (mDocumentViewer) {
392 mDocumentViewer->Close(nullptr);
393 mDocumentViewer->Destroy();
394 mDocumentViewer = nullptr;
395 }
396
397 MOZ_LOG(gDocShellLeakLog, LogLevel::Debug, ("DOCSHELL %p destroyed\n", this))do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p destroyed\n", this); } } while
(0)
;
398
399#ifdef DEBUG1
400 if (MOZ_LOG_TEST(gDocShellAndDOMWindowLeakLogging, LogLevel::Info)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellAndDOMWindowLeakLogging
, LogLevel::Info)), 0))
) {
401 nsAutoCString url;
402 if (mLastOpenedURI) {
403 url = mLastOpenedURI->GetSpecOrDefault();
404
405 // Data URLs can be very long, so truncate to avoid flooding the log.
406 const uint32_t maxURLLength = 1000;
407 if (url.Length() > maxURLLength) {
408 url.Truncate(maxURLLength);
409 }
410 }
411
412 // We're counting the number of |nsDocShells| to help find leaks
413 --gNumberOfDocShells;
414 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOCSHELL %p == %ld [pid = %d] [id = %" "l"
"u" "] [url = %s]\n", (void*)this, gNumberOfDocShells, getpid
(), mDocShellID, url.get()); } } while (0)
415 gDocShellAndDOMWindowLeakLogging, LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOCSHELL %p == %ld [pid = %d] [id = %" "l"
"u" "] [url = %s]\n", (void*)this, gNumberOfDocShells, getpid
(), mDocShellID, url.get()); } } while (0)
416 ("--DOCSHELL %p == %ld [pid = %d] [id = %" PRIu64 "] [url = %s]\n",do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOCSHELL %p == %ld [pid = %d] [id = %" "l"
"u" "] [url = %s]\n", (void*)this, gNumberOfDocShells, getpid
(), mDocShellID, url.get()); } } while (0)
417 (void*)this, gNumberOfDocShells, getpid(), mDocShellID, url.get()))do { const ::mozilla::LogModule* moz_real_module = gDocShellAndDOMWindowLeakLogging
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "--DOCSHELL %p == %ld [pid = %d] [id = %" "l"
"u" "] [url = %s]\n", (void*)this, gNumberOfDocShells, getpid
(), mDocShellID, url.get()); } } while (0)
;
418 }
419#endif
420}
421
422bool nsDocShell::Initialize() {
423 if (mInitialized) {
424 // We've already been initialized.
425 return true;
426 }
427
428 NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome,do { if (!(mItemType == typeContent || mItemType == typeChrome
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Unexpected item type in docshell"
, "mItemType == typeContent || mItemType == typeChrome", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 429); MOZ_PretendNoReturn(); } } while (0)
429 "Unexpected item type in docshell")do { if (!(mItemType == typeContent || mItemType == typeChrome
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Unexpected item type in docshell"
, "mItemType == typeContent || mItemType == typeChrome", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 429); MOZ_PretendNoReturn(); } } while (0)
;
430
431 NS_ENSURE_TRUE(Preferences::GetRootBranch(), false)do { if ((__builtin_expect(!!(!(Preferences::GetRootBranch())
), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "Preferences::GetRootBranch()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 431); return false; } } while (false)
;
432 mInitialized = true;
433
434 mDisableMetaRefreshWhenInactive =
435 Preferences::GetBool("browser.meta_refresh_when_inactive.disabled",
436 mDisableMetaRefreshWhenInactive);
437
438 if (nsCOMPtr<nsIObserverService> serv = services::GetObserverService()) {
439 const char* msg = mItemType == typeContent ? NS_WEBNAVIGATION_CREATE"webnavigation-create"
440 : NS_CHROME_WEBNAVIGATION_CREATE"chrome-webnavigation-create";
441 serv->NotifyWhenScriptSafe(GetAsSupports(this), msg, nullptr);
442 }
443
444 return true;
445}
446
447/* static */
448already_AddRefed<nsDocShell> nsDocShell::Create(
449 BrowsingContext* aBrowsingContext, uint64_t aContentWindowID) {
450 MOZ_ASSERT(aBrowsingContext, "DocShell without a BrowsingContext!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aBrowsingContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aBrowsingContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aBrowsingContext"
" (" "DocShell without a BrowsingContext!" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBrowsingContext"
") (" "DocShell without a BrowsingContext!" ")"); do { *((volatile
int*)__null) = 450; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
451
452 nsresult rv;
453 RefPtr<nsDocShell> ds = new nsDocShell(aBrowsingContext, aContentWindowID);
454
455 // Initialize the underlying nsDocLoader.
456 rv = ds->nsDocLoader::InitWithBrowsingContext(aBrowsingContext);
457 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 457)
) {
458 return nullptr;
459 }
460
461 // Create our ContentListener
462 ds->mContentListener = new nsDSURIContentListener(ds);
463
464 // We enable if we're in the parent process in order to support non-e10s
465 // configurations.
466 // Note: This check is duplicated in SharedWorkerInterfaceRequestor's
467 // constructor.
468 if (XRE_IsParentProcess()) {
469 ds->mInterceptController = new ServiceWorkerInterceptController();
470 }
471
472 // We want to hold a strong ref to the loadgroup, so it better hold a weak
473 // ref to us... use an InterfaceRequestorProxy to do this.
474 nsCOMPtr<nsIInterfaceRequestor> proxy = new InterfaceRequestorProxy(ds);
475 ds->mLoadGroup->SetNotificationCallbacks(proxy);
476
477 // XXX(nika): We have our BrowsingContext, so we might be able to skip this.
478 // It could be nice to directly set up our DocLoader tree?
479 rv = nsDocLoader::AddDocLoaderAsChildOfRoot(ds);
480 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 480)
) {
481 return nullptr;
482 }
483
484 // Add |ds| as a progress listener to itself. A little weird, but simpler
485 // than reproducing all the listener-notification logic in overrides of the
486 // various methods via which nsDocLoader can be notified. Note that this
487 // holds an nsWeakPtr to |ds|, so it's ok.
488 rv = ds->AddProgressListener(ds, nsIWebProgress::NOTIFY_STATE_DOCUMENT |
489 nsIWebProgress::NOTIFY_STATE_NETWORK |
490 nsIWebProgress::NOTIFY_LOCATION);
491 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 491)
) {
492 return nullptr;
493 }
494
495 // If our BrowsingContext has private browsing enabled, update the number of
496 // private browsing docshells.
497 if (aBrowsingContext->UsePrivateBrowsing()) {
498 ds->NotifyPrivateBrowsingChanged();
499 }
500
501 // If our parent window is present in this process, set up our parent now.
502 RefPtr<WindowContext> parentWC = aBrowsingContext->GetParentWindowContext();
503 if (parentWC && parentWC->IsInProcess()) {
504 // If we don't have a parent element anymore, we can't finish this load!
505 // How'd we get here?
506 RefPtr<Element> parentElement = aBrowsingContext->GetEmbedderElement();
507 if (!parentElement) {
508 MOZ_ASSERT_UNREACHABLE("nsDocShell::Create() - !parentElement")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"nsDocShell::Create() - !parentElement" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 508); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "nsDocShell::Create() - !parentElement"
")"); do { *((volatile int*)__null) = 508; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
509 return nullptr;
510 }
511
512 // We have an in-process parent window, but don't have a parent nsDocShell?
513 // How'd we get here!
514 nsCOMPtr<nsIDocShell> parentShell =
515 parentElement->OwnerDoc()->GetDocShell();
516 if (!parentShell) {
517 MOZ_ASSERT_UNREACHABLE("nsDocShell::Create() - !parentShell")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"nsDocShell::Create() - !parentShell" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 517); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "nsDocShell::Create() - !parentShell"
")"); do { *((volatile int*)__null) = 517; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
518 return nullptr;
519 }
520 parentShell->AddChild(ds);
521 }
522
523 // Make |ds| the primary DocShell for the given context.
524 aBrowsingContext->SetDocShell(ds);
525
526 // Set |ds| default load flags on load group.
527 ds->SetLoadGroupDefaultLoadFlags(aBrowsingContext->GetDefaultLoadFlags());
528
529 if (XRE_IsParentProcess()) {
530 aBrowsingContext->Canonical()->MaybeAddAsProgressListener(ds);
531 }
532
533 return ds.forget();
534}
535
536void nsDocShell::DestroyChildren() {
537 for (auto* child : mChildList.ForwardRange()) {
538 nsCOMPtr<nsIDocShellTreeItem> shell = do_QueryObject(child);
539 NS_ASSERTION(shell, "docshell has null child")do { if (!(shell)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "docshell has null child"
, "shell", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 539); MOZ_PretendNoReturn(); } } while (0)
;
540
541 if (shell) {
542 shell->SetTreeOwner(nullptr);
543 }
544 }
545
546 nsDocLoader::DestroyChildren();
547}
548
549NS_IMPL_CYCLE_COLLECTION_WEAK_PTR_INHERITED(nsDocShell, nsDocLoader,nsDocShell::cycleCollection nsDocShell::_cycleCollectorGlobal
; void nsDocShell::cycleCollection::Unlink(void* p) { nsDocShell
* tmp = DowncastCCParticipant<nsDocShell>(p); nsISupports
* s = static_cast<nsISupports*>(p); nsDocLoader::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mScriptGlobal)
; ImplCycleCollectionUnlink(tmp->mInitialClientSource); ImplCycleCollectionUnlink
(tmp->mBrowsingContext); ImplCycleCollectionUnlink(tmp->
mChromeEventHandler); tmp->DetachWeakPtr(); (void)tmp; } nsresult
nsDocShell::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { nsDocShell* tmp = DowncastCCParticipant<nsDocShell
>(p); nsISupports* s = static_cast<nsISupports*>(p);
if (nsDocLoader::cycleCollection::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE
) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mScriptGlobal, "mScriptGlobal", 0); ImplCycleCollectionTraverse
(cb, tmp->mInitialClientSource, "mInitialClientSource", 0)
; ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext"
, 0); ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler
, "mChromeEventHandler", 0); (void)tmp; return NS_OK; }
550 mScriptGlobal, mInitialClientSource,nsDocShell::cycleCollection nsDocShell::_cycleCollectorGlobal
; void nsDocShell::cycleCollection::Unlink(void* p) { nsDocShell
* tmp = DowncastCCParticipant<nsDocShell>(p); nsISupports
* s = static_cast<nsISupports*>(p); nsDocLoader::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mScriptGlobal)
; ImplCycleCollectionUnlink(tmp->mInitialClientSource); ImplCycleCollectionUnlink
(tmp->mBrowsingContext); ImplCycleCollectionUnlink(tmp->
mChromeEventHandler); tmp->DetachWeakPtr(); (void)tmp; } nsresult
nsDocShell::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { nsDocShell* tmp = DowncastCCParticipant<nsDocShell
>(p); nsISupports* s = static_cast<nsISupports*>(p);
if (nsDocLoader::cycleCollection::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE
) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mScriptGlobal, "mScriptGlobal", 0); ImplCycleCollectionTraverse
(cb, tmp->mInitialClientSource, "mInitialClientSource", 0)
; ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext"
, 0); ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler
, "mChromeEventHandler", 0); (void)tmp; return NS_OK; }
551 mBrowsingContext,nsDocShell::cycleCollection nsDocShell::_cycleCollectorGlobal
; void nsDocShell::cycleCollection::Unlink(void* p) { nsDocShell
* tmp = DowncastCCParticipant<nsDocShell>(p); nsISupports
* s = static_cast<nsISupports*>(p); nsDocLoader::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mScriptGlobal)
; ImplCycleCollectionUnlink(tmp->mInitialClientSource); ImplCycleCollectionUnlink
(tmp->mBrowsingContext); ImplCycleCollectionUnlink(tmp->
mChromeEventHandler); tmp->DetachWeakPtr(); (void)tmp; } nsresult
nsDocShell::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { nsDocShell* tmp = DowncastCCParticipant<nsDocShell
>(p); nsISupports* s = static_cast<nsISupports*>(p);
if (nsDocLoader::cycleCollection::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE
) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mScriptGlobal, "mScriptGlobal", 0); ImplCycleCollectionTraverse
(cb, tmp->mInitialClientSource, "mInitialClientSource", 0)
; ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext"
, 0); ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler
, "mChromeEventHandler", 0); (void)tmp; return NS_OK; }
552 mChromeEventHandler)nsDocShell::cycleCollection nsDocShell::_cycleCollectorGlobal
; void nsDocShell::cycleCollection::Unlink(void* p) { nsDocShell
* tmp = DowncastCCParticipant<nsDocShell>(p); nsISupports
* s = static_cast<nsISupports*>(p); nsDocLoader::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mScriptGlobal)
; ImplCycleCollectionUnlink(tmp->mInitialClientSource); ImplCycleCollectionUnlink
(tmp->mBrowsingContext); ImplCycleCollectionUnlink(tmp->
mChromeEventHandler); tmp->DetachWeakPtr(); (void)tmp; } nsresult
nsDocShell::cycleCollection::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { nsDocShell* tmp = DowncastCCParticipant<nsDocShell
>(p); nsISupports* s = static_cast<nsISupports*>(p);
if (nsDocLoader::cycleCollection::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE
) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mScriptGlobal, "mScriptGlobal", 0); ImplCycleCollectionTraverse
(cb, tmp->mInitialClientSource, "mInitialClientSource", 0)
; ImplCycleCollectionTraverse(cb, tmp->mBrowsingContext, "mBrowsingContext"
, 0); ImplCycleCollectionTraverse(cb, tmp->mChromeEventHandler
, "mChromeEventHandler", 0); (void)tmp; return NS_OK; }
553
554NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader)MozExternalRefCountType nsDocShell::AddRef(void) { static_assert
(!std::is_destructible_v<nsDocShell>, "Reference-counted class "
"nsDocShell" " should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = nsDocLoader::AddRef(); if constexpr (::mozilla
::detail::ShouldLogInheritedRefcnt<nsDocShell>) { NS_LogAddRef
((this), (r), ("nsDocShell"), (uint32_t)(sizeof(*this))); } return
r; }
555NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader)MozExternalRefCountType nsDocShell::Release(void) { nsrefcnt r
= nsDocLoader::Release(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt
<nsDocShell>) { NS_LogRelease((this), (r), ("nsDocShell"
)); } return r; }
556
557NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDocShell)nsresult nsDocShell::QueryInterface(const nsIID& aIID, void
** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(
NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 557); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID), (nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID)) && (LowWordEquals(aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID)) || LowWordEquals(aIID, (nsCycleCollectionISupports::COMTypeInfo
<nsCycleCollectionISupports, void>::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::COMTypeInfo<nsXPCOMCycleCollectionParticipant
, void>::kIID))) { *aInstancePtr = nsDocShell::cycleCollection
::GetParticipant(); return NS_OK; } if (LowWordEquals(aIID, (
nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID))) { *aInstancePtr = nsDocShell::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
558 NS_INTERFACE_MAP_ENTRY(nsIDocShell)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDocShell>)) foundInterface = static_cast
<nsIDocShell*>(this); else
559 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDocShellTreeItem>)) foundInterface
= static_cast<nsIDocShellTreeItem*>(this); else
560 NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIWebNavigation>)) foundInterface
= static_cast<nsIWebNavigation*>(this); else
561 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIBaseWindow>)) foundInterface =
static_cast<nsIBaseWindow*>(this); else
562 NS_INTERFACE_MAP_ENTRY(nsIRefreshURI)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRefreshURI>)) foundInterface =
static_cast<nsIRefreshURI*>(this); else
563 NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIWebProgressListener>)) foundInterface
= static_cast<nsIWebProgressListener*>(this); else
564 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
565 NS_INTERFACE_MAP_ENTRY(nsIWebPageDescriptor)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIWebPageDescriptor>)) foundInterface
= static_cast<nsIWebPageDescriptor*>(this); else
566 NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIAuthPromptProvider>)) foundInterface
= static_cast<nsIAuthPromptProvider*>(this); else
567 NS_INTERFACE_MAP_ENTRY(nsILoadContext)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsILoadContext>)) foundInterface =
static_cast<nsILoadContext*>(this); else
568 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsINetworkInterceptController,if ((mInterceptController) && aIID.Equals(mozilla::detail
::kImplementedIID<std::remove_reference_t<decltype(*this
)>, nsINetworkInterceptController>)) foundInterface = static_cast
<nsINetworkInterceptController*>(this); else
569 mInterceptController)if ((mInterceptController) && aIID.Equals(mozilla::detail
::kImplementedIID<std::remove_reference_t<decltype(*this
)>, nsINetworkInterceptController>)) foundInterface = static_cast
<nsINetworkInterceptController*>(this); else
570NS_INTERFACE_MAP_END_INHERITING(nsDocLoader)foundInterface = 0; nsresult status; if (!foundInterface) status
= nsDocLoader::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
571
572NS_IMETHODIMPnsresult
573nsDocShell::GetInterface(const nsIID& aIID, void** aSink) {
574 MOZ_ASSERT(aSink, "null out param")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSink)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(aSink))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("aSink" " (" "null out param"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aSink" ") ("
"null out param" ")"); do { *((volatile int*)__null) = 574; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
575
576 *aSink = nullptr;
577
578 if (aIID.Equals(NS_GET_IID(nsICommandManager)(nsICommandManager::COMTypeInfo<nsICommandManager, void>
::kIID)
)) {
579 NS_ENSURE_SUCCESS(EnsureCommandHandler(), NS_ERROR_FAILURE)do { nsresult __rv = EnsureCommandHandler(); if (((bool)(__builtin_expect
(!!(NS_FAILED_impl(__rv)), 0)))) { const char* name = mozilla
::GetStaticErrorName(__rv); mozilla::SmprintfPointer msg = mozilla
::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%"
"X" "%s%s%s", "EnsureCommandHandler()", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 579); return NS_ERROR_FAILURE; } } while (false)
;
580 *aSink = static_cast<nsICommandManager*>(mCommandManager.get());
581 } else if (aIID.Equals(NS_GET_IID(nsIURIContentListener)(nsIURIContentListener::COMTypeInfo<nsIURIContentListener,
void>::kIID)
)) {
582 *aSink = mContentListener;
583 } else if ((aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)(nsIScriptGlobalObject::COMTypeInfo<nsIScriptGlobalObject,
void>::kIID)
) ||
584 aIID.Equals(NS_GET_IID(nsIGlobalObject)(nsIGlobalObject::COMTypeInfo<nsIGlobalObject, void>::kIID
)
) ||
585 aIID.Equals(NS_GET_IID(nsPIDOMWindowOuter)(nsPIDOMWindowOuter::COMTypeInfo<nsPIDOMWindowOuter, void>
::kIID)
) ||
586 aIID.Equals(NS_GET_IID(mozIDOMWindowProxy)(mozIDOMWindowProxy::COMTypeInfo<mozIDOMWindowProxy, void>
::kIID)
) ||
587 aIID.Equals(NS_GET_IID(nsIDOMWindow)(nsIDOMWindow::COMTypeInfo<nsIDOMWindow, void>::kIID))) &&
588 NS_SUCCEEDED(EnsureScriptEnvironment())((bool)(__builtin_expect(!!(!NS_FAILED_impl(EnsureScriptEnvironment
())), 1)))
) {
589 return mScriptGlobal->QueryInterface(aIID, aSink);
590 } else if (aIID.Equals(NS_GET_IID(Document)(Document::COMTypeInfo<Document, void>::kIID)) &&
591 NS_SUCCEEDED(EnsureDocumentViewer())((bool)(__builtin_expect(!!(!NS_FAILED_impl(EnsureDocumentViewer
())), 1)))
) {
592 RefPtr<Document> doc = mDocumentViewer->GetDocument();
593 doc.forget(aSink);
594 return *aSink ? NS_OK : NS_NOINTERFACE;
595 } else if (aIID.Equals(NS_GET_IID(nsIPrompt)(nsIPrompt::COMTypeInfo<nsIPrompt, void>::kIID)) &&
596 NS_SUCCEEDED(EnsureScriptEnvironment())((bool)(__builtin_expect(!!(!NS_FAILED_impl(EnsureScriptEnvironment
())), 1)))
) {
597 nsresult rv;
598 nsCOMPtr<nsIWindowWatcher> wwatch =
599 do_GetService(NS_WINDOWWATCHER_CONTRACTID"@mozilla.org/embedcomp/window-watcher;1", &rv);
600 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 600); return rv; } } while (false)
;
601
602 // Get the an auth prompter for our window so that the parenting
603 // of the dialogs works as it should when using tabs.
604 nsIPrompt* prompt;
605 rv = wwatch->GetNewPrompter(mScriptGlobal, &prompt);
606 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 606); return rv; } } while (false)
;
607
608 *aSink = prompt;
609 return NS_OK;
610 } else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)(nsIAuthPrompt::COMTypeInfo<nsIAuthPrompt, void>::kIID)) ||
611 aIID.Equals(NS_GET_IID(nsIAuthPrompt2)(nsIAuthPrompt2::COMTypeInfo<nsIAuthPrompt2, void>::kIID
)
)) {
612 return NS_SUCCEEDED(GetAuthPrompt(PROMPT_NORMAL, aIID, aSink))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetAuthPrompt(PROMPT_NORMAL
, aIID, aSink))), 1)))
613 ? NS_OK
614 : NS_NOINTERFACE;
615 } else if (aIID.Equals(NS_GET_IID(nsISHistory)(nsISHistory::COMTypeInfo<nsISHistory, void>::kIID))) {
616 // This is deprecated, you should instead directly get
617 // ChildSHistory from the browsing context.
618 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Do not try to get a nsISHistory interface from nsIDocShell"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 619); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "Do not try to get a nsISHistory interface from nsIDocShell"
")"); do { *((volatile int*)__null) = 619; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
619 false, "Do not try to get a nsISHistory interface from nsIDocShell")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Do not try to get a nsISHistory interface from nsIDocShell"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 619); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "Do not try to get a nsISHistory interface from nsIDocShell"
")"); do { *((volatile int*)__null) = 619; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
620 return NS_NOINTERFACE;
621 } else if (aIID.Equals(NS_GET_IID(nsIWebBrowserFind)(nsIWebBrowserFind::COMTypeInfo<nsIWebBrowserFind, void>
::kIID)
)) {
622 nsresult rv = EnsureFind();
623 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
624 return rv;
625 }
626
627 *aSink = mFind;
628 NS_ADDREF((nsISupports*)*aSink)((nsISupports*)*aSink)->AddRef();
629 return NS_OK;
630 } else if (aIID.Equals(NS_GET_IID(nsISelectionDisplay)(nsISelectionDisplay::COMTypeInfo<nsISelectionDisplay, void
>::kIID)
)) {
631 if (PresShell* presShell = GetPresShell()) {
632 return presShell->QueryInterface(aIID, aSink);
633 }
634 } else if (aIID.Equals(NS_GET_IID(nsIDocShellTreeOwner)(nsIDocShellTreeOwner::COMTypeInfo<nsIDocShellTreeOwner, void
>::kIID)
)) {
635 nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
636 nsresult rv = GetTreeOwner(getter_AddRefs(treeOwner));
637 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && treeOwner) {
638 return treeOwner->QueryInterface(aIID, aSink);
639 }
640 } else if (aIID.Equals(NS_GET_IID(nsIBrowserChild)(nsIBrowserChild::COMTypeInfo<nsIBrowserChild, void>::kIID
)
)) {
641 *aSink = GetBrowserChild().take();
642 return *aSink ? NS_OK : NS_ERROR_FAILURE;
643 } else {
644 return nsDocLoader::GetInterface(aIID, aSink);
645 }
646
647 NS_IF_ADDREF(((nsISupports*)*aSink))ns_if_addref(((nsISupports*)*aSink));
648 return *aSink ? NS_OK : NS_NOINTERFACE;
649}
650
651NS_IMETHODIMPnsresult
652nsDocShell::SetCancelContentJSEpoch(int32_t aEpoch) {
653 // Note: this gets called fairly early (before a pageload actually starts).
654 // We could probably defer this even longer.
655 nsCOMPtr<nsIBrowserChild> browserChild = GetBrowserChild();
656 static_cast<BrowserChild*>(browserChild.get())
657 ->SetCancelContentJSEpoch(aEpoch);
658 return NS_OK;
659}
660
661nsresult nsDocShell::CheckDisallowedJavascriptLoad(
662 nsDocShellLoadState* aLoadState) {
663 if (!net::SchemeIsJavascript(aLoadState->URI())) {
664 return NS_OK;
665 }
666
667 if (nsCOMPtr<nsIPrincipal> targetPrincipal =
668 GetInheritedPrincipal(/* aConsiderCurrentDocument */ true)) {
669 if (!aLoadState->TriggeringPrincipal()->Subsumes(targetPrincipal)) {
670 return NS_ERROR_DOM_BAD_CROSS_ORIGIN_URI;
671 }
672 return NS_OK;
673 }
674 return NS_ERROR_DOM_BAD_CROSS_ORIGIN_URI;
675}
676
677NS_IMETHODIMPnsresult
678nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
679 return LoadURI(aLoadState, aSetNavigating, false);
680}
681
682nsresult nsDocShell::LoadURI(nsDocShellLoadState* aLoadState,
683 bool aSetNavigating,
684 bool aContinueHandlingSubframeHistory) {
685 MOZ_ASSERT(aLoadState, "Must have a valid load state!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadState)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadState))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aLoadState" " (" "Must have a valid load state!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 685); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState" ") ("
"Must have a valid load state!" ")"); do { *((volatile int*)
__null) = 685; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
686 // NOTE: This comparison between what appears to be internal/external load
687 // flags is intentional, as it's ensuring that the caller isn't using any of
688 // the flags reserved for implementations by the `nsIWebNavigation` interface.
689 // In the future, this check may be dropped.
690 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype((aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!((aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("(aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0"
" (" "Should not have these flags set" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 692); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0"
") (" "Should not have these flags set" ")"); do { *((volatile
int*)__null) = 692; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
691 (aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,do { static_assert( mozilla::detail::AssertionConditionType<
decltype((aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!((aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("(aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0"
" (" "Should not have these flags set" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 692); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0"
") (" "Should not have these flags set" ")"); do { *((volatile
int*)__null) = 692; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
692 "Should not have these flags set")do { static_assert( mozilla::detail::AssertionConditionType<
decltype((aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!((aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("(aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0"
" (" "Should not have these flags set" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 692); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0"
") (" "Should not have these flags set" ")"); do { *((volatile
int*)__null) = 692; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
693 MOZ_ASSERT(aLoadState->TargetBrowsingContext().IsNull(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadState->TargetBrowsingContext().IsNull())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aLoadState->TargetBrowsingContext().IsNull()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aLoadState->TargetBrowsingContext().IsNull()"
" (" "Targeting doesn't occur until InternalLoad" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 694); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->TargetBrowsingContext().IsNull()"
") (" "Targeting doesn't occur until InternalLoad" ")"); do {
*((volatile int*)__null) = 694; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
694 "Targeting doesn't occur until InternalLoad")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadState->TargetBrowsingContext().IsNull())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aLoadState->TargetBrowsingContext().IsNull()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aLoadState->TargetBrowsingContext().IsNull()"
" (" "Targeting doesn't occur until InternalLoad" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 694); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->TargetBrowsingContext().IsNull()"
") (" "Targeting doesn't occur until InternalLoad" ")"); do {
*((volatile int*)__null) = 694; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
695
696 if (!aLoadState->TriggeringPrincipal()) {
697 MOZ_ASSERT(false, "LoadURI must have a triggering principal")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "LoadURI must have a triggering principal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 697); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"LoadURI must have a triggering principal" ")"); do { *((volatile
int*)__null) = 697; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
698 return NS_ERROR_FAILURE;
699 }
700
701 MOZ_TRY(CheckDisallowedJavascriptLoad(aLoadState))do { auto mozTryTempResult_ = ::mozilla::ToResult(CheckDisallowedJavascriptLoad
(aLoadState)); if ((__builtin_expect(!!(mozTryTempResult_.isErr
()), 0))) { return mozTryTempResult_.propagateErr(); } } while
(0)
;
702
703 bool oldIsNavigating = mIsNavigating;
704 auto cleanupIsNavigating =
705 MakeScopeExit([&]() { mIsNavigating = oldIsNavigating; });
706 if (aSetNavigating) {
707 mIsNavigating = true;
708 }
709
710 PopupBlocker::PopupControlState popupState = PopupBlocker::openOverridden;
711 if (aLoadState->HasLoadFlags(LOAD_FLAGS_ALLOW_POPUPS)) {
712 popupState = PopupBlocker::openAllowed;
713 // If we allow popups as part of the navigation, ensure we fake a user
714 // interaction, so that popups can, in fact, be allowed to open.
715 if (WindowContext* wc = mBrowsingContext->GetCurrentWindowContext()) {
716 wc->NotifyUserGestureActivation();
717 }
718 }
719
720 AutoPopupStatePusherAutoPopupStatePusherInternal statePusher(popupState);
721
722 if (aLoadState->GetCancelContentJSEpoch().isSome()) {
723 SetCancelContentJSEpoch(*aLoadState->GetCancelContentJSEpoch());
724 }
725
726 // Note: we allow loads to get through here even if mFiredUnloadEvent is
727 // true; that case will get handled in LoadInternal or LoadHistoryEntry,
728 // so we pass false as the second parameter to IsNavigationAllowed.
729 // However, we don't allow the page to change location *in the middle of*
730 // firing beforeunload, so we do need to check if *beforeunload* is currently
731 // firing, so we call IsNavigationAllowed rather than just IsPrintingOrPP.
732 if (!IsNavigationAllowed(true, false)) {
733 return NS_OK; // JS may not handle returning of an error code
734 }
735
736 nsLoadFlags defaultLoadFlags = mBrowsingContext->GetDefaultLoadFlags();
737 if (aLoadState->HasLoadFlags(LOAD_FLAGS_FORCE_TRR)) {
738 defaultLoadFlags |= nsIRequest::LOAD_TRR_ONLY_MODE;
739 } else if (aLoadState->HasLoadFlags(LOAD_FLAGS_DISABLE_TRR)) {
740 defaultLoadFlags |= nsIRequest::LOAD_TRR_DISABLED_MODE;
741 }
742
743 MOZ_ALWAYS_SUCCEEDS(mBrowsingContext->SetDefaultLoadFlags(defaultLoadFlags))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mBrowsingContext->SetDefaultLoadFlags(defaultLoadFlags)))
, 1)))), 1))) { } else { do { static_assert( mozilla::detail::
AssertionConditionType<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mBrowsingContext->SetDefaultLoadFlags(defaultLoadFlags))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 743); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mBrowsingContext->SetDefaultLoadFlags(defaultLoadFlags))"
")"); do { *((volatile int*)__null) = 743; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
744
745 if (!StartupTimeline::HasRecord(StartupTimeline::FIRST_LOAD_URI) &&
746 mItemType == typeContent && !NS_IsAboutBlank(aLoadState->URI())) {
747 StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI);
748 }
749
750 // LoadType used to be set to a default value here, if no LoadInfo/LoadState
751 // object was passed in. That functionality has been removed as of bug
752 // 1492648. LoadType should now be set up by the caller at the time they
753 // create their nsDocShellLoadState object to pass into LoadURI.
754
755 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]: loading %s with flags 0x%08x"
, this, aLoadState->URI()->GetSpecOrDefault().get(), aLoadState
->LoadFlags()); } } while (0)
756 gDocShellLeakLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]: loading %s with flags 0x%08x"
, this, aLoadState->URI()->GetSpecOrDefault().get(), aLoadState
->LoadFlags()); } } while (0)
757 ("nsDocShell[%p]: loading %s with flags 0x%08x", this,do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]: loading %s with flags 0x%08x"
, this, aLoadState->URI()->GetSpecOrDefault().get(), aLoadState
->LoadFlags()); } } while (0)
758 aLoadState->URI()->GetSpecOrDefault().get(), aLoadState->LoadFlags()))do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]: loading %s with flags 0x%08x"
, this, aLoadState->URI()->GetSpecOrDefault().get(), aLoadState
->LoadFlags()); } } while (0)
;
759
760 if ((!aLoadState->LoadIsFromSessionHistory() &&
761 !LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(),((aLoadState->LoadType()) & ((LOAD_FLAGS_REPLACE_HISTORY
) << 16))
762 LOAD_FLAGS_REPLACE_HISTORY)((aLoadState->LoadType()) & ((LOAD_FLAGS_REPLACE_HISTORY
) << 16))
) ||
763 aContinueHandlingSubframeHistory) {
764 // This is possibly a subframe, so handle it accordingly.
765 //
766 // If history exists, it will be loaded into the aLoadState object, and the
767 // LoadType will be changed.
768 if (MaybeHandleSubframeHistory(aLoadState,
769 aContinueHandlingSubframeHistory)) {
770 // MaybeHandleSubframeHistory returns true if we need to continue loading
771 // asynchronously.
772 return NS_OK;
773 }
774 }
775
776 if (aLoadState->LoadIsFromSessionHistory()) {
777 MOZ_LOG(gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]: loading from session history"
, this); } } while (0)
778 ("nsDocShell[%p]: loading from session history", this))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]: loading from session history"
, this); } } while (0)
;
779
780 if (!mozilla::SessionHistoryInParent()) {
781 nsCOMPtr<nsISHEntry> entry = aLoadState->SHEntry();
782 return LoadHistoryEntry(entry, aLoadState->LoadType(),
783 aLoadState->HasValidUserGestureActivation());
784 }
785
786 // FIXME Null check aLoadState->GetLoadingSessionHistoryInfo()?
787 return LoadHistoryEntry(*aLoadState->GetLoadingSessionHistoryInfo(),
788 aLoadState->LoadType(),
789 aLoadState->HasValidUserGestureActivation());
790 }
791
792 // On history navigation via Back/Forward buttons, don't execute
793 // automatic JavaScript redirection such as |location.href = ...| or
794 // |window.open()|
795 //
796 // LOAD_NORMAL: window.open(...) etc.
797 // LOAD_STOP_CONTENT: location.href = ..., location.assign(...)
798 if ((aLoadState->LoadType() == LOAD_NORMAL ||
799 aLoadState->LoadType() == LOAD_STOP_CONTENT) &&
800 ShouldBlockLoadingForBackButton()) {
801 return NS_OK;
802 }
803
804 BrowsingContext::Type bcType = mBrowsingContext->GetType();
805
806 // Set up the inheriting principal in LoadState.
807 nsresult rv = aLoadState->SetupInheritingPrincipal(
808 bcType, mBrowsingContext->OriginAttributesRef());
809 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 809); return rv; } } while (false)
;
810
811 rv = aLoadState->SetupTriggeringPrincipal(
812 mBrowsingContext->OriginAttributesRef());
813 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 813); return rv; } } while (false)
;
814
815 aLoadState->CalculateLoadURIFlags();
816
817 MOZ_ASSERT(aLoadState->TypeHint().IsVoid(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadState->TypeHint().IsVoid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadState->TypeHint().IsVoid
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aLoadState->TypeHint().IsVoid()" " (" "Typehint should be null when calling InternalLoad from LoadURI"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->TypeHint().IsVoid()"
") (" "Typehint should be null when calling InternalLoad from LoadURI"
")"); do { *((volatile int*)__null) = 818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
818 "Typehint should be null when calling InternalLoad from LoadURI")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadState->TypeHint().IsVoid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadState->TypeHint().IsVoid
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aLoadState->TypeHint().IsVoid()" " (" "Typehint should be null when calling InternalLoad from LoadURI"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->TypeHint().IsVoid()"
") (" "Typehint should be null when calling InternalLoad from LoadURI"
")"); do { *((volatile int*)__null) = 818; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
819 MOZ_ASSERT(aLoadState->FileName().IsVoid(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadState->FileName().IsVoid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadState->FileName().IsVoid
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aLoadState->FileName().IsVoid()" " (" "FileName should be null when calling InternalLoad from LoadURI"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 820); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->FileName().IsVoid()"
") (" "FileName should be null when calling InternalLoad from LoadURI"
")"); do { *((volatile int*)__null) = 820; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
820 "FileName should be null when calling InternalLoad from LoadURI")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadState->FileName().IsVoid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadState->FileName().IsVoid
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aLoadState->FileName().IsVoid()" " (" "FileName should be null when calling InternalLoad from LoadURI"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 820); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->FileName().IsVoid()"
") (" "FileName should be null when calling InternalLoad from LoadURI"
")"); do { *((volatile int*)__null) = 820; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
821 MOZ_ASSERT(!aLoadState->LoadIsFromSessionHistory(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aLoadState->LoadIsFromSessionHistory())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!aLoadState->LoadIsFromSessionHistory()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!aLoadState->LoadIsFromSessionHistory()"
" (" "Shouldn't be loading from an entry when calling InternalLoad "
"from LoadURI" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 823); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aLoadState->LoadIsFromSessionHistory()"
") (" "Shouldn't be loading from an entry when calling InternalLoad "
"from LoadURI" ")"); do { *((volatile int*)__null) = 823; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
822 "Shouldn't be loading from an entry when calling InternalLoad "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aLoadState->LoadIsFromSessionHistory())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!aLoadState->LoadIsFromSessionHistory()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!aLoadState->LoadIsFromSessionHistory()"
" (" "Shouldn't be loading from an entry when calling InternalLoad "
"from LoadURI" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 823); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aLoadState->LoadIsFromSessionHistory()"
") (" "Shouldn't be loading from an entry when calling InternalLoad "
"from LoadURI" ")"); do { *((volatile int*)__null) = 823; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
823 "from LoadURI")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aLoadState->LoadIsFromSessionHistory())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!aLoadState->LoadIsFromSessionHistory()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!aLoadState->LoadIsFromSessionHistory()"
" (" "Shouldn't be loading from an entry when calling InternalLoad "
"from LoadURI" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 823); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aLoadState->LoadIsFromSessionHistory()"
") (" "Shouldn't be loading from an entry when calling InternalLoad "
"from LoadURI" ")"); do { *((volatile int*)__null) = 823; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
824
825 // If we have a system triggering principal, we can assume that this load was
826 // triggered by some UI in the browser chrome, such as the URL bar or
827 // bookmark bar. This should count as a user interaction for the current sh
828 // entry, so that the user may navigate back to the current entry, from the
829 // entry that is going to be added as part of this load.
830 nsCOMPtr<nsIPrincipal> triggeringPrincipal =
831 aLoadState->TriggeringPrincipal();
832 if (triggeringPrincipal && triggeringPrincipal->IsSystemPrincipal()) {
833 if (mozilla::SessionHistoryInParent()) {
834 WindowContext* topWc = mBrowsingContext->GetTopWindowContext();
835 if (topWc && !topWc->IsDiscarded()) {
836 MOZ_ALWAYS_SUCCEEDS(topWc->SetSHEntryHasUserInteraction(true))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(topWc->SetSHEntryHasUserInteraction(true))), 1)))), 1))) {
} else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(topWc->SetSHEntryHasUserInteraction(true))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 836); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(topWc->SetSHEntryHasUserInteraction(true))"
")"); do { *((volatile int*)__null) = 836; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
837 }
838 } else {
839 bool oshe = false;
840 nsCOMPtr<nsISHEntry> currentSHEntry;
841 GetCurrentSHEntry(getter_AddRefs(currentSHEntry), &oshe);
842 if (currentSHEntry) {
843 currentSHEntry->SetHasUserInteraction(true);
844 }
845 }
846 }
847
848 rv = InternalLoad(aLoadState);
849 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 849); return rv; } } while (false)
;
850
851 if (aLoadState->GetOriginalURIString().isSome()) {
852 // Save URI string in case it's needed later when
853 // sending to search engine service in EndPageLoad()
854 mOriginalUriString = *aLoadState->GetOriginalURIString();
855 }
856
857 return NS_OK;
858}
859
860bool nsDocShell::IsLoadingFromSessionHistory() {
861 return mActiveEntryIsLoadingFromSessionHistory;
862}
863
864// StopDetector is modeled similarly to OnloadBlocker; it is a rather
865// dummy nsIRequest implementation which can be added to an nsILoadGroup to
866// detect Cancel calls.
867class StopDetector final : public nsIRequest {
868 public:
869 StopDetector() = default;
870
871 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
872 NS_DECL_NSIREQUESTvirtual nsresult GetName(nsACString& aName) override; virtual
nsresult IsPending(bool *_retval) override; virtual nsresult
GetStatus(nsresult *aStatus) override; virtual nsresult Cancel
(nsresult aStatus) override; virtual nsresult Suspend(void) override
; virtual nsresult Resume(void) override; virtual nsresult GetLoadGroup
(nsILoadGroup **aLoadGroup) override; virtual nsresult SetLoadGroup
(nsILoadGroup *aLoadGroup) override; virtual nsresult GetLoadFlags
(nsLoadFlags *aLoadFlags) override; virtual nsresult SetLoadFlags
(nsLoadFlags aLoadFlags) override; virtual nsresult GetTRRMode
(nsIRequest::TRRMode *_retval) override; virtual nsresult SetTRRMode
(nsIRequest::TRRMode mode) override; virtual nsresult CancelWithReason
(nsresult aStatus, const nsACString& aReason) override; virtual
nsresult GetCanceledReason(nsACString& aCanceledReason) override
; virtual nsresult SetCanceledReason(const nsACString& aCanceledReason
) override;
873
874 bool Canceled() { return mCanceled; }
875
876 private:
877 ~StopDetector() = default;
878
879 bool mCanceled = false;
880};
881
882NS_IMPL_ISUPPORTS(StopDetector, nsIRequest)MozExternalRefCountType StopDetector::AddRef(void) { static_assert
(!std::is_destructible_v<StopDetector>, "Reference-counted class "
"StopDetector" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 882); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
882; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("StopDetector" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("StopDetector" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"StopDetector\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 882); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"StopDetector\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 882; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("StopDetector" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("StopDetector"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
StopDetector::Release(void) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(int32_t(mRefCnt) > 0)
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 882); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 882
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("StopDetector" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("StopDetector" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"StopDetector\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 882); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"StopDetector\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 882; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("StopDetector" " not thread-safe"); const char
* const nametmp = "StopDetector"; nsrefcnt count = --mRefCnt;
NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
StopDetector::QueryInterface(const nsIID& aIID, void** aInstancePtr
) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 882); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<StopDetector, nsIRequest>, int32_t( reinterpret_cast
<char*>(static_cast<nsIRequest*>((StopDetector*)0x1000
)) - reinterpret_cast<char*>((StopDetector*)0x1000))}, {
&mozilla::detail::kImplementedIID<StopDetector, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIRequest*>((StopDetector*)0x1000))
) - reinterpret_cast<char*>((StopDetector*)0x1000))}, {
nullptr, 0 } } ; static_assert((sizeof(table) / sizeof(table
[0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
883
884NS_IMETHODIMPnsresult
885StopDetector::GetName(nsACString& aResult) {
886 aResult.AssignLiteral("about:stop-detector");
887 return NS_OK;
888}
889
890NS_IMETHODIMPnsresult
891StopDetector::IsPending(bool* aRetVal) {
892 *aRetVal = true;
893 return NS_OK;
894}
895
896NS_IMETHODIMPnsresult
897StopDetector::GetStatus(nsresult* aStatus) {
898 *aStatus = NS_OK;
899 return NS_OK;
900}
901
902NS_IMETHODIMPnsresult StopDetector::SetCanceledReason(const nsACString& aReason) {
903 return SetCanceledReasonImpl(aReason);
904}
905
906NS_IMETHODIMPnsresult StopDetector::GetCanceledReason(nsACString& aReason) {
907 return GetCanceledReasonImpl(aReason);
908}
909
910NS_IMETHODIMPnsresult StopDetector::CancelWithReason(nsresult aStatus,
911 const nsACString& aReason) {
912 return CancelWithReasonImpl(aStatus, aReason);
913}
914
915NS_IMETHODIMPnsresult
916StopDetector::Cancel(nsresult aStatus) {
917 mCanceled = true;
918 return NS_OK;
919}
920
921NS_IMETHODIMPnsresult
922StopDetector::Suspend(void) { return NS_OK; }
923NS_IMETHODIMPnsresult
924StopDetector::Resume(void) { return NS_OK; }
925
926NS_IMETHODIMPnsresult
927StopDetector::GetLoadGroup(nsILoadGroup** aLoadGroup) {
928 *aLoadGroup = nullptr;
929 return NS_OK;
930}
931
932NS_IMETHODIMPnsresult
933StopDetector::SetLoadGroup(nsILoadGroup* aLoadGroup) { return NS_OK; }
934
935NS_IMETHODIMPnsresult
936StopDetector::GetLoadFlags(nsLoadFlags* aLoadFlags) {
937 *aLoadFlags = nsIRequest::LOAD_NORMAL;
938 return NS_OK;
939}
940
941NS_IMETHODIMPnsresult
942StopDetector::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
943 return GetTRRModeImpl(aTRRMode);
944}
945
946NS_IMETHODIMPnsresult
947StopDetector::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
948 return SetTRRModeImpl(aTRRMode);
949}
950
951NS_IMETHODIMPnsresult
952StopDetector::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; }
953
954bool nsDocShell::MaybeHandleSubframeHistory(
955 nsDocShellLoadState* aLoadState, bool aContinueHandlingSubframeHistory) {
956 // First, verify if this is a subframe.
957 // Note, it is ok to rely on docshell here and not browsing context since when
958 // an iframe is created, it has first in-process docshell.
959 nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
960 GetInProcessSameTypeParent(getter_AddRefs(parentAsItem));
961 nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(parentAsItem));
962
963 if (!parentDS || parentDS == static_cast<nsIDocShell*>(this)) {
964 if (mBrowsingContext && mBrowsingContext->IsTop()) {
965 // This is the root docshell. If we got here while
966 // executing an onLoad Handler,this load will not go
967 // into session history.
968 // XXX Why is this code in a method which deals with iframes!
969 if (aLoadState->IsFormSubmission()) {
970#ifdef DEBUG1
971 if (!mEODForCurrentDocument) {
972 const MaybeDiscarded<BrowsingContext>& targetBC =
973 aLoadState->TargetBrowsingContext();
974 MOZ_ASSERT_IF(GetBrowsingContext() == targetBC.get(),do { if (GetBrowsingContext() == targetBC.get()) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(aLoadState
->LoadType() == LOAD_NORMAL_REPLACE)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadState->LoadType() ==
LOAD_NORMAL_REPLACE))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aLoadState->LoadType() == LOAD_NORMAL_REPLACE", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 975); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->LoadType() == LOAD_NORMAL_REPLACE"
")"); do { *((volatile int*)__null) = 975; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
975 aLoadState->LoadType() == LOAD_NORMAL_REPLACE)do { if (GetBrowsingContext() == targetBC.get()) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(aLoadState
->LoadType() == LOAD_NORMAL_REPLACE)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadState->LoadType() ==
LOAD_NORMAL_REPLACE))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aLoadState->LoadType() == LOAD_NORMAL_REPLACE", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 975); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aLoadState->LoadType() == LOAD_NORMAL_REPLACE"
")"); do { *((volatile int*)__null) = 975; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
976 }
977#endif
978 } else {
979 bool inOnLoadHandler = false;
980 GetIsExecutingOnLoadHandler(&inOnLoadHandler);
981 if (inOnLoadHandler) {
982 aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
983 }
984 }
985 }
986 return false;
987 }
988
989 /* OK. It is a subframe. Checkout the parent's loadtype. If the parent was
990 * loaded through a history mechanism, then get the SH entry for the child
991 * from the parent. This is done to restore frameset navigation while going
992 * back/forward. If the parent was loaded through any other loadType, set the
993 * child's loadType too accordingly, so that session history does not get
994 * confused.
995 */
996
997 // Get the parent's load type
998 uint32_t parentLoadType;
999 parentDS->GetLoadType(&parentLoadType);
1000
1001 if (!aContinueHandlingSubframeHistory) {
1002 if (mozilla::SessionHistoryInParent()) {
1003 if (nsDocShell::Cast(parentDS.get())->IsLoadingFromSessionHistory() &&
1004 !GetCreatedDynamically()) {
1005 if (XRE_IsContentProcess()) {
1006 dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
1007 nsCOMPtr<nsILoadGroup> loadGroup;
1008 GetLoadGroup(getter_AddRefs(loadGroup));
1009 if (contentChild && loadGroup && !mCheckingSessionHistory) {
1010 RefPtr<Document> parentDoc = parentDS->GetDocument();
1011 parentDoc->BlockOnload();
1012 RefPtr<BrowsingContext> browsingContext = mBrowsingContext;
1013 Maybe<uint64_t> currentLoadIdentifier =
1014 mBrowsingContext->GetCurrentLoadIdentifier();
1015 RefPtr<nsDocShellLoadState> loadState = aLoadState;
1016 bool isNavigating = mIsNavigating;
1017 RefPtr<StopDetector> stopDetector = new StopDetector();
1018 loadGroup->AddRequest(stopDetector, nullptr);
1019 // Need to set mCheckingSessionHistory so that
1020 // GetIsAttemptingToNavigate() returns true.
1021 mCheckingSessionHistory = true;
1022
1023 auto resolve =
1024 [currentLoadIdentifier, browsingContext, parentDoc, loadState,
1025 isNavigating, loadGroup, stopDetector](
1026 mozilla::Maybe<LoadingSessionHistoryInfo>&& aResult) {
1027 RefPtr<nsDocShell> docShell =
1028 static_cast<nsDocShell*>(browsingContext->GetDocShell());
1029 auto unblockParent = MakeScopeExit(
1030 [loadGroup, stopDetector, parentDoc, docShell]() {
1031 if (docShell) {
1032 docShell->mCheckingSessionHistory = false;
1033 }
1034 loadGroup->RemoveRequest(stopDetector, nullptr, NS_OK);
1035 parentDoc->UnblockOnload(false);
1036 });
1037
1038 if (!docShell || !docShell->mCheckingSessionHistory) {
1039 return;
1040 }
1041
1042 if (stopDetector->Canceled()) {
1043 return;
1044 }
1045 if (currentLoadIdentifier ==
1046 browsingContext->GetCurrentLoadIdentifier() &&
1047 aResult.isSome()) {
1048 loadState->SetLoadingSessionHistoryInfo(aResult.value());
1049 // This is an initial subframe load from the session
1050 // history, index doesn't need to be updated.
1051 loadState->SetLoadIsFromSessionHistory(0, false);
1052 }
1053
1054 // We got the results back from the parent process, call
1055 // LoadURI again with the possibly updated data.
1056 docShell->LoadURI(loadState, isNavigating, true);
1057 };
1058 auto reject = [loadGroup, stopDetector, browsingContext,
1059 parentDoc](mozilla::ipc::ResponseRejectReason) {
1060 RefPtr<nsDocShell> docShell =
1061 static_cast<nsDocShell*>(browsingContext->GetDocShell());
1062 if (docShell) {
1063 docShell->mCheckingSessionHistory = false;
1064 }
1065 // In practise reject shouldn't be called ever.
1066 loadGroup->RemoveRequest(stopDetector, nullptr, NS_OK);
1067 parentDoc->UnblockOnload(false);
1068 };
1069 contentChild->SendGetLoadingSessionHistoryInfoFromParent(
1070 mBrowsingContext, std::move(resolve), std::move(reject));
1071 return true;
1072 }
1073 } else {
1074 Maybe<LoadingSessionHistoryInfo> info;
1075 mBrowsingContext->Canonical()->GetLoadingSessionHistoryInfoFromParent(
1076 info);
1077 if (info.isSome()) {
1078 aLoadState->SetLoadingSessionHistoryInfo(info.value());
1079 // This is an initial subframe load from the session
1080 // history, index doesn't need to be updated.
1081 aLoadState->SetLoadIsFromSessionHistory(0, false);
1082 }
1083 }
1084 }
1085 } else {
1086 // Get the ShEntry for the child from the parent
1087 nsCOMPtr<nsISHEntry> currentSH;
1088 bool oshe = false;
1089 parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe);
1090 bool dynamicallyAddedChild = GetCreatedDynamically();
1091
1092 if (!dynamicallyAddedChild && !oshe && currentSH) {
1093 // Only use the old SHEntry, if we're sure enough that
1094 // it wasn't originally for some other frame.
1095 nsCOMPtr<nsISHEntry> shEntry;
1096 currentSH->GetChildSHEntryIfHasNoDynamicallyAddedChild(
1097 mBrowsingContext->ChildOffset(), getter_AddRefs(shEntry));
1098 if (shEntry) {
1099 aLoadState->SetSHEntry(shEntry);
1100 }
1101 }
1102 }
1103 }
1104
1105 // Make some decisions on the child frame's loadType based on the
1106 // parent's loadType, if the subframe hasn't loaded anything into it.
1107 //
1108 // In some cases privileged scripts may try to get the DOMWindow
1109 // reference of this docshell before the loading starts, causing the
1110 // initial about:blank content viewer being created and mCurrentURI being
1111 // set. To handle this case we check if mCurrentURI is about:blank and
1112 // currentSHEntry is null.
1113 bool oshe = false;
1114 nsCOMPtr<nsISHEntry> currentChildEntry;
1115 GetCurrentSHEntry(getter_AddRefs(currentChildEntry), &oshe);
1116
1117 if (mCurrentURI && (!NS_IsAboutBlank(mCurrentURI) || currentChildEntry ||
1118 mLoadingEntry || mActiveEntry)) {
1119 // This is a pre-existing subframe. If
1120 // 1. The load of this frame was not originally initiated by session
1121 // history directly (i.e. (!shEntry) condition succeeded, but it can
1122 // still be a history load on parent which causes this frame being
1123 // loaded), which we checked with the above assert, and
1124 // 2. mCurrentURI is not null, nor the initial about:blank,
1125 // it is possible that a parent's onLoadHandler or even self's
1126 // onLoadHandler is loading a new page in this child. Check parent's and
1127 // self's busy flag and if it is set, we don't want this onLoadHandler
1128 // load to get in to session history.
1129 BusyFlags parentBusy = parentDS->GetBusyFlags();
1130 BusyFlags selfBusy = GetBusyFlags();
1131
1132 if (parentBusy & BUSY_FLAGS_BUSY || selfBusy & BUSY_FLAGS_BUSY) {
1133 aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
1134 aLoadState->ClearLoadIsFromSessionHistory();
1135 }
1136 return false;
1137 }
1138
1139 // This is a newly created frame. Check for exception cases first.
1140 // By default the subframe will inherit the parent's loadType.
1141 if (aLoadState->LoadIsFromSessionHistory() &&
1142 (parentLoadType == LOAD_NORMAL || parentLoadType == LOAD_LINK)) {
1143 // The parent was loaded normally. In this case, this *brand new*
1144 // child really shouldn't have a SHEntry. If it does, it could be
1145 // because the parent is replacing an existing frame with a new frame,
1146 // in the onLoadHandler. We don't want this url to get into session
1147 // history. Clear off shEntry, and set load type to
1148 // LOAD_BYPASS_HISTORY.
1149 bool inOnLoadHandler = false;
1150 parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler);
1151 if (inOnLoadHandler) {
1152 aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
1153 aLoadState->ClearLoadIsFromSessionHistory();
1154 }
1155 } else if (parentLoadType == LOAD_REFRESH) {
1156 // Clear shEntry. For refresh loads, we have to load
1157 // what comes through the pipe, not what's in history.
1158 aLoadState->ClearLoadIsFromSessionHistory();
1159 } else if ((parentLoadType == LOAD_BYPASS_HISTORY) ||
1160 (aLoadState->LoadIsFromSessionHistory() &&
1161 ((parentLoadType & LOAD_CMD_HISTORY) ||
1162 (parentLoadType == LOAD_RELOAD_NORMAL) ||
1163 (parentLoadType == LOAD_RELOAD_CHARSET_CHANGE) ||
1164 (parentLoadType == LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE) ||
1165 (parentLoadType ==
1166 LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE)))) {
1167 // If the parent url, bypassed history or was loaded from
1168 // history, pass on the parent's loadType to the new child
1169 // frame too, so that the child frame will also
1170 // avoid getting into history.
1171 aLoadState->SetLoadType(parentLoadType);
1172 } else if (parentLoadType == LOAD_ERROR_PAGE) {
1173 // If the parent document is an error page, we don't
1174 // want to update global/session history. However,
1175 // this child frame is not an error page.
1176 aLoadState->SetLoadType(LOAD_BYPASS_HISTORY);
1177 } else if ((parentLoadType == LOAD_RELOAD_BYPASS_CACHE) ||
1178 (parentLoadType == LOAD_RELOAD_BYPASS_PROXY) ||
1179 (parentLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE)) {
1180 // the new frame should inherit the parent's load type so that it also
1181 // bypasses the cache and/or proxy
1182 aLoadState->SetLoadType(parentLoadType);
1183 }
1184
1185 return false;
1186}
1187
1188/*
1189 * Reset state to a new content model within the current document and the
1190 * document viewer. Called by the document before initiating an out of band
1191 * document.write().
1192 */
1193NS_IMETHODIMPnsresult
1194nsDocShell::PrepareForNewContentModel() {
1195 // Clear out our form control state, because the state of controls
1196 // in the pre-open() document should not affect the state of
1197 // controls that are now going to be written.
1198 SetLayoutHistoryState(nullptr);
1199 mEODForCurrentDocument = false;
1200 return NS_OK;
1201}
1202
1203NS_IMETHODIMPnsresult
1204nsDocShell::FirePageHideNotification(bool aIsUnload) {
1205 FirePageHideNotificationInternal(aIsUnload, false);
1206 return NS_OK;
1207}
1208
1209void nsDocShell::FirePageHideNotificationInternal(
1210 bool aIsUnload, bool aSkipCheckingDynEntries) {
1211 if (mDocumentViewer && !mFiredUnloadEvent) {
1212 // Keep an explicit reference since calling PageHide could release
1213 // mDocumentViewer
1214 nsCOMPtr<nsIDocumentViewer> viewer(mDocumentViewer);
1215 mFiredUnloadEvent = true;
1216
1217 if (mTiming) {
1218 mTiming->NotifyUnloadEventStart();
1219 }
1220
1221 viewer->PageHide(aIsUnload);
1222
1223 if (mTiming) {
1224 mTiming->NotifyUnloadEventEnd();
1225 }
1226
1227 AutoTArray<nsCOMPtr<nsIDocShell>, 8> kids;
1228 uint32_t n = mChildList.Length();
1229 kids.SetCapacity(n);
1230 for (uint32_t i = 0; i < n; i++) {
1231 kids.AppendElement(do_QueryInterface(ChildAt(i)));
1232 }
1233
1234 n = kids.Length();
1235 for (uint32_t i = 0; i < n; ++i) {
1236 RefPtr<nsDocShell> child = static_cast<nsDocShell*>(kids[i].get());
1237 if (child) {
1238 // Skip checking dynamic subframe entries in our children.
1239 child->FirePageHideNotificationInternal(aIsUnload, true);
1240 }
1241 }
1242
1243 // If the document is unloading, remove all dynamic subframe entries.
1244 if (aIsUnload && !aSkipCheckingDynEntries) {
1245 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
1246 if (rootSH) {
1247 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p unloading, remove dynamic subframe entries"
, this); } } while (0)
1248 gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p unloading, remove dynamic subframe entries"
, this); } } while (0)
1249 ("nsDocShell %p unloading, remove dynamic subframe entries", this))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p unloading, remove dynamic subframe entries"
, this); } } while (0)
;
1250 if (mozilla::SessionHistoryInParent()) {
1251 if (mActiveEntry) {
1252 mBrowsingContext->RemoveDynEntriesFromActiveSessionHistoryEntry();
1253 }
1254 MOZ_LOG(gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p unloading, no active entries"
, this); } } while (0)
1255 ("nsDocShell %p unloading, no active entries", this))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p unloading, no active entries"
, this); } } while (0)
;
1256 } else if (mOSHE) {
1257 int32_t index = rootSH->Index();
1258 rootSH->LegacySHistory()->RemoveDynEntries(index, mOSHE);
1259 }
1260 }
1261 }
1262
1263 // Now make sure our editor, if any, is detached before we go
1264 // any farther.
1265 DetachEditorFromWindow();
1266 }
1267}
1268
1269void nsDocShell::ThawFreezeNonRecursive(bool aThaw) {
1270 MOZ_ASSERT(mozilla::BFCacheInParent())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mozilla::BFCacheInParent())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mozilla::BFCacheInParent()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mozilla::BFCacheInParent()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1270); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::BFCacheInParent()"
")"); do { *((volatile int*)__null) = 1270; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1271
1272 if (!mScriptGlobal) {
1273 return;
1274 }
1275
1276 if (RefPtr<nsGlobalWindowInner> inner =
1277 nsGlobalWindowInner::Cast(mScriptGlobal->GetCurrentInnerWindow())) {
1278 if (aThaw) {
1279 inner->Thaw(false);
1280 } else {
1281 inner->Freeze(false);
1282 }
1283 }
1284}
1285
1286void nsDocShell::FirePageHideShowNonRecursive(bool aShow) {
1287 MOZ_ASSERT(mozilla::BFCacheInParent())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mozilla::BFCacheInParent())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mozilla::BFCacheInParent()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mozilla::BFCacheInParent()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1287); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::BFCacheInParent()"
")"); do { *((volatile int*)__null) = 1287; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1288
1289 if (!mDocumentViewer) {
1290 return;
1291 }
1292
1293 // Emulate what non-SHIP BFCache does too. In pageshow case
1294 // add and remove a request and before that call SetCurrentURI to get
1295 // the location change notification.
1296 // For pagehide, set mFiredUnloadEvent to true, so that unload doesn't fire.
1297 nsCOMPtr<nsIDocumentViewer> viewer(mDocumentViewer);
1298 if (aShow) {
1299 viewer->SetIsHidden(false);
1300 mRefreshURIList = std::move(mBFCachedRefreshURIList);
1301 RefreshURIFromQueue();
1302 mFiredUnloadEvent = false;
1303 RefPtr<Document> doc = viewer->GetDocument();
1304 if (doc) {
1305 doc->NotifyActivityChanged();
1306 nsCOMPtr<nsPIDOMWindowInner> inner =
1307 mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindow() : nullptr;
1308 if (mBrowsingContext->IsTop()) {
1309 doc->NotifyPossibleTitleChange(false);
1310 doc->SetLoadingOrRestoredFromBFCacheTimeStampToNow();
1311 if (inner) {
1312 // Now that we have found the inner window of the page restored
1313 // from the history, we have to make sure that
1314 // performance.navigation.type is 2.
1315 // Traditionally this type change has been done to the top level page
1316 // only.
1317 Performance* performance = inner->GetPerformance();
1318 if (performance) {
1319 performance->GetDOMTiming()->NotifyRestoreStart();
1320 }
1321 }
1322 }
1323
1324 nsCOMPtr<nsIChannel> channel = doc->GetChannel();
1325 if (channel) {
1326 SetLoadType(LOAD_HISTORY);
1327 mEODForCurrentDocument = false;
1328 mIsRestoringDocument = true;
1329 mLoadGroup->AddRequest(channel, nullptr);
1330 SetCurrentURI(doc->GetDocumentURI(), channel,
1331 /* aFireOnLocationChange */ true,
1332 /* aIsInitialAboutBlank */ false,
1333 /* aLocationFlags */ 0);
1334 mLoadGroup->RemoveRequest(channel, nullptr, NS_OK);
1335 mIsRestoringDocument = false;
1336 }
1337 RefPtr<PresShell> presShell = GetPresShell();
1338 if (presShell) {
1339 presShell->Thaw(false);
1340 }
1341
1342 if (inner) {
1343 inner->FireDelayedDOMEvents(false);
1344 }
1345 }
1346 } else if (!mFiredUnloadEvent) {
1347 // XXXBFCache check again that the page can enter bfcache.
1348 // XXXBFCache should mTiming->NotifyUnloadEventStart()/End() be called here?
1349
1350 if (mRefreshURIList) {
1351 RefreshURIToQueue();
1352 mBFCachedRefreshURIList = std::move(mRefreshURIList);
1353 } else {
1354 // If Stop was called, the list was moved to mSavedRefreshURIList after
1355 // calling SuspendRefreshURIs, which calls RefreshURIToQueue.
1356 mBFCachedRefreshURIList = std::move(mSavedRefreshURIList);
1357 }
1358
1359 mFiredUnloadEvent = true;
1360 viewer->PageHide(false);
1361
1362 RefPtr<PresShell> presShell = GetPresShell();
1363 if (presShell) {
1364 presShell->Freeze(false);
1365 }
1366 }
1367}
1368
1369nsresult nsDocShell::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable) {
1370 nsCOMPtr<nsIRunnable> runnable(aRunnable);
1371 if (NS_WARN_IF(!GetWindow())NS_warn_if_impl(!GetWindow(), "!GetWindow()", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1371)
) {
1372 // Window should only be unavailable after destroyed.
1373 MOZ_ASSERT(mIsBeingDestroyed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mIsBeingDestroyed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mIsBeingDestroyed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mIsBeingDestroyed"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1373); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIsBeingDestroyed"
")"); do { *((volatile int*)__null) = 1373; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1374 return NS_ERROR_FAILURE;
1375 }
1376 return SchedulerGroup::Dispatch(runnable.forget());
1377}
1378
1379NS_IMETHODIMPnsresult
1380nsDocShell::DispatchLocationChangeEvent() {
1381 return Dispatch(NewRunnableMethod("nsDocShell::FireDummyOnLocationChange",
1382 this,
1383 &nsDocShell::FireDummyOnLocationChange));
1384}
1385
1386NS_IMETHODIMPnsresult
1387nsDocShell::StartDelayedAutoplayMediaComponents() {
1388 RefPtr<nsPIDOMWindowOuter> outerWindow = GetWindow();
1389 if (outerWindow) {
1390 outerWindow->ActivateMediaComponents();
1391 }
1392 return NS_OK;
1393}
1394
1395bool nsDocShell::MaybeInitTiming() {
1396 if (mTiming && !mBlankTiming) {
1397 return false;
1398 }
1399
1400 bool canBeReset = false;
1401
1402 if (mScriptGlobal && mBlankTiming) {
1403 nsPIDOMWindowInner* innerWin = mScriptGlobal->GetCurrentInnerWindow();
1404 if (innerWin && innerWin->GetPerformance()) {
1405 mTiming = innerWin->GetPerformance()->GetDOMTiming();
1406 mBlankTiming = false;
1407 }
1408 }
1409
1410 if (!mTiming) {
1411 mTiming = new nsDOMNavigationTiming(this);
1412 canBeReset = true;
1413 }
1414
1415 mTiming->NotifyNavigationStart(
1416 mBrowsingContext->IsActive()
1417 ? nsDOMNavigationTiming::DocShellState::eActive
1418 : nsDOMNavigationTiming::DocShellState::eInactive);
1419
1420 return canBeReset;
1421}
1422
1423void nsDocShell::MaybeResetInitTiming(bool aReset) {
1424 if (aReset) {
1425 mTiming = nullptr;
1426 }
1427}
1428
1429nsDOMNavigationTiming* nsDocShell::GetNavigationTiming() const {
1430 return mTiming;
1431}
1432
1433nsPresContext* nsDocShell::GetEldestPresContext() {
1434 nsIDocumentViewer* viewer = mDocumentViewer;
1435 while (viewer) {
1436 nsIDocumentViewer* prevViewer = viewer->GetPreviousViewer();
1437 if (!prevViewer) {
1438 return viewer->GetPresContext();
1439 }
1440 viewer = prevViewer;
1441 }
1442
1443 return nullptr;
1444}
1445
1446nsPresContext* nsDocShell::GetPresContext() {
1447 if (!mDocumentViewer) {
1448 return nullptr;
1449 }
1450
1451 return mDocumentViewer->GetPresContext();
1452}
1453
1454PresShell* nsDocShell::GetPresShell() {
1455 nsPresContext* presContext = GetPresContext();
1456 return presContext ? presContext->GetPresShell() : nullptr;
1457}
1458
1459PresShell* nsDocShell::GetEldestPresShell() {
1460 nsPresContext* presContext = GetEldestPresContext();
1461
1462 if (presContext) {
1463 return presContext->GetPresShell();
1464 }
1465
1466 return nullptr;
1467}
1468
1469NS_IMETHODIMPnsresult
1470nsDocShell::GetDocViewer(nsIDocumentViewer** aDocumentViewer) {
1471 NS_ENSURE_ARG_POINTER(aDocumentViewer)do { if ((__builtin_expect(!!(!(aDocumentViewer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDocumentViewer" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1471); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1472
1473 *aDocumentViewer = mDocumentViewer;
1474 NS_IF_ADDREF(*aDocumentViewer)ns_if_addref(*aDocumentViewer);
1475 return NS_OK;
1476}
1477
1478NS_IMETHODIMPnsresult
1479nsDocShell::GetOuterWindowID(uint64_t* aWindowID) {
1480 *aWindowID = mContentWindowID;
1481 return NS_OK;
1482}
1483
1484NS_IMETHODIMPnsresult
1485nsDocShell::SetChromeEventHandler(EventTarget* aChromeEventHandler) {
1486 mChromeEventHandler = aChromeEventHandler;
1487
1488 if (mScriptGlobal) {
1489 mScriptGlobal->SetChromeEventHandler(mChromeEventHandler);
1490 }
1491
1492 return NS_OK;
1493}
1494
1495NS_IMETHODIMPnsresult
1496nsDocShell::GetChromeEventHandler(EventTarget** aChromeEventHandler) {
1497 NS_ENSURE_ARG_POINTER(aChromeEventHandler)do { if ((__builtin_expect(!!(!(aChromeEventHandler)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChromeEventHandler"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1497); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1498 RefPtr<EventTarget> handler = mChromeEventHandler;
1499 handler.forget(aChromeEventHandler);
1500 return NS_OK;
1501}
1502
1503NS_IMETHODIMPnsresult
1504nsDocShell::SetCurrentURIForSessionStore(nsIURI* aURI) {
1505 // Note that securityUI will set STATE_IS_INSECURE, even if
1506 // the scheme of |aURI| is "https".
1507 SetCurrentURI(aURI, nullptr,
1508 /* aFireOnLocationChange */
1509 true,
1510 /* aIsInitialAboutBlank */
1511 false,
1512 /* aLocationFlags */
1513 nsIWebProgressListener::LOCATION_CHANGE_SESSION_STORE);
1514 return NS_OK;
1515}
1516
1517bool nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest,
1518 bool aFireOnLocationChange,
1519 bool aIsInitialAboutBlank,
1520 uint32_t aLocationFlags) {
1521 MOZ_ASSERT(!mIsBeingDestroyed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIsBeingDestroyed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIsBeingDestroyed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mIsBeingDestroyed"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1521); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIsBeingDestroyed"
")"); do { *((volatile int*)__null) = 1521; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1522
1523 MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p SetCurrentURI %s\n", this, aURI
? aURI->GetSpecOrDefault().get() : ""); } } while (0)
1524 ("DOCSHELL %p SetCurrentURI %s\n", this,do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p SetCurrentURI %s\n", this, aURI
? aURI->GetSpecOrDefault().get() : ""); } } while (0)
1525 aURI ? aURI->GetSpecOrDefault().get() : ""))do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p SetCurrentURI %s\n", this, aURI
? aURI->GetSpecOrDefault().get() : ""); } } while (0)
;
1526
1527 // We don't want to send a location change when we're displaying an error
1528 // page, and we don't want to change our idea of "current URI" either
1529 if (mLoadType == LOAD_ERROR_PAGE) {
1530 return false;
1531 }
1532
1533 bool uriIsEqual = false;
1534 if (!mCurrentURI || !aURI ||
1535 NS_FAILED(mCurrentURI->Equals(aURI, &uriIsEqual))((bool)(__builtin_expect(!!(NS_FAILED_impl(mCurrentURI->Equals
(aURI, &uriIsEqual))), 0)))
|| !uriIsEqual) {
1536 mTitleValidForCurrentURI = false;
1537 }
1538
1539 SetCurrentURIInternal(aURI);
1540
1541#ifdef DEBUG1
1542 mLastOpenedURI = aURI;
1543#endif
1544
1545 if (!NS_IsAboutBlank(mCurrentURI)) {
1546 mHasLoadedNonBlankURI = true;
1547 }
1548
1549 // Don't fire onLocationChange when creating a subframe's initial about:blank
1550 // document, as this can happen when it's not safe for us to run script.
1551 if (aIsInitialAboutBlank && !mHasLoadedNonBlankURI &&
1552 !mBrowsingContext->IsTop()) {
1553 MOZ_ASSERT(!aRequest && aLocationFlags == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aRequest && aLocationFlags == 0)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!aRequest && aLocationFlags == 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!aRequest && aLocationFlags == 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1553); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aRequest && aLocationFlags == 0"
")"); do { *((volatile int*)__null) = 1553; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1554 return false;
1555 }
1556
1557 MOZ_ASSERT(nsContentUtils::IsSafeToRunScript())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nsContentUtils::IsSafeToRunScript())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nsContentUtils::IsSafeToRunScript
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("nsContentUtils::IsSafeToRunScript()", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1557); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nsContentUtils::IsSafeToRunScript()"
")"); do { *((volatile int*)__null) = 1557; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1558
1559 if (aFireOnLocationChange) {
1560 FireOnLocationChange(this, aRequest, aURI, aLocationFlags);
1561 }
1562 return !aFireOnLocationChange;
1563}
1564
1565void nsDocShell::SetCurrentURIInternal(nsIURI* aURI) {
1566 mCurrentURI = aURI;
1567 if (mBrowsingContext) {
1568 mBrowsingContext->ClearCachedValuesOfLocations();
1569 }
1570}
1571
1572NS_IMETHODIMPnsresult
1573nsDocShell::GetCharset(nsACString& aCharset) {
1574 aCharset.Truncate();
1575
1576 PresShell* presShell = GetPresShell();
1577 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(presShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "presShell" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1577); return NS_ERROR_FAILURE; } } while (false)
;
1578 Document* doc = presShell->GetDocument();
1579 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(doc)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "doc" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1579); return NS_ERROR_FAILURE; } } while (false)
;
1580 doc->GetDocumentCharacterSet()->Name(aCharset);
1581 return NS_OK;
1582}
1583
1584NS_IMETHODIMPnsresult
1585nsDocShell::ForceEncodingDetection() {
1586 nsCOMPtr<nsIDocumentViewer> viewer;
1587 GetDocViewer(getter_AddRefs(viewer));
1588 if (!viewer) {
1589 return NS_OK;
1590 }
1591
1592 Document* doc = viewer->GetDocument();
1593 if (!doc || doc->WillIgnoreCharsetOverride()) {
1594 return NS_OK;
1595 }
1596
1597 mForcedAutodetection = true;
1598
1599 nsIURI* url = doc->GetOriginalURI();
1600 bool isFileURL = url && SchemeIsFile(url);
1601
1602 int32_t charsetSource = doc->GetDocumentCharacterSetSource();
1603 auto encoding = doc->GetDocumentCharacterSet();
1604 // AsHTMLDocument is valid, because we called
1605 // WillIgnoreCharsetOverride() above.
1606 if (doc->AsHTMLDocument()->IsPlainText()) {
1607 switch (charsetSource) {
1608 case kCharsetFromInitialAutoDetectionASCII:
1609 // Deliberately no final version
1610 LOGCHARSETMENU(("TEXT:UnlabeledAscii"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "TEXT:UnlabeledAscii"
); } } while (0)
;
1611 Telemetry::AccumulateCategorical(
1612 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_TEXT::UnlabeledAscii);
1613 break;
1614 case kCharsetFromInitialAutoDetectionWouldNotHaveBeenUTF8Generic:
1615 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8Generic:
1616 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8GenericInitialWasASCII:
1617 case kCharsetFromInitialAutoDetectionWouldNotHaveBeenUTF8Content:
1618 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8Content:
1619 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8ContentInitialWasASCII:
1620 LOGCHARSETMENU(("TEXT:UnlabeledNonUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "TEXT:UnlabeledNonUtf8"
); } } while (0)
;
1621 Telemetry::AccumulateCategorical(
1622 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_TEXT::
1623 UnlabeledNonUtf8);
1624 break;
1625 case kCharsetFromInitialAutoDetectionWouldNotHaveBeenUTF8DependedOnTLD:
1626 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLD:
1627 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII:
1628 LOGCHARSETMENU(("TEXT:UnlabeledNonUtf8TLD"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "TEXT:UnlabeledNonUtf8TLD"
); } } while (0)
;
1629 Telemetry::AccumulateCategorical(
1630 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_TEXT::
1631 UnlabeledNonUtf8TLD);
1632 break;
1633 case kCharsetFromInitialAutoDetectionWouldHaveBeenUTF8:
1634 case kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII:
1635 LOGCHARSETMENU(("TEXT:UnlabeledUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "TEXT:UnlabeledUtf8"
); } } while (0)
;
1636 Telemetry::AccumulateCategorical(
1637 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_TEXT::UnlabeledUtf8);
1638 break;
1639 case kCharsetFromChannel:
1640 if (encoding == UTF_8_ENCODING) {
1641 LOGCHARSETMENU(("TEXT:ChannelUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "TEXT:ChannelUtf8"
); } } while (0)
;
1642 Telemetry::AccumulateCategorical(
1643 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_TEXT::ChannelUtf8);
1644 } else {
1645 LOGCHARSETMENU(("TEXT:ChannelNonUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "TEXT:ChannelNonUtf8"
); } } while (0)
;
1646 Telemetry::AccumulateCategorical(
1647 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_TEXT::
1648 ChannelNonUtf8);
1649 }
1650 break;
1651 default:
1652 LOGCHARSETMENU(("TEXT:Bug"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "TEXT:Bug"); } } while
(0)
;
1653 Telemetry::AccumulateCategorical(
1654 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_TEXT::Bug);
1655 break;
1656 }
1657 } else {
1658 switch (charsetSource) {
1659 case kCharsetFromInitialAutoDetectionASCII:
1660 // Deliberately no final version
1661 LOGCHARSETMENU(("HTML:UnlabeledAscii"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:UnlabeledAscii"
); } } while (0)
;
1662 Telemetry::AccumulateCategorical(
1663 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::UnlabeledAscii);
1664 break;
1665 case kCharsetFromInitialAutoDetectionWouldNotHaveBeenUTF8Generic:
1666 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8Generic:
1667 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8GenericInitialWasASCII:
1668 case kCharsetFromInitialAutoDetectionWouldNotHaveBeenUTF8Content:
1669 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8Content:
1670 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8ContentInitialWasASCII:
1671 LOGCHARSETMENU(("HTML:UnlabeledNonUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:UnlabeledNonUtf8"
); } } while (0)
;
1672 Telemetry::AccumulateCategorical(
1673 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::
1674 UnlabeledNonUtf8);
1675 break;
1676 case kCharsetFromInitialAutoDetectionWouldNotHaveBeenUTF8DependedOnTLD:
1677 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLD:
1678 case kCharsetFromFinalAutoDetectionWouldNotHaveBeenUTF8DependedOnTLDInitialWasASCII:
1679 LOGCHARSETMENU(("HTML:UnlabeledNonUtf8TLD"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:UnlabeledNonUtf8TLD"
); } } while (0)
;
1680 Telemetry::AccumulateCategorical(
1681 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::
1682 UnlabeledNonUtf8TLD);
1683 break;
1684 case kCharsetFromInitialAutoDetectionWouldHaveBeenUTF8:
1685 case kCharsetFromFinalAutoDetectionWouldHaveBeenUTF8InitialWasASCII:
1686 LOGCHARSETMENU(("HTML:UnlabeledUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:UnlabeledUtf8"
); } } while (0)
;
1687 Telemetry::AccumulateCategorical(
1688 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::UnlabeledUtf8);
1689 break;
1690 case kCharsetFromChannel:
1691 if (encoding == UTF_8_ENCODING) {
1692 LOGCHARSETMENU(("HTML:ChannelUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:ChannelUtf8"
); } } while (0)
;
1693 Telemetry::AccumulateCategorical(
1694 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::ChannelUtf8);
1695 } else {
1696 LOGCHARSETMENU(("HTML:ChannelNonUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:ChannelNonUtf8"
); } } while (0)
;
1697 Telemetry::AccumulateCategorical(
1698 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::
1699 ChannelNonUtf8);
1700 }
1701 break;
1702 case kCharsetFromXmlDeclaration:
1703 case kCharsetFromMetaTag:
1704 if (isFileURL) {
1705 LOGCHARSETMENU(("HTML:LocalLabeled"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:LocalLabeled"
); } } while (0)
;
1706 Telemetry::AccumulateCategorical(
1707 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::LocalLabeled);
1708 } else if (encoding == UTF_8_ENCODING) {
1709 LOGCHARSETMENU(("HTML:MetaUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:MetaUtf8");
} } while (0)
;
1710 Telemetry::AccumulateCategorical(
1711 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::InternalUtf8);
1712 } else {
1713 LOGCHARSETMENU(("HTML:MetaNonUtf8"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:MetaNonUtf8"
); } } while (0)
;
1714 Telemetry::AccumulateCategorical(
1715 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::
1716 InternalNonUtf8);
1717 }
1718 break;
1719 default:
1720 LOGCHARSETMENU(("HTML:Bug"))do { const ::mozilla::LogModule* moz_real_module = gCharsetMenuLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "HTML:Bug"); } } while
(0)
;
1721 Telemetry::AccumulateCategorical(
1722 Telemetry::LABELS_ENCODING_OVERRIDE_SITUATION_HTML::Bug);
1723 break;
1724 }
1725 }
1726 return NS_OK;
1727}
1728
1729void nsDocShell::SetParentCharset(const Encoding*& aCharset,
1730 int32_t aCharsetSource,
1731 nsIPrincipal* aPrincipal) {
1732 mParentCharset = aCharset;
1733 mParentCharsetSource = aCharsetSource;
1734 mParentCharsetPrincipal = aPrincipal;
1735}
1736
1737void nsDocShell::GetParentCharset(const Encoding*& aCharset,
1738 int32_t* aCharsetSource,
1739 nsIPrincipal** aPrincipal) {
1740 aCharset = mParentCharset;
1741 *aCharsetSource = mParentCharsetSource;
1742 NS_IF_ADDREF(*aPrincipal = mParentCharsetPrincipal)ns_if_addref(*aPrincipal = mParentCharsetPrincipal);
1743}
1744
1745NS_IMETHODIMPnsresult
1746nsDocShell::GetHasTrackingContentBlocked(Promise** aPromise) {
1747 MOZ_ASSERT(aPromise)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPromise)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPromise))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aPromise", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1747); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPromise" ")"
); do { *((volatile int*)__null) = 1747; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1748
1749 ErrorResult rv;
1750 RefPtr<Document> doc(GetDocument());
1751 RefPtr<Promise> retPromise = Promise::Create(doc->GetOwnerGlobal(), rv);
1752 if (NS_WARN_IF(rv.Failed())NS_warn_if_impl(rv.Failed(), "rv.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1752)
) {
1753 return rv.StealNSResult();
1754 }
1755
1756 // Retrieve the document's content blocking events from the parent process.
1757 RefPtr<Document::GetContentBlockingEventsPromise> promise =
1758 doc->GetContentBlockingEvents();
1759 if (promise) {
1760 promise->Then(
1761 GetCurrentSerialEventTarget(), __func__,
1762 [retPromise](const Document::GetContentBlockingEventsPromise::
1763 ResolveOrRejectValue& aValue) {
1764 if (aValue.IsResolve()) {
1765 bool has = aValue.ResolveValue() &
1766 nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
1767 retPromise->MaybeResolve(has);
1768 } else {
1769 retPromise->MaybeResolve(false);
1770 }
1771 });
1772 } else {
1773 retPromise->MaybeResolve(false);
1774 }
1775
1776 retPromise.forget(aPromise);
1777 return NS_OK;
1778}
1779
1780NS_IMETHODIMPnsresult
1781nsDocShell::GetCssErrorReportingEnabled(bool* aEnabled) {
1782 MOZ_ASSERT(aEnabled)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aEnabled)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aEnabled))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aEnabled", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1782); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aEnabled" ")"
); do { *((volatile int*)__null) = 1782; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1783 *aEnabled = mCSSErrorReportingEnabled;
1784 return NS_OK;
1785}
1786
1787NS_IMETHODIMPnsresult
1788nsDocShell::SetCssErrorReportingEnabled(bool aEnabled) {
1789 mCSSErrorReportingEnabled = aEnabled;
1790 return NS_OK;
1791}
1792
1793NS_IMETHODIMPnsresult
1794nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
1795 NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing)do { if ((__builtin_expect(!!(!(aUsePrivateBrowsing)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aUsePrivateBrowsing"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1795); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1796 return mBrowsingContext->GetUsePrivateBrowsing(aUsePrivateBrowsing);
1797}
1798
1799void nsDocShell::NotifyPrivateBrowsingChanged() {
1800 MOZ_ASSERT(!mIsBeingDestroyed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIsBeingDestroyed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIsBeingDestroyed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mIsBeingDestroyed"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1800); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIsBeingDestroyed"
")"); do { *((volatile int*)__null) = 1800; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1801
1802 nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers);
1803 while (iter.HasMore()) {
1804 nsWeakPtr ref = iter.GetNext();
1805 nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref);
1806 if (!obs) {
1807 iter.Remove();
1808 } else {
1809 obs->PrivateModeChanged(UsePrivateBrowsing());
1810 }
1811 }
1812}
1813
1814NS_IMETHODIMPnsresult
1815nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) {
1816 return mBrowsingContext->SetUsePrivateBrowsing(aUsePrivateBrowsing);
1817}
1818
1819NS_IMETHODIMPnsresult
1820nsDocShell::SetPrivateBrowsing(bool aUsePrivateBrowsing) {
1821 return mBrowsingContext->SetPrivateBrowsing(aUsePrivateBrowsing);
1822}
1823
1824NS_IMETHODIMPnsresult
1825nsDocShell::GetHasLoadedNonBlankURI(bool* aResult) {
1826 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1826); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1827
1828 *aResult = mHasLoadedNonBlankURI;
1829 return NS_OK;
1830}
1831
1832NS_IMETHODIMPnsresult
1833nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs) {
1834 NS_ENSURE_ARG_POINTER(aUseRemoteTabs)do { if ((__builtin_expect(!!(!(aUseRemoteTabs)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aUseRemoteTabs" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1834); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1835 return mBrowsingContext->GetUseRemoteTabs(aUseRemoteTabs);
1836}
1837
1838NS_IMETHODIMPnsresult
1839nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) {
1840 return mBrowsingContext->SetRemoteTabs(aUseRemoteTabs);
1841}
1842
1843NS_IMETHODIMPnsresult
1844nsDocShell::GetUseRemoteSubframes(bool* aUseRemoteSubframes) {
1845 NS_ENSURE_ARG_POINTER(aUseRemoteSubframes)do { if ((__builtin_expect(!!(!(aUseRemoteSubframes)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aUseRemoteSubframes"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1845); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1846 return mBrowsingContext->GetUseRemoteSubframes(aUseRemoteSubframes);
1847}
1848
1849NS_IMETHODIMPnsresult
1850nsDocShell::SetRemoteSubframes(bool aUseRemoteSubframes) {
1851 return mBrowsingContext->SetRemoteSubframes(aUseRemoteSubframes);
1852}
1853
1854NS_IMETHODIMPnsresult
1855nsDocShell::AddWeakPrivacyTransitionObserver(
1856 nsIPrivacyTransitionObserver* aObserver) {
1857 nsWeakPtr weakObs = do_GetWeakReference(aObserver);
1858 if (!weakObs) {
1859 return NS_ERROR_NOT_AVAILABLE;
1860 }
1861 mPrivacyObservers.AppendElement(weakObs);
1862 return NS_OK;
1863}
1864
1865NS_IMETHODIMPnsresult
1866nsDocShell::AddWeakReflowObserver(nsIReflowObserver* aObserver) {
1867 nsWeakPtr weakObs = do_GetWeakReference(aObserver);
1868 if (!weakObs) {
1869 return NS_ERROR_FAILURE;
1870 }
1871 mReflowObservers.AppendElement(weakObs);
1872 return NS_OK;
1873}
1874
1875NS_IMETHODIMPnsresult
1876nsDocShell::RemoveWeakReflowObserver(nsIReflowObserver* aObserver) {
1877 nsWeakPtr obs = do_GetWeakReference(aObserver);
1878 return mReflowObservers.RemoveElement(obs) ? NS_OK : NS_ERROR_FAILURE;
1879}
1880
1881NS_IMETHODIMPnsresult
1882nsDocShell::NotifyReflowObservers(bool aInterruptible,
1883 DOMHighResTimeStamp aStart,
1884 DOMHighResTimeStamp aEnd) {
1885 nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mReflowObservers);
1886 while (iter.HasMore()) {
1887 nsWeakPtr ref = iter.GetNext();
1888 nsCOMPtr<nsIReflowObserver> obs = do_QueryReferent(ref);
1889 if (!obs) {
1890 iter.Remove();
1891 } else if (aInterruptible) {
1892 obs->ReflowInterruptible(aStart, aEnd);
1893 } else {
1894 obs->Reflow(aStart, aEnd);
1895 }
1896 }
1897 return NS_OK;
1898}
1899
1900NS_IMETHODIMPnsresult
1901nsDocShell::GetAllowMetaRedirects(bool* aReturn) {
1902 NS_ENSURE_ARG_POINTER(aReturn)do { if ((__builtin_expect(!!(!(aReturn)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aReturn" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1902); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1903
1904 *aReturn = mAllowMetaRedirects;
1905 return NS_OK;
1906}
1907
1908NS_IMETHODIMPnsresult
1909nsDocShell::SetAllowMetaRedirects(bool aValue) {
1910 mAllowMetaRedirects = aValue;
1911 return NS_OK;
1912}
1913
1914NS_IMETHODIMPnsresult
1915nsDocShell::GetAllowSubframes(bool* aAllowSubframes) {
1916 NS_ENSURE_ARG_POINTER(aAllowSubframes)do { if ((__builtin_expect(!!(!(aAllowSubframes)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowSubframes" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1916); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1917
1918 *aAllowSubframes = mAllowSubframes;
1919 return NS_OK;
1920}
1921
1922NS_IMETHODIMPnsresult
1923nsDocShell::SetAllowSubframes(bool aAllowSubframes) {
1924 mAllowSubframes = aAllowSubframes;
1925 return NS_OK;
1926}
1927
1928NS_IMETHODIMPnsresult
1929nsDocShell::GetAllowImages(bool* aAllowImages) {
1930 NS_ENSURE_ARG_POINTER(aAllowImages)do { if ((__builtin_expect(!!(!(aAllowImages)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowImages" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 1930); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1931
1932 *aAllowImages = mAllowImages;
1933 return NS_OK;
1934}
1935
1936NS_IMETHODIMPnsresult
1937nsDocShell::SetAllowImages(bool aAllowImages) {
1938 mAllowImages = aAllowImages;
1939 return NS_OK;
1940}
1941
1942NS_IMETHODIMPnsresult
1943nsDocShell::GetAllowMedia(bool* aAllowMedia) {
1944 *aAllowMedia = mAllowMedia;
1945 return NS_OK;
1946}
1947
1948NS_IMETHODIMPnsresult
1949nsDocShell::SetAllowMedia(bool aAllowMedia) {
1950 mAllowMedia = aAllowMedia;
1951
1952 // Mute or unmute audio contexts attached to the inner window.
1953 if (mScriptGlobal) {
1954 if (nsPIDOMWindowInner* innerWin = mScriptGlobal->GetCurrentInnerWindow()) {
1955 if (aAllowMedia) {
1956 innerWin->UnmuteAudioContexts();
1957 } else {
1958 innerWin->MuteAudioContexts();
1959 }
1960 }
1961 }
1962
1963 return NS_OK;
1964}
1965
1966NS_IMETHODIMPnsresult
1967nsDocShell::GetAllowDNSPrefetch(bool* aAllowDNSPrefetch) {
1968 *aAllowDNSPrefetch = mAllowDNSPrefetch;
1969 return NS_OK;
1970}
1971
1972NS_IMETHODIMPnsresult
1973nsDocShell::SetAllowDNSPrefetch(bool aAllowDNSPrefetch) {
1974 mAllowDNSPrefetch = aAllowDNSPrefetch;
1975 return NS_OK;
1976}
1977
1978NS_IMETHODIMPnsresult
1979nsDocShell::GetAllowWindowControl(bool* aAllowWindowControl) {
1980 *aAllowWindowControl = mAllowWindowControl;
1981 return NS_OK;
1982}
1983
1984NS_IMETHODIMPnsresult
1985nsDocShell::SetAllowWindowControl(bool aAllowWindowControl) {
1986 mAllowWindowControl = aAllowWindowControl;
1987 return NS_OK;
1988}
1989
1990NS_IMETHODIMPnsresult
1991nsDocShell::GetAllowContentRetargeting(bool* aAllowContentRetargeting) {
1992 *aAllowContentRetargeting = mBrowsingContext->GetAllowContentRetargeting();
1993 return NS_OK;
1994}
1995
1996NS_IMETHODIMPnsresult
1997nsDocShell::SetAllowContentRetargeting(bool aAllowContentRetargeting) {
1998 BrowsingContext::Transaction txn;
1999 txn.SetAllowContentRetargeting(aAllowContentRetargeting);
2000 txn.SetAllowContentRetargetingOnChildren(aAllowContentRetargeting);
2001 return txn.Commit(mBrowsingContext);
2002}
2003
2004NS_IMETHODIMPnsresult
2005nsDocShell::GetAllowContentRetargetingOnChildren(
2006 bool* aAllowContentRetargetingOnChildren) {
2007 *aAllowContentRetargetingOnChildren =
2008 mBrowsingContext->GetAllowContentRetargetingOnChildren();
2009 return NS_OK;
2010}
2011
2012NS_IMETHODIMPnsresult
2013nsDocShell::SetAllowContentRetargetingOnChildren(
2014 bool aAllowContentRetargetingOnChildren) {
2015 return mBrowsingContext->SetAllowContentRetargetingOnChildren(
2016 aAllowContentRetargetingOnChildren);
2017}
2018
2019NS_IMETHODIMPnsresult
2020nsDocShell::GetMayEnableCharacterEncodingMenu(
2021 bool* aMayEnableCharacterEncodingMenu) {
2022 *aMayEnableCharacterEncodingMenu = false;
2023 if (!mDocumentViewer) {
2024 return NS_OK;
2025 }
2026 Document* doc = mDocumentViewer->GetDocument();
2027 if (!doc) {
2028 return NS_OK;
2029 }
2030 if (doc->WillIgnoreCharsetOverride()) {
2031 return NS_OK;
2032 }
2033
2034 *aMayEnableCharacterEncodingMenu = true;
2035 return NS_OK;
2036}
2037
2038NS_IMETHODIMPnsresult
2039nsDocShell::GetAllDocShellsInSubtree(int32_t aItemType,
2040 DocShellEnumeratorDirection aDirection,
2041 nsTArray<RefPtr<nsIDocShell>>& aResult) {
2042 aResult.Clear();
2043
2044 nsDocShellEnumerator docShellEnum(
2045 (aDirection == ENUMERATE_FORWARDS)
2046 ? nsDocShellEnumerator::EnumerationDirection::Forwards
2047 : nsDocShellEnumerator::EnumerationDirection::Backwards,
2048 aItemType, *this);
2049
2050 nsresult rv = docShellEnum.BuildDocShellArray(aResult);
2051 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2052 return rv;
2053 }
2054
2055 return NS_OK;
2056}
2057
2058NS_IMETHODIMPnsresult
2059nsDocShell::GetAppType(AppType* aAppType) {
2060 *aAppType = mAppType;
2061 return NS_OK;
2062}
2063
2064NS_IMETHODIMPnsresult
2065nsDocShell::SetAppType(AppType aAppType) {
2066 mAppType = aAppType;
2067 return NS_OK;
2068}
2069
2070NS_IMETHODIMPnsresult
2071nsDocShell::GetAllowAuth(bool* aAllowAuth) {
2072 *aAllowAuth = mAllowAuth;
2073 return NS_OK;
2074}
2075
2076NS_IMETHODIMPnsresult
2077nsDocShell::SetAllowAuth(bool aAllowAuth) {
2078 mAllowAuth = aAllowAuth;
2079 return NS_OK;
2080}
2081
2082NS_IMETHODIMPnsresult
2083nsDocShell::GetZoom(float* aZoom) {
2084 NS_ENSURE_ARG_POINTER(aZoom)do { if ((__builtin_expect(!!(!(aZoom)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aZoom" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2084); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2085 *aZoom = 1.0f;
2086 return NS_OK;
2087}
2088
2089NS_IMETHODIMPnsresult
2090nsDocShell::SetZoom(float aZoom) { return NS_ERROR_NOT_IMPLEMENTED; }
2091
2092NS_IMETHODIMPnsresult
2093nsDocShell::GetBusyFlags(BusyFlags* aBusyFlags) {
2094 NS_ENSURE_ARG_POINTER(aBusyFlags)do { if ((__builtin_expect(!!(!(aBusyFlags)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aBusyFlags" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2094); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2095
2096 *aBusyFlags = mBusyFlags;
2097 return NS_OK;
2098}
2099
2100NS_IMETHODIMPnsresult
2101nsDocShell::GetLoadURIDelegate(nsILoadURIDelegate** aLoadURIDelegate) {
2102 nsCOMPtr<nsILoadURIDelegate> delegate = GetLoadURIDelegate();
2103 delegate.forget(aLoadURIDelegate);
2104 return NS_OK;
2105}
2106
2107already_AddRefed<nsILoadURIDelegate> nsDocShell::GetLoadURIDelegate() {
2108 if (nsCOMPtr<nsILoadURIDelegate> result =
2109 do_QueryActor("LoadURIDelegate", GetDocument())) {
2110 return result.forget();
2111 }
2112
2113 return nullptr;
2114}
2115
2116NS_IMETHODIMPnsresult
2117nsDocShell::GetUseErrorPages(bool* aUseErrorPages) {
2118 *aUseErrorPages = mBrowsingContext->GetUseErrorPages();
2119 return NS_OK;
2120}
2121
2122NS_IMETHODIMPnsresult
2123nsDocShell::SetUseErrorPages(bool aUseErrorPages) {
2124 return mBrowsingContext->SetUseErrorPages(aUseErrorPages);
2125}
2126
2127NS_IMETHODIMPnsresult
2128nsDocShell::GetPreviousEntryIndex(int32_t* aPreviousEntryIndex) {
2129 *aPreviousEntryIndex = mPreviousEntryIndex;
2130 return NS_OK;
2131}
2132
2133NS_IMETHODIMPnsresult
2134nsDocShell::GetLoadedEntryIndex(int32_t* aLoadedEntryIndex) {
2135 *aLoadedEntryIndex = mLoadedEntryIndex;
2136 return NS_OK;
2137}
2138
2139NS_IMETHODIMPnsresult
2140nsDocShell::HistoryPurged(int32_t aNumEntries) {
2141 // These indices are used for fastback cache eviction, to determine
2142 // which session history entries are candidates for content viewer
2143 // eviction. We need to adjust by the number of entries that we
2144 // just purged from history, so that we look at the right session history
2145 // entries during eviction.
2146 mPreviousEntryIndex = std::max(-1, mPreviousEntryIndex - aNumEntries);
2147 mLoadedEntryIndex = std::max(0, mLoadedEntryIndex - aNumEntries);
2148
2149 for (auto* child : mChildList.ForwardRange()) {
2150 nsCOMPtr<nsIDocShell> shell = do_QueryObject(child);
2151 if (shell) {
2152 shell->HistoryPurged(aNumEntries);
2153 }
2154 }
2155
2156 return NS_OK;
2157}
2158
2159nsresult nsDocShell::HistoryEntryRemoved(int32_t aIndex) {
2160 // These indices are used for fastback cache eviction, to determine
2161 // which session history entries are candidates for content viewer
2162 // eviction. We need to adjust by the number of entries that we
2163 // just purged from history, so that we look at the right session history
2164 // entries during eviction.
2165 if (aIndex == mPreviousEntryIndex) {
2166 mPreviousEntryIndex = -1;
2167 } else if (aIndex < mPreviousEntryIndex) {
2168 --mPreviousEntryIndex;
2169 }
2170 if (mLoadedEntryIndex == aIndex) {
2171 mLoadedEntryIndex = 0;
2172 } else if (aIndex < mLoadedEntryIndex) {
2173 --mLoadedEntryIndex;
2174 }
2175
2176 for (auto* child : mChildList.ForwardRange()) {
2177 nsCOMPtr<nsIDocShell> shell = do_QueryObject(child);
2178 if (shell) {
2179 static_cast<nsDocShell*>(shell.get())->HistoryEntryRemoved(aIndex);
2180 }
2181 }
2182
2183 return NS_OK;
2184}
2185
2186nsresult nsDocShell::Now(DOMHighResTimeStamp* aWhen) {
2187 *aWhen = (TimeStamp::Now() - TimeStamp::ProcessCreation()).ToMilliseconds();
2188 return NS_OK;
2189}
2190
2191NS_IMETHODIMPnsresult
2192nsDocShell::SetWindowDraggingAllowed(bool aValue) {
2193 RefPtr<nsDocShell> parent = GetInProcessParentDocshell();
2194 if (!aValue && mItemType == typeChrome && !parent) {
2195 // Window dragging is always allowed for top level
2196 // chrome docshells.
2197 return NS_ERROR_FAILURE;
2198 }
2199 mWindowDraggingAllowed = aValue;
2200 return NS_OK;
2201}
2202
2203NS_IMETHODIMPnsresult
2204nsDocShell::GetWindowDraggingAllowed(bool* aValue) {
2205 // window dragging regions in CSS (-moz-window-drag:drag)
2206 // can be slow. Default behavior is to only allow it for
2207 // chrome top level windows.
2208 RefPtr<nsDocShell> parent = GetInProcessParentDocshell();
2209 if (mItemType == typeChrome && !parent) {
2210 // Top level chrome window
2211 *aValue = true;
2212 } else {
2213 *aValue = mWindowDraggingAllowed;
2214 }
2215 return NS_OK;
2216}
2217
2218NS_IMETHODIMPnsresult
2219nsDocShell::GetCurrentDocumentChannel(nsIChannel** aResult) {
2220 NS_IF_ADDREF(*aResult = GetCurrentDocChannel())ns_if_addref(*aResult = GetCurrentDocChannel());
2221 return NS_OK;
2222}
2223
2224nsIChannel* nsDocShell::GetCurrentDocChannel() {
2225 if (mDocumentViewer) {
2226 Document* doc = mDocumentViewer->GetDocument();
2227 if (doc) {
2228 return doc->GetChannel();
2229 }
2230 }
2231 return nullptr;
2232}
2233
2234NS_IMETHODIMPnsresult
2235nsDocShell::AddWeakScrollObserver(nsIScrollObserver* aObserver) {
2236 nsWeakPtr weakObs = do_GetWeakReference(aObserver);
2237 if (!weakObs) {
2238 return NS_ERROR_FAILURE;
2239 }
2240 mScrollObservers.AppendElement(weakObs);
2241 return NS_OK;
2242}
2243
2244NS_IMETHODIMPnsresult
2245nsDocShell::RemoveWeakScrollObserver(nsIScrollObserver* aObserver) {
2246 nsWeakPtr obs = do_GetWeakReference(aObserver);
2247 return mScrollObservers.RemoveElement(obs) ? NS_OK : NS_ERROR_FAILURE;
2248}
2249
2250void nsDocShell::NotifyAsyncPanZoomStarted() {
2251 nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers);
2252 while (iter.HasMore()) {
2253 nsWeakPtr ref = iter.GetNext();
2254 nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref);
2255 if (obs) {
2256 obs->AsyncPanZoomStarted();
2257 } else {
2258 iter.Remove();
2259 }
2260 }
2261}
2262
2263void nsDocShell::NotifyAsyncPanZoomStopped() {
2264 nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers);
2265 while (iter.HasMore()) {
2266 nsWeakPtr ref = iter.GetNext();
2267 nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref);
2268 if (obs) {
2269 obs->AsyncPanZoomStopped();
2270 } else {
2271 iter.Remove();
2272 }
2273 }
2274}
2275
2276NS_IMETHODIMPnsresult
2277nsDocShell::NotifyScrollObservers() {
2278 nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers);
2279 while (iter.HasMore()) {
2280 nsWeakPtr ref = iter.GetNext();
2281 nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref);
2282 if (obs) {
2283 obs->ScrollPositionChanged();
2284 } else {
2285 iter.Remove();
2286 }
2287 }
2288 return NS_OK;
2289}
2290
2291//*****************************************************************************
2292// nsDocShell::nsIDocShellTreeItem
2293//*****************************************************************************
2294
2295NS_IMETHODIMPnsresult
2296nsDocShell::GetName(nsAString& aName) {
2297 aName = mBrowsingContext->Name();
2298 return NS_OK;
2299}
2300
2301NS_IMETHODIMPnsresult
2302nsDocShell::SetName(const nsAString& aName) {
2303 return mBrowsingContext->SetName(aName);
2304}
2305
2306NS_IMETHODIMPnsresult
2307nsDocShell::NameEquals(const nsAString& aName, bool* aResult) {
2308 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2308); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2309 *aResult = mBrowsingContext->NameEquals(aName);
2310 return NS_OK;
2311}
2312
2313NS_IMETHODIMPnsresult
2314nsDocShell::GetCustomUserAgent(nsAString& aCustomUserAgent) {
2315 mBrowsingContext->GetCustomUserAgent(aCustomUserAgent);
2316 return NS_OK;
2317}
2318
2319NS_IMETHODIMPnsresult
2320nsDocShell::SetCustomUserAgent(const nsAString& aCustomUserAgent) {
2321 if (mWillChangeProcess) {
2322 NS_WARNING("SetCustomUserAgent: Process is changing. Ignoring set")NS_DebugBreak(NS_DEBUG_WARNING, "SetCustomUserAgent: Process is changing. Ignoring set"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2322)
;
2323 return NS_ERROR_FAILURE;
2324 }
2325
2326 return mBrowsingContext->SetCustomUserAgent(aCustomUserAgent);
2327}
2328
2329NS_IMETHODIMPnsresult
2330nsDocShell::ClearCachedPlatform() {
2331 nsCOMPtr<nsPIDOMWindowInner> win =
2332 mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindow() : nullptr;
2333 if (win) {
2334 Navigator* navigator = win->Navigator();
2335 if (navigator) {
2336 navigator->ClearPlatformCache();
2337 }
2338 }
2339
2340 return NS_OK;
2341}
2342
2343NS_IMETHODIMPnsresult
2344nsDocShell::ClearCachedUserAgent() {
2345 nsCOMPtr<nsPIDOMWindowInner> win =
2346 mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindow() : nullptr;
2347 if (win) {
2348 Navigator* navigator = win->Navigator();
2349 if (navigator) {
2350 navigator->ClearUserAgentCache();
2351 }
2352 }
2353
2354 return NS_OK;
2355}
2356
2357/* virtual */
2358int32_t nsDocShell::ItemType() { return mItemType; }
2359
2360NS_IMETHODIMPnsresult
2361nsDocShell::GetItemType(int32_t* aItemType) {
2362 NS_ENSURE_ARG_POINTER(aItemType)do { if ((__builtin_expect(!!(!(aItemType)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aItemType" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2362); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2363
2364 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype((mBrowsingContext->IsContent() ? typeContent : typeChrome
) == mItemType)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!((mBrowsingContext->IsContent
() ? typeContent : typeChrome) == mItemType))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("(mBrowsingContext->IsContent() ? typeContent : typeChrome) == mItemType"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2365); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "(mBrowsingContext->IsContent() ? typeContent : typeChrome) == mItemType"
")"); do { *((volatile int*)__null) = 2365; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2365 (mBrowsingContext->IsContent() ? typeContent : typeChrome) == mItemType)do { static_assert( mozilla::detail::AssertionConditionType<
decltype((mBrowsingContext->IsContent() ? typeContent : typeChrome
) == mItemType)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!((mBrowsingContext->IsContent
() ? typeContent : typeChrome) == mItemType))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("(mBrowsingContext->IsContent() ? typeContent : typeChrome) == mItemType"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2365); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "(mBrowsingContext->IsContent() ? typeContent : typeChrome) == mItemType"
")"); do { *((volatile int*)__null) = 2365; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2366 *aItemType = mItemType;
2367 return NS_OK;
2368}
2369
2370NS_IMETHODIMPnsresult
2371nsDocShell::GetInProcessParent(nsIDocShellTreeItem** aParent) {
2372 if (!mParent) {
2373 *aParent = nullptr;
2374 } else {
2375 CallQueryInterface(mParent, aParent);
2376 }
2377 // Note that in the case when the parent is not an nsIDocShellTreeItem we
2378 // don't want to throw; we just want to return null.
2379 return NS_OK;
2380}
2381
2382// With Fission, related nsDocShell objects may exist in a different process. In
2383// that case, this method will return `nullptr`, despite a parent nsDocShell
2384// object existing.
2385//
2386// Prefer using `BrowsingContext::Parent()`, which will succeed even if the
2387// parent entry is not in the current process, and handle the case where the
2388// parent nsDocShell is inaccessible.
2389already_AddRefed<nsDocShell> nsDocShell::GetInProcessParentDocshell() {
2390 nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(GetAsSupports(mParent));
2391 return docshell.forget().downcast<nsDocShell>();
2392}
2393
2394void nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal) {
2395 MOZ_ASSERT(!mIsBeingDestroyed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIsBeingDestroyed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIsBeingDestroyed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mIsBeingDestroyed"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2395); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIsBeingDestroyed"
")"); do { *((volatile int*)__null) = 2395; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2396
2397 // If there is an existing document then there is no need to create
2398 // a client for a future initial about:blank document.
2399 if (mScriptGlobal && mScriptGlobal->GetCurrentInnerWindow() &&
2400 mScriptGlobal->GetCurrentInnerWindow()->GetExtantDoc()) {
2401 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mScriptGlobal->GetCurrentInnerWindow()->GetClientInfo
().isSome())>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mScriptGlobal->GetCurrentInnerWindow
()->GetClientInfo().isSome()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mScriptGlobal->GetCurrentInnerWindow()->GetClientInfo().isSome()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2402); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mScriptGlobal->GetCurrentInnerWindow()->GetClientInfo().isSome()"
")"); do { *((volatile int*)__null) = 2402; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2402 mScriptGlobal->GetCurrentInnerWindow()->GetClientInfo().isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mScriptGlobal->GetCurrentInnerWindow()->GetClientInfo
().isSome())>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mScriptGlobal->GetCurrentInnerWindow
()->GetClientInfo().isSome()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mScriptGlobal->GetCurrentInnerWindow()->GetClientInfo().isSome()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2402); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mScriptGlobal->GetCurrentInnerWindow()->GetClientInfo().isSome()"
")"); do { *((volatile int*)__null) = 2402; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2403 MOZ_DIAGNOSTIC_ASSERT(!mInitialClientSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInitialClientSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mInitialClientSource))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mInitialClientSource"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2403); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mInitialClientSource"
")"); do { *((volatile int*)__null) = 2403; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2404 return;
2405 }
2406
2407 // Don't recreate the initial client source. We call this multiple times
2408 // when DoChannelLoad() is called before CreateAboutBlankDocumentViewer.
2409 if (mInitialClientSource) {
2410 return;
2411 }
2412
2413 // Don't pre-allocate the client when we are sandboxed. The inherited
2414 // principal does not take sandboxing into account.
2415 // TODO: Refactor sandboxing principal code out so we can use it here.
2416 if (!aPrincipal && mBrowsingContext->GetSandboxFlags()) {
2417 return;
2418 }
2419
2420 // We cannot get inherited foreign partitioned principal here. Instead, we
2421 // directly check which principal we want to inherit for the service worker.
2422 nsIPrincipal* principal =
2423 aPrincipal
2424 ? aPrincipal
2425 : GetInheritedPrincipal(
2426 false, StoragePrincipalHelper::
2427 ShouldUsePartitionPrincipalForServiceWorker(this));
2428
2429 // Sometimes there is no principal available when we are called from
2430 // CreateAboutBlankDocumentViewer. For example, sometimes the principal
2431 // is only extracted from the load context after the document is created
2432 // in Document::ResetToURI(). Ideally we would do something similar
2433 // here, but for now lets just avoid the issue by not preallocating the
2434 // client.
2435 if (!principal) {
2436 return;
2437 }
2438
2439 nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
2440 if (!win) {
2441 return;
2442 }
2443
2444 mInitialClientSource = ClientManager::CreateSource(
2445 ClientType::Window, GetMainThreadSerialEventTarget(), principal);
2446 MOZ_DIAGNOSTIC_ASSERT(mInitialClientSource)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mInitialClientSource)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mInitialClientSource))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mInitialClientSource"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2446); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mInitialClientSource"
")"); do { *((volatile int*)__null) = 2446; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2447
2448 // Mark the initial client as execution ready, but owned by the docshell.
2449 // If the client is actually used this will cause ClientSource to force
2450 // the creation of the initial about:blank by calling
2451 // nsDocShell::GetDocument().
2452 mInitialClientSource->DocShellExecutionReady(this);
2453
2454 // Next, check to see if the parent is controlled.
2455 nsCOMPtr<nsIDocShell> parent = GetInProcessParentDocshell();
2456 nsPIDOMWindowOuter* parentOuter = parent ? parent->GetWindow() : nullptr;
2457 nsPIDOMWindowInner* parentInner =
2458 parentOuter ? parentOuter->GetCurrentInnerWindow() : nullptr;
2459 if (!parentInner) {
2460 return;
2461 }
2462
2463 nsCOMPtr<nsIURI> uri;
2464 MOZ_ALWAYS_SUCCEEDS(NS_NewURI(getter_AddRefs(uri), "about:blank"_ns))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(NS_NewURI(getter_AddRefs(uri), "about:blank"_ns))), 1)))), 1
))) { } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), \"about:blank\"_ns))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2464); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), \"about:blank\"_ns))"
")"); do { *((volatile int*)__null) = 2464; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2465
2466 // We're done if there is no parent controller or if this docshell
2467 // is not permitted to control for some reason.
2468 Maybe<ServiceWorkerDescriptor> controller(parentInner->GetController());
2469 if (controller.isNothing() ||
2470 !ServiceWorkerAllowedToControlWindow(principal, uri)) {
2471 return;
2472 }
2473
2474 mInitialClientSource->InheritController(controller.ref());
2475}
2476
2477Maybe<ClientInfo> nsDocShell::GetInitialClientInfo() const {
2478 if (mInitialClientSource) {
2479 Maybe<ClientInfo> result;
2480 result.emplace(mInitialClientSource->Info());
2481 return result;
2482 }
2483
2484 nsPIDOMWindowInner* innerWindow =
2485 mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindow() : nullptr;
2486 Document* doc = innerWindow ? innerWindow->GetExtantDoc() : nullptr;
2487
2488 if (!doc || !doc->IsInitialDocument()) {
2489 return Maybe<ClientInfo>();
2490 }
2491
2492 return innerWindow->GetClientInfo();
2493}
2494
2495nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
2496 bool wasFrame = IsSubframe();
2497
2498 nsresult rv = nsDocLoader::SetDocLoaderParent(aParent);
2499 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2499); return rv; } } while (false)
;
2500
2501 nsCOMPtr<nsISupportsPriority> priorityGroup = do_QueryInterface(mLoadGroup);
2502 if (wasFrame != IsSubframe() && priorityGroup) {
2503 priorityGroup->AdjustPriority(wasFrame ? -1 : 1);
2504 }
2505
2506 // Curse ambiguous nsISupports inheritance!
2507 nsISupports* parent = GetAsSupports(aParent);
2508
2509 // If parent is another docshell, we inherit all their flags for
2510 // allowing plugins, scripting etc.
2511 bool value;
2512 nsCOMPtr<nsIDocShell> parentAsDocShell(do_QueryInterface(parent));
2513
2514 if (parentAsDocShell) {
2515 if (mAllowMetaRedirects &&
2516 NS_SUCCEEDED(parentAsDocShell->GetAllowMetaRedirects(&value))((bool)(__builtin_expect(!!(!NS_FAILED_impl(parentAsDocShell->
GetAllowMetaRedirects(&value))), 1)))
) {
2517 SetAllowMetaRedirects(value);
2518 }
2519 if (mAllowSubframes &&
2520 NS_SUCCEEDED(parentAsDocShell->GetAllowSubframes(&value))((bool)(__builtin_expect(!!(!NS_FAILED_impl(parentAsDocShell->
GetAllowSubframes(&value))), 1)))
) {
2521 SetAllowSubframes(value);
2522 }
2523 if (mAllowImages &&
2524 NS_SUCCEEDED(parentAsDocShell->GetAllowImages(&value))((bool)(__builtin_expect(!!(!NS_FAILED_impl(parentAsDocShell->
GetAllowImages(&value))), 1)))
) {
2525 SetAllowImages(value);
2526 }
2527 SetAllowMedia(parentAsDocShell->GetAllowMedia() && mAllowMedia);
2528 if (mAllowWindowControl &&
2529 NS_SUCCEEDED(parentAsDocShell->GetAllowWindowControl(&value))((bool)(__builtin_expect(!!(!NS_FAILED_impl(parentAsDocShell->
GetAllowWindowControl(&value))), 1)))
) {
2530 SetAllowWindowControl(value);
2531 }
2532 if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))((bool)(__builtin_expect(!!(NS_FAILED_impl(parentAsDocShell->
GetAllowDNSPrefetch(&value))), 0)))
) {
2533 value = false;
2534 }
2535 SetAllowDNSPrefetch(mAllowDNSPrefetch && value);
2536 }
2537
2538 nsCOMPtr<nsIURIContentListener> parentURIListener(do_GetInterface(parent));
2539 if (parentURIListener) {
2540 mContentListener->SetParentContentListener(parentURIListener);
2541 }
2542
2543 return NS_OK;
2544}
2545
2546void nsDocShell::MaybeRestoreWindowName() {
2547 if (!StaticPrefs::privacy_window_name_update_enabled()) {
2548 return;
2549 }
2550
2551 // We only restore window.name for the top-level content.
2552 if (!mBrowsingContext->IsTopContent()) {
2553 return;
2554 }
2555
2556 nsAutoString name;
2557
2558 // Following implements https://html.spec.whatwg.org/#history-traversal:
2559 // Step 4.4. Check if the loading entry has a name.
2560
2561 if (mLSHE) {
2562 mLSHE->GetName(name);
2563 }
2564
2565 if (mLoadingEntry) {
2566 name = mLoadingEntry->mInfo.GetName();
2567 }
2568
2569 if (name.IsEmpty()) {
2570 return;
2571 }
2572
2573 // Step 4.4.1. Set the name to the browsing context.
2574 Unused << mBrowsingContext->SetName(name);
2575
2576 // Step 4.4.2. Clear the name of all entries that are contiguous and
2577 // same-origin with the loading entry.
2578 if (mLSHE) {
2579 nsSHistory::WalkContiguousEntries(
2580 mLSHE, [](nsISHEntry* aEntry) { aEntry->SetName(EmptyString()); });
2581 }
2582
2583 if (mLoadingEntry) {
2584 // Clear the name of the session entry in the child side. For parent side,
2585 // the clearing will be done when we commit the history to the parent.
2586 mLoadingEntry->mInfo.SetName(EmptyString());
2587 }
2588}
2589
2590void nsDocShell::StoreWindowNameToSHEntries() {
2591 MOZ_ASSERT(mBrowsingContext->IsTopContent())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mBrowsingContext->IsTopContent())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mBrowsingContext->IsTopContent
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mBrowsingContext->IsTopContent()", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mBrowsingContext->IsTopContent()"
")"); do { *((volatile int*)__null) = 2591; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2592
2593 nsAutoString name;
2594 mBrowsingContext->GetName(name);
2595
2596 if (mOSHE) {
2597 nsSHistory::WalkContiguousEntries(
2598 mOSHE, [&](nsISHEntry* aEntry) { aEntry->SetName(name); });
2599 }
2600
2601 if (mozilla::SessionHistoryInParent()) {
2602 if (XRE_IsParentProcess()) {
2603 SessionHistoryEntry* entry =
2604 mBrowsingContext->Canonical()->GetActiveSessionHistoryEntry();
2605 if (entry) {
2606 nsSHistory::WalkContiguousEntries(
2607 entry, [&](nsISHEntry* aEntry) { aEntry->SetName(name); });
2608 }
2609 } else {
2610 // Ask parent process to store the name in entries.
2611 mozilla::Unused
2612 << ContentChild::GetSingleton()
2613 ->SendSessionHistoryEntryStoreWindowNameInContiguousEntries(
2614 mBrowsingContext, name);
2615 }
2616 }
2617}
2618
2619NS_IMETHODIMPnsresult
2620nsDocShell::GetInProcessSameTypeParent(nsIDocShellTreeItem** aParent) {
2621 if (BrowsingContext* parentBC = mBrowsingContext->GetParent()) {
2622 *aParent = do_AddRef(parentBC->GetDocShell()).take();
2623 }
2624 return NS_OK;
2625}
2626
2627NS_IMETHODIMPnsresult
2628nsDocShell::GetInProcessRootTreeItem(nsIDocShellTreeItem** aRootTreeItem) {
2629 NS_ENSURE_ARG_POINTER(aRootTreeItem)do { if ((__builtin_expect(!!(!(aRootTreeItem)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aRootTreeItem" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2629); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2630
2631 RefPtr<nsDocShell> root = this;
2632 RefPtr<nsDocShell> parent = root->GetInProcessParentDocshell();
2633 while (parent) {
2634 root = parent;
2635 parent = root->GetInProcessParentDocshell();
2636 }
2637
2638 root.forget(aRootTreeItem);
2639 return NS_OK;
2640}
2641
2642NS_IMETHODIMPnsresult
2643nsDocShell::GetInProcessSameTypeRootTreeItem(
2644 nsIDocShellTreeItem** aRootTreeItem) {
2645 NS_ENSURE_ARG_POINTER(aRootTreeItem)do { if ((__builtin_expect(!!(!(aRootTreeItem)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aRootTreeItem" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2645); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2646 *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
2647
2648 nsCOMPtr<nsIDocShellTreeItem> parent;
2649 NS_ENSURE_SUCCESS(GetInProcessSameTypeParent(getter_AddRefs(parent)),do { nsresult __rv = GetInProcessSameTypeParent(getter_AddRefs
(parent)); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(__rv
)), 0)))) { const char* name = mozilla::GetStaticErrorName(__rv
); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "GetInProcessSameTypeParent(getter_AddRefs(parent))"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2650); return NS_ERROR_FAILURE; } } while (false)
2650 NS_ERROR_FAILURE)do { nsresult __rv = GetInProcessSameTypeParent(getter_AddRefs
(parent)); if (((bool)(__builtin_expect(!!(NS_FAILED_impl(__rv
)), 0)))) { const char* name = mozilla::GetStaticErrorName(__rv
); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "GetInProcessSameTypeParent(getter_AddRefs(parent))"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2650); return NS_ERROR_FAILURE; } } while (false)
;
2651 while (parent) {
2652 *aRootTreeItem = parent;
2653 NS_ENSURE_SUCCESS(do { nsresult __rv = (*aRootTreeItem)->GetInProcessSameTypeParent
(getter_AddRefs(parent)); if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "(*aRootTreeItem)->GetInProcessSameTypeParent(getter_AddRefs(parent))"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2655); return NS_ERROR_FAILURE; } } while (false)
2654 (*aRootTreeItem)->GetInProcessSameTypeParent(getter_AddRefs(parent)),do { nsresult __rv = (*aRootTreeItem)->GetInProcessSameTypeParent
(getter_AddRefs(parent)); if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "(*aRootTreeItem)->GetInProcessSameTypeParent(getter_AddRefs(parent))"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2655); return NS_ERROR_FAILURE; } } while (false)
2655 NS_ERROR_FAILURE)do { nsresult __rv = (*aRootTreeItem)->GetInProcessSameTypeParent
(getter_AddRefs(parent)); if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "(*aRootTreeItem)->GetInProcessSameTypeParent(getter_AddRefs(parent))"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2655); return NS_ERROR_FAILURE; } } while (false)
;
2656 }
2657 NS_ADDREF(*aRootTreeItem)(*aRootTreeItem)->AddRef();
2658 return NS_OK;
2659}
2660
2661NS_IMETHODIMPnsresult
2662nsDocShell::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner) {
2663 NS_ENSURE_ARG_POINTER(aTreeOwner)do { if ((__builtin_expect(!!(!(aTreeOwner)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aTreeOwner" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2663); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2664
2665 *aTreeOwner = mTreeOwner;
2666 NS_IF_ADDREF(*aTreeOwner)ns_if_addref(*aTreeOwner);
2667 return NS_OK;
2668}
2669
2670NS_IMETHODIMPnsresult
2671nsDocShell::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner) {
2672 if (mIsBeingDestroyed && aTreeOwner) {
2673 return NS_ERROR_FAILURE;
2674 }
2675
2676 // Don't automatically set the progress based on the tree owner for frames
2677 if (!IsSubframe()) {
2678 nsCOMPtr<nsIWebProgress> webProgress =
2679 do_QueryInterface(GetAsSupports(this));
2680
2681 if (webProgress) {
2682 nsCOMPtr<nsIWebProgressListener> oldListener =
2683 do_QueryInterface(mTreeOwner);
2684 nsCOMPtr<nsIWebProgressListener> newListener =
2685 do_QueryInterface(aTreeOwner);
2686
2687 if (oldListener) {
2688 webProgress->RemoveProgressListener(oldListener);
2689 }
2690
2691 if (newListener) {
2692 webProgress->AddProgressListener(newListener,
2693 nsIWebProgress::NOTIFY_ALL);
2694 }
2695 }
2696 }
2697
2698 mTreeOwner = aTreeOwner; // Weak reference per API
2699
2700 for (auto* childDocLoader : mChildList.ForwardRange()) {
2701 nsCOMPtr<nsIDocShellTreeItem> child = do_QueryObject(childDocLoader);
2702 NS_ENSURE_TRUE(child, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(child)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "child" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2702); return NS_ERROR_FAILURE; } } while (false)
;
2703
2704 if (child->ItemType() == mItemType) {
2705 child->SetTreeOwner(aTreeOwner);
2706 }
2707 }
2708
2709 // If we're in the content process and have had a TreeOwner set on us, extract
2710 // our BrowserChild actor. If we've already had our BrowserChild set, assert
2711 // that it hasn't changed.
2712 if (mTreeOwner && XRE_IsContentProcess()) {
2713 nsCOMPtr<nsIBrowserChild> newBrowserChild = do_GetInterface(mTreeOwner);
2714 MOZ_ASSERT(newBrowserChild,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(newBrowserChild)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(newBrowserChild))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("newBrowserChild"
" (" "No BrowserChild actor for tree owner in Content!" ")",
"/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2715); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newBrowserChild"
") (" "No BrowserChild actor for tree owner in Content!" ")"
); do { *((volatile int*)__null) = 2715; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2715 "No BrowserChild actor for tree owner in Content!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(newBrowserChild)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(newBrowserChild))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("newBrowserChild"
" (" "No BrowserChild actor for tree owner in Content!" ")",
"/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2715); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newBrowserChild"
") (" "No BrowserChild actor for tree owner in Content!" ")"
); do { *((volatile int*)__null) = 2715; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2716
2717 if (mBrowserChild) {
2718 nsCOMPtr<nsIBrowserChild> oldBrowserChild =
2719 do_QueryReferent(mBrowserChild);
2720 MOZ_RELEASE_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(oldBrowserChild == newBrowserChild)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(oldBrowserChild == newBrowserChild
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"oldBrowserChild == newBrowserChild" " (" "Cannot change BrowserChild during nsDocShell lifetime!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2722); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "oldBrowserChild == newBrowserChild"
") (" "Cannot change BrowserChild during nsDocShell lifetime!"
")"); do { *((volatile int*)__null) = 2722; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2721 oldBrowserChild == newBrowserChild,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(oldBrowserChild == newBrowserChild)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(oldBrowserChild == newBrowserChild
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"oldBrowserChild == newBrowserChild" " (" "Cannot change BrowserChild during nsDocShell lifetime!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2722); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "oldBrowserChild == newBrowserChild"
") (" "Cannot change BrowserChild during nsDocShell lifetime!"
")"); do { *((volatile int*)__null) = 2722; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2722 "Cannot change BrowserChild during nsDocShell lifetime!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(oldBrowserChild == newBrowserChild)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(oldBrowserChild == newBrowserChild
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"oldBrowserChild == newBrowserChild" " (" "Cannot change BrowserChild during nsDocShell lifetime!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2722); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "oldBrowserChild == newBrowserChild"
") (" "Cannot change BrowserChild during nsDocShell lifetime!"
")"); do { *((volatile int*)__null) = 2722; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2723 } else {
2724 mBrowserChild = do_GetWeakReference(newBrowserChild);
2725 }
2726 }
2727
2728 return NS_OK;
2729}
2730
2731NS_IMETHODIMPnsresult
2732nsDocShell::GetHistoryID(nsID& aID) {
2733 aID = mBrowsingContext->GetHistoryID();
2734 return NS_OK;
2735}
2736
2737const nsID& nsDocShell::HistoryID() { return mBrowsingContext->GetHistoryID(); }
2738
2739NS_IMETHODIMPnsresult
2740nsDocShell::GetIsInUnload(bool* aIsInUnload) {
2741 *aIsInUnload = mFiredUnloadEvent;
2742 return NS_OK;
2743}
2744
2745NS_IMETHODIMPnsresult
2746nsDocShell::GetInProcessChildCount(int32_t* aChildCount) {
2747 NS_ENSURE_ARG_POINTER(aChildCount)do { if ((__builtin_expect(!!(!(aChildCount)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChildCount" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2747); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2748 *aChildCount = mChildList.Length();
2749 return NS_OK;
2750}
2751
2752NS_IMETHODIMPnsresult
2753nsDocShell::AddChild(nsIDocShellTreeItem* aChild) {
2754 NS_ENSURE_ARG_POINTER(aChild)do { if ((__builtin_expect(!!(!(aChild)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChild" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2754); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2755
2756 RefPtr<nsDocLoader> childAsDocLoader = GetAsDocLoader(aChild);
2757 NS_ENSURE_TRUE(childAsDocLoader, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(childAsDocLoader)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "childAsDocLoader" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2757); return NS_ERROR_UNEXPECTED; } } while (false)
;
2758
2759 // Make sure we're not creating a loop in the docshell tree
2760 nsDocLoader* ancestor = this;
2761 do {
2762 if (childAsDocLoader == ancestor) {
2763 return NS_ERROR_ILLEGAL_VALUE;
2764 }
2765 ancestor = ancestor->GetParent();
2766 } while (ancestor);
2767
2768 // Make sure to remove the child from its current parent.
2769 nsDocLoader* childsParent = childAsDocLoader->GetParent();
2770 if (childsParent) {
2771 nsresult rv = childsParent->RemoveChildLoader(childAsDocLoader);
2772 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2772); return rv; } } while (false)
;
2773 }
2774
2775 // Make sure to clear the treeowner in case this child is a different type
2776 // from us.
2777 aChild->SetTreeOwner(nullptr);
2778
2779 nsresult res = AddChildLoader(childAsDocLoader);
2780 NS_ENSURE_SUCCESS(res, res)do { nsresult __rv = res; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "res", "res", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2780); return res; } } while (false)
;
2781 NS_ASSERTION(!mChildList.IsEmpty(),do { if (!(!mChildList.IsEmpty())) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "child list must not be empty after a successful add", "!mChildList.IsEmpty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2782); MOZ_PretendNoReturn(); } } while (0)
2782 "child list must not be empty after a successful add")do { if (!(!mChildList.IsEmpty())) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "child list must not be empty after a successful add", "!mChildList.IsEmpty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2782); MOZ_PretendNoReturn(); } } while (0)
;
2783
2784 /* Set the child's global history if the parent has one */
2785 if (mBrowsingContext->GetUseGlobalHistory()) {
2786 // childDocShell->SetUseGlobalHistory(true);
2787 // this should be set through BC inherit
2788 MOZ_ASSERT(aChild->GetBrowsingContext()->GetUseGlobalHistory())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aChild->GetBrowsingContext()->GetUseGlobalHistory
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aChild->GetBrowsingContext()->GetUseGlobalHistory
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aChild->GetBrowsingContext()->GetUseGlobalHistory()",
"/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2788); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aChild->GetBrowsingContext()->GetUseGlobalHistory()"
")"); do { *((volatile int*)__null) = 2788; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2789 }
2790
2791 if (aChild->ItemType() != mItemType) {
2792 return NS_OK;
2793 }
2794
2795 aChild->SetTreeOwner(mTreeOwner);
2796
2797 nsCOMPtr<nsIDocShell> childAsDocShell(do_QueryInterface(aChild));
2798 if (!childAsDocShell) {
2799 return NS_OK;
2800 }
2801
2802 // charset, style-disabling, and zoom will be inherited in SetupNewViewer()
2803
2804 // Now take this document's charset and set the child's parentCharset field
2805 // to it. We'll later use that field, in the loading process, for the
2806 // charset choosing algorithm.
2807 // If we fail, at any point, we just return NS_OK.
2808 // This code has some performance impact. But this will be reduced when
2809 // the current charset will finally be stored as an Atom, avoiding the
2810 // alias resolution extra look-up.
2811
2812 // we are NOT going to propagate the charset is this Chrome's docshell
2813 if (mItemType == nsIDocShellTreeItem::typeChrome) {
2814 return NS_OK;
2815 }
2816
2817 // get the parent's current charset
2818 if (!mDocumentViewer) {
2819 return NS_OK;
2820 }
2821 Document* doc = mDocumentViewer->GetDocument();
2822 if (!doc) {
2823 return NS_OK;
2824 }
2825
2826 const Encoding* parentCS = doc->GetDocumentCharacterSet();
2827 int32_t charsetSource = doc->GetDocumentCharacterSetSource();
2828 // set the child's parentCharset
2829 childAsDocShell->SetParentCharset(parentCS, charsetSource,
2830 doc->NodePrincipal());
2831
2832 // printf("### 1 >>> Adding child. Parent CS = %s. ItemType = %d.\n",
2833 // NS_LossyConvertUTF16toASCII(parentCS).get(), mItemType);
2834
2835 return NS_OK;
2836}
2837
2838NS_IMETHODIMPnsresult
2839nsDocShell::RemoveChild(nsIDocShellTreeItem* aChild) {
2840 NS_ENSURE_ARG_POINTER(aChild)do { if ((__builtin_expect(!!(!(aChild)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChild" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2840); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2841
2842 RefPtr<nsDocLoader> childAsDocLoader = GetAsDocLoader(aChild);
2843 NS_ENSURE_TRUE(childAsDocLoader, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(childAsDocLoader)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "childAsDocLoader" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2843); return NS_ERROR_UNEXPECTED; } } while (false)
;
2844
2845 nsresult rv = RemoveChildLoader(childAsDocLoader);
2846 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2846); return rv; } } while (false)
;
2847
2848 aChild->SetTreeOwner(nullptr);
2849
2850 return nsDocLoader::AddDocLoaderAsChildOfRoot(childAsDocLoader);
2851}
2852
2853NS_IMETHODIMPnsresult
2854nsDocShell::GetInProcessChildAt(int32_t aIndex, nsIDocShellTreeItem** aChild) {
2855 NS_ENSURE_ARG_POINTER(aChild)do { if ((__builtin_expect(!!(!(aChild)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChild" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2855); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2856
2857 RefPtr<nsDocShell> child = GetInProcessChildAt(aIndex);
2858 NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(child)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "child" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2858); return NS_ERROR_UNEXPECTED; } } while (false)
;
2859
2860 child.forget(aChild);
2861
2862 return NS_OK;
2863}
2864
2865nsDocShell* nsDocShell::GetInProcessChildAt(int32_t aIndex) {
2866#ifdef DEBUG1
2867 if (aIndex < 0) {
2868 NS_WARNING("Negative index passed to GetChildAt")NS_DebugBreak(NS_DEBUG_WARNING, "Negative index passed to GetChildAt"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2868)
;
2869 } else if (static_cast<uint32_t>(aIndex) >= mChildList.Length()) {
2870 NS_WARNING("Too large an index passed to GetChildAt")NS_DebugBreak(NS_DEBUG_WARNING, "Too large an index passed to GetChildAt"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2870)
;
2871 }
2872#endif
2873
2874 nsIDocumentLoader* child = ChildAt(aIndex);
2875
2876 // child may be nullptr here.
2877 return static_cast<nsDocShell*>(child);
2878}
2879
2880nsresult nsDocShell::AddChildSHEntry(nsISHEntry* aCloneRef,
2881 nsISHEntry* aNewEntry,
2882 int32_t aChildOffset, uint32_t aLoadType,
2883 bool aCloneChildren) {
2884 MOZ_ASSERT(!mozilla::SessionHistoryInParent())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mozilla::SessionHistoryInParent())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mozilla::SessionHistoryInParent
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!mozilla::SessionHistoryInParent()", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2884); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mozilla::SessionHistoryInParent()"
")"); do { *((volatile int*)__null) = 2884; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2885 nsresult rv = NS_OK;
2886
2887 if (mLSHE && aLoadType != LOAD_PUSHSTATE) {
2888 /* You get here if you are currently building a
2889 * hierarchy ie.,you just visited a frameset page
2890 */
2891 if (NS_FAILED(mLSHE->ReplaceChild(aNewEntry))((bool)(__builtin_expect(!!(NS_FAILED_impl(mLSHE->ReplaceChild
(aNewEntry))), 0)))
) {
2892 rv = mLSHE->AddChild(aNewEntry, aChildOffset);
2893 }
2894 } else if (!aCloneRef) {
2895 /* This is an initial load in some subframe. Just append it if we can */
2896 if (mOSHE) {
2897 rv = mOSHE->AddChild(aNewEntry, aChildOffset, UseRemoteSubframes());
2898 }
2899 } else {
2900 RefPtr<ChildSHistory> shistory = GetRootSessionHistory();
2901 if (shistory) {
2902 rv = shistory->LegacySHistory()->AddChildSHEntryHelper(
2903 aCloneRef, aNewEntry, mBrowsingContext->Top(), aCloneChildren);
2904 }
2905 }
2906 return rv;
2907}
2908
2909nsresult nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry,
2910 int32_t aChildOffset,
2911 bool aCloneChildren) {
2912 MOZ_ASSERT(!mozilla::SessionHistoryInParent())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mozilla::SessionHistoryInParent())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mozilla::SessionHistoryInParent
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!mozilla::SessionHistoryInParent()", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2912); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mozilla::SessionHistoryInParent()"
")"); do { *((volatile int*)__null) = 2912; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2913 /* You will get here when you are in a subframe and
2914 * a new url has been loaded on you.
2915 * The mOSHE in this subframe will be the previous url's
2916 * mOSHE. This mOSHE will be used as the identification
2917 * for this subframe in the CloneAndReplace function.
2918 */
2919
2920 // In this case, we will end up calling AddEntry, which increases the
2921 // current index by 1
2922 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
2923 if (rootSH) {
2924 mPreviousEntryIndex = rootSH->Index();
2925 }
2926
2927 nsresult rv;
2928 // XXX(farre): this is not Fission safe, expect errors. This never
2929 // get's executed once session history in the parent is enabled.
2930 nsCOMPtr<nsIDocShell> parent = do_QueryInterface(GetAsSupports(mParent), &rv);
2931 NS_WARNING_ASSERTION(do { if (!(parent || !UseRemoteSubframes())) { NS_DebugBreak(
NS_DEBUG_WARNING, "Failed to add child session history entry! This will be resolved once "
"session history in the parent is enabled.", "parent || !UseRemoteSubframes()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2934); } } while (false)
2932 parent || !UseRemoteSubframes(),do { if (!(parent || !UseRemoteSubframes())) { NS_DebugBreak(
NS_DEBUG_WARNING, "Failed to add child session history entry! This will be resolved once "
"session history in the parent is enabled.", "parent || !UseRemoteSubframes()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2934); } } while (false)
2933 "Failed to add child session history entry! This will be resolved once "do { if (!(parent || !UseRemoteSubframes())) { NS_DebugBreak(
NS_DEBUG_WARNING, "Failed to add child session history entry! This will be resolved once "
"session history in the parent is enabled.", "parent || !UseRemoteSubframes()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2934); } } while (false)
2934 "session history in the parent is enabled.")do { if (!(parent || !UseRemoteSubframes())) { NS_DebugBreak(
NS_DEBUG_WARNING, "Failed to add child session history entry! This will be resolved once "
"session history in the parent is enabled.", "parent || !UseRemoteSubframes()"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2934); } } while (false)
;
2935 if (parent) {
2936 rv = nsDocShell::Cast(parent)->AddChildSHEntry(
2937 mOSHE, aNewEntry, aChildOffset, mLoadType, aCloneChildren);
2938 }
2939
2940 if (rootSH) {
2941 mLoadedEntryIndex = rootSH->Index();
2942
2943 if (MOZ_UNLIKELY(MOZ_LOG_TEST(gPageCacheLog, LogLevel::Verbose))(__builtin_expect(!!((__builtin_expect(!!(mozilla::detail::log_test
(gPageCacheLog, LogLevel::Verbose)), 0))), 0))
) {
2944 MOZ_LOG(gPageCacheLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Previous index: %d, Loaded index: %d", mPreviousEntryIndex
, mLoadedEntryIndex); } } while (0)
2945 ("Previous index: %d, Loaded index: %d", mPreviousEntryIndex,do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Previous index: %d, Loaded index: %d", mPreviousEntryIndex
, mLoadedEntryIndex); } } while (0)
2946 mLoadedEntryIndex))do { const ::mozilla::LogModule* moz_real_module = gPageCacheLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "Previous index: %d, Loaded index: %d", mPreviousEntryIndex
, mLoadedEntryIndex); } } while (0)
;
2947 }
2948 }
2949
2950 return rv;
2951}
2952
2953NS_IMETHODIMPnsresult
2954nsDocShell::GetCurrentSHEntry(nsISHEntry** aEntry, bool* aOSHE) {
2955 *aOSHE = false;
2956 *aEntry = nullptr;
2957 if (mLSHE) {
2958 NS_ADDREF(*aEntry = mLSHE)(*aEntry = mLSHE)->AddRef();
2959 } else if (mOSHE) {
2960 NS_ADDREF(*aEntry = mOSHE)(*aEntry = mOSHE)->AddRef();
2961 *aOSHE = true;
2962 }
2963 return NS_OK;
2964}
2965
2966NS_IMETHODIMPnsresult nsDocShell::SynchronizeLayoutHistoryState() {
2967 if (mActiveEntry && mActiveEntry->GetLayoutHistoryState() &&
2968 mBrowsingContext) {
2969 if (XRE_IsContentProcess()) {
2970 dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
2971 if (contentChild) {
2972 contentChild->SendSynchronizeLayoutHistoryState(
2973 mBrowsingContext, mActiveEntry->GetLayoutHistoryState());
2974 }
2975 } else {
2976 SessionHistoryEntry* entry =
2977 mBrowsingContext->Canonical()->GetActiveSessionHistoryEntry();
2978 if (entry) {
2979 entry->SetLayoutHistoryState(mActiveEntry->GetLayoutHistoryState());
2980 }
2981 }
2982 if (mLoadingEntry &&
2983 mLoadingEntry->mInfo.SharedId() == mActiveEntry->SharedId()) {
2984 mLoadingEntry->mInfo.SetLayoutHistoryState(
2985 mActiveEntry->GetLayoutHistoryState());
2986 }
2987 }
2988
2989 return NS_OK;
2990}
2991
2992void nsDocShell::SetLoadGroupDefaultLoadFlags(nsLoadFlags aLoadFlags) {
2993 if (mLoadGroup) {
2994 mLoadGroup->SetDefaultLoadFlags(aLoadFlags);
2995 } else {
2996 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "nsDocShell::SetLoadGroupDefaultLoadFlags has no loadGroup to "
"propagate the mode to", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2998)
2997 "nsDocShell::SetLoadGroupDefaultLoadFlags has no loadGroup to "NS_DebugBreak(NS_DEBUG_WARNING, "nsDocShell::SetLoadGroupDefaultLoadFlags has no loadGroup to "
"propagate the mode to", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2998)
2998 "propagate the mode to")NS_DebugBreak(NS_DEBUG_WARNING, "nsDocShell::SetLoadGroupDefaultLoadFlags has no loadGroup to "
"propagate the mode to", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 2998)
;
2999 }
3000}
3001
3002nsIScriptGlobalObject* nsDocShell::GetScriptGlobalObject() {
3003 NS_ENSURE_SUCCESS(EnsureScriptEnvironment(), nullptr)do { nsresult __rv = EnsureScriptEnvironment(); if (((bool)(__builtin_expect
(!!(NS_FAILED_impl(__rv)), 0)))) { const char* name = mozilla
::GetStaticErrorName(__rv); mozilla::SmprintfPointer msg = mozilla
::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%"
"X" "%s%s%s", "EnsureScriptEnvironment()", "nullptr", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3003); return nullptr; } } while (false)
;
3004 return mScriptGlobal;
3005}
3006
3007Document* nsDocShell::GetDocument() {
3008 NS_ENSURE_SUCCESS(EnsureDocumentViewer(), nullptr)do { nsresult __rv = EnsureDocumentViewer(); if (((bool)(__builtin_expect
(!!(NS_FAILED_impl(__rv)), 0)))) { const char* name = mozilla
::GetStaticErrorName(__rv); mozilla::SmprintfPointer msg = mozilla
::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%"
"X" "%s%s%s", "EnsureDocumentViewer()", "nullptr", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3008); return nullptr; } } while (false)
;
3009 return mDocumentViewer->GetDocument();
3010}
3011
3012Document* nsDocShell::GetExtantDocument() {
3013 return mDocumentViewer ? mDocumentViewer->GetDocument() : nullptr;
3014}
3015
3016nsPIDOMWindowOuter* nsDocShell::GetWindow() {
3017 if (NS_FAILED(EnsureScriptEnvironment())((bool)(__builtin_expect(!!(NS_FAILED_impl(EnsureScriptEnvironment
())), 0)))
) {
3018 return nullptr;
3019 }
3020 return mScriptGlobal;
3021}
3022
3023NS_IMETHODIMPnsresult
3024nsDocShell::GetDomWindow(mozIDOMWindowProxy** aWindow) {
3025 NS_ENSURE_ARG_POINTER(aWindow)do { if ((__builtin_expect(!!(!(aWindow)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aWindow" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3025); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3026
3027 nsresult rv = EnsureScriptEnvironment();
3028 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3028); return rv; } } while (false)
;
3029
3030 RefPtr<nsGlobalWindowOuter> window = mScriptGlobal;
3031 window.forget(aWindow);
3032 return NS_OK;
3033}
3034
3035NS_IMETHODIMPnsresult
3036nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) {
3037 RefPtr<ContentFrameMessageManager> mm;
3038 if (RefPtr<BrowserChild> browserChild = BrowserChild::GetFrom(this)) {
3039 mm = browserChild->GetMessageManager();
3040 } else if (nsPIDOMWindowOuter* win = GetWindow()) {
3041 mm = win->GetMessageManager();
3042 }
3043 mm.forget(aMessageManager);
3044 return NS_OK;
3045}
3046
3047NS_IMETHODIMPnsresult
3048nsDocShell::GetIsNavigating(bool* aOut) {
3049 *aOut = mIsNavigating;
3050 return NS_OK;
3051}
3052
3053void nsDocShell::ClearFrameHistory(nsISHEntry* aEntry) {
3054 MOZ_ASSERT(!mozilla::SessionHistoryInParent())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mozilla::SessionHistoryInParent())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mozilla::SessionHistoryInParent
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!mozilla::SessionHistoryInParent()", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3054); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mozilla::SessionHistoryInParent()"
")"); do { *((volatile int*)__null) = 3054; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3055 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
3056 if (!rootSH || !aEntry) {
3057 return;
3058 }
3059
3060 rootSH->LegacySHistory()->RemoveFrameEntries(aEntry);
3061}
3062
3063//-------------------------------------
3064//-- Helper Method for Print discovery
3065//-------------------------------------
3066bool nsDocShell::NavigationBlockedByPrinting(bool aDisplayErrorDialog) {
3067 if (!mBrowsingContext->Top()->GetIsPrinting()) {
3068 return false;
3069 }
3070 if (aDisplayErrorDialog) {
3071 DisplayLoadError(NS_ERROR_DOCUMENT_IS_PRINTMODE, nullptr, nullptr, nullptr);
3072 }
3073 return true;
3074}
3075
3076bool nsDocShell::IsNavigationAllowed(bool aDisplayPrintErrorDialog,
3077 bool aCheckIfUnloadFired) {
3078 bool isAllowed = !NavigationBlockedByPrinting(aDisplayPrintErrorDialog) &&
3079 (!aCheckIfUnloadFired || !mFiredUnloadEvent);
3080 if (!isAllowed) {
3081 return false;
3082 }
3083 if (!mDocumentViewer) {
3084 return true;
3085 }
3086 bool firingBeforeUnload;
3087 mDocumentViewer->GetBeforeUnloadFiring(&firingBeforeUnload);
3088 return !firingBeforeUnload;
3089}
3090
3091//*****************************************************************************
3092// nsDocShell::nsIWebNavigation
3093//*****************************************************************************
3094
3095NS_IMETHODIMPnsresult
3096nsDocShell::GetCanGoBack(bool* aCanGoBack) {
3097 *aCanGoBack = false;
3098 if (!IsNavigationAllowed(false)) {
3099 return NS_OK; // JS may not handle returning of an error code
3100 }
3101 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
3102 if (rootSH) {
3103 *aCanGoBack = rootSH->CanGo(-1);
3104 MOZ_LOG(gSHLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "nsDocShell %p CanGoBack()->%d", this
, *aCanGoBack); } } while (0)
3105 ("nsDocShell %p CanGoBack()->%d", this, *aCanGoBack))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "nsDocShell %p CanGoBack()->%d", this
, *aCanGoBack); } } while (0)
;
3106
3107 return NS_OK;
3108 }
3109 return NS_ERROR_FAILURE;
3110}
3111
3112NS_IMETHODIMPnsresult
3113nsDocShell::GetCanGoForward(bool* aCanGoForward) {
3114 *aCanGoForward = false;
3115 if (!IsNavigationAllowed(false)) {
3116 return NS_OK; // JS may not handle returning of an error code
3117 }
3118 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
3119 if (rootSH) {
3120 *aCanGoForward = rootSH->CanGo(1);
3121 MOZ_LOG(gSHLog, LogLevel::Verbose,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "nsDocShell %p CanGoForward()->%d", this
, *aCanGoForward); } } while (0)
3122 ("nsDocShell %p CanGoForward()->%d", this, *aCanGoForward))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Verbose)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Verbose, "nsDocShell %p CanGoForward()->%d", this
, *aCanGoForward); } } while (0)
;
3123 return NS_OK;
3124 }
3125 return NS_ERROR_FAILURE;
3126}
3127
3128NS_IMETHODIMPnsresult
3129nsDocShell::GoBack(bool aRequireUserInteraction, bool aUserActivation) {
3130 if (!IsNavigationAllowed()) {
3131 return NS_OK; // JS may not handle returning of an error code
3132 }
3133
3134 auto cleanupIsNavigating = MakeScopeExit([&]() { mIsNavigating = false; });
3135 mIsNavigating = true;
3136
3137 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
3138 NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(rootSH)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "rootSH" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3138); return NS_ERROR_FAILURE; } } while (false)
;
3139 ErrorResult rv;
3140 rootSH->Go(-1, aRequireUserInteraction, aUserActivation, rv);
3141 return rv.StealNSResult();
3142}
3143
3144NS_IMETHODIMPnsresult
3145nsDocShell::GoForward(bool aRequireUserInteraction, bool aUserActivation) {
3146 if (!IsNavigationAllowed()) {
3147 return NS_OK; // JS may not handle returning of an error code
3148 }
3149
3150 auto cleanupIsNavigating = MakeScopeExit([&]() { mIsNavigating = false; });
3151 mIsNavigating = true;
3152
3153 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
3154 NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(rootSH)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "rootSH" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3154); return NS_ERROR_FAILURE; } } while (false)
;
3155 ErrorResult rv;
3156 rootSH->Go(1, aRequireUserInteraction, aUserActivation, rv);
3157 return rv.StealNSResult();
3158}
3159
3160// XXX(nika): We may want to stop exposing this API in the child process? Going
3161// to a specific index from multiple different processes could definitely race.
3162NS_IMETHODIMPnsresult
3163nsDocShell::GotoIndex(int32_t aIndex, bool aUserActivation) {
3164 if (!IsNavigationAllowed()) {
3165 return NS_OK; // JS may not handle returning of an error code
3166 }
3167
3168 auto cleanupIsNavigating = MakeScopeExit([&]() { mIsNavigating = false; });
3169 mIsNavigating = true;
3170
3171 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
3172 NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(rootSH)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "rootSH" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3172); return NS_ERROR_FAILURE; } } while (false)
;
3173
3174 ErrorResult rv;
3175 rootSH->GotoIndex(aIndex, aIndex - rootSH->Index(), false, aUserActivation,
3176 rv);
3177 return rv.StealNSResult();
3178}
3179
3180nsresult nsDocShell::LoadURI(nsIURI* aURI,
3181 const LoadURIOptions& aLoadURIOptions) {
3182 if (!IsNavigationAllowed()) {
3183 return NS_OK; // JS may not handle returning of an error code
3184 }
3185 RefPtr<nsDocShellLoadState> loadState;
3186 nsresult rv = nsDocShellLoadState::CreateFromLoadURIOptions(
3187 mBrowsingContext, aURI, aLoadURIOptions, getter_AddRefs(loadState));
3188 MOZ_ASSERT(rv != NS_ERROR_MALFORMED_URI)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(rv != NS_ERROR_MALFORMED_URI)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(rv != NS_ERROR_MALFORMED_URI
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"rv != NS_ERROR_MALFORMED_URI", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "rv != NS_ERROR_MALFORMED_URI"
")"); do { *((volatile int*)__null) = 3188; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3189 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !loadState) {
3190 return NS_ERROR_FAILURE;
3191 }
3192
3193 return LoadURI(loadState, true);
3194}
3195
3196NS_IMETHODIMPnsresult
3197nsDocShell::LoadURIFromScript(nsIURI* aURI,
3198 JS::Handle<JS::Value> aLoadURIOptions,
3199 JSContext* aCx) {
3200 // generate dictionary for aLoadURIOptions and forward call
3201 LoadURIOptions loadURIOptions;
3202 if (!loadURIOptions.Init(aCx, aLoadURIOptions)) {
3203 return NS_ERROR_INVALID_ARG;
3204 }
3205 return LoadURI(aURI, loadURIOptions);
3206}
3207
3208nsresult nsDocShell::FixupAndLoadURIString(
3209 const nsAString& aURIString, const LoadURIOptions& aLoadURIOptions) {
3210 if (!IsNavigationAllowed()) {
3211 return NS_OK; // JS may not handle returning of an error code
3212 }
3213
3214 RefPtr<nsDocShellLoadState> loadState;
3215 nsresult rv = nsDocShellLoadState::CreateFromLoadURIOptions(
3216 mBrowsingContext, aURIString, aLoadURIOptions, getter_AddRefs(loadState));
3217
3218 uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
3219 if (NS_ERROR_MALFORMED_URI == rv) {
3220 MOZ_LOG(gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Creating an active entry on nsDocShell %p to %s (because "
"we're showing an error page)", this, NS_ConvertUTF16toUTF8(
aURIString).get()); } } while (0)
3221 ("Creating an active entry on nsDocShell %p to %s (because "do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Creating an active entry on nsDocShell %p to %s (because "
"we're showing an error page)", this, NS_ConvertUTF16toUTF8(
aURIString).get()); } } while (0)
3222 "we're showing an error page)",do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Creating an active entry on nsDocShell %p to %s (because "
"we're showing an error page)", this, NS_ConvertUTF16toUTF8(
aURIString).get()); } } while (0)
3223 this, NS_ConvertUTF16toUTF8(aURIString).get()))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "Creating an active entry on nsDocShell %p to %s (because "
"we're showing an error page)", this, NS_ConvertUTF16toUTF8(
aURIString).get()); } } while (0)
;
3224
3225 // We need to store a session history entry. We don't have a valid URI, so
3226 // we use about:blank instead.
3227 nsCOMPtr<nsIURI> uri;
3228 MOZ_ALWAYS_SUCCEEDS(NS_NewURI(getter_AddRefs(uri), "about:blank"_ns))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(NS_NewURI(getter_AddRefs(uri), "about:blank"_ns))), 1)))), 1
))) { } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), \"about:blank\"_ns))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3228); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), \"about:blank\"_ns))"
")"); do { *((volatile int*)__null) = 3228; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3229 nsCOMPtr<nsIPrincipal> triggeringPrincipal;
3230 if (aLoadURIOptions.mTriggeringPrincipal) {
3231 triggeringPrincipal = aLoadURIOptions.mTriggeringPrincipal;
3232 } else {
3233 triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
3234 }
3235 if (mozilla::SessionHistoryInParent()) {
3236 mActiveEntry = MakeUnique<SessionHistoryInfo>(
3237 uri, triggeringPrincipal, nullptr, nullptr, nullptr,
3238 nsLiteralCString("text/html"));
3239 mBrowsingContext->SetActiveSessionHistoryEntry(
3240 Nothing(), mActiveEntry.get(), MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags)((LOAD_NORMAL) | ((loadFlags) << 16)),
3241 /* aUpdatedCacheKey = */ 0);
3242 }
3243 if (DisplayLoadError(rv, nullptr, PromiseFlatStringTPromiseFlatString<char16_t>(aURIString).get(),
3244 nullptr) &&
3245 (loadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) {
3246 return NS_ERROR_LOAD_SHOWED_ERRORPAGE;
3247 }
3248 }
3249
3250 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !loadState) {
3251 return NS_ERROR_FAILURE;
3252 }
3253
3254 return LoadURI(loadState, true);
3255}
3256
3257NS_IMETHODIMPnsresult
3258nsDocShell::FixupAndLoadURIStringFromScript(
3259 const nsAString& aURIString, JS::Handle<JS::Value> aLoadURIOptions,
3260 JSContext* aCx) {
3261 // generate dictionary for aLoadURIOptions and forward call
3262 LoadURIOptions loadURIOptions;
3263 if (!loadURIOptions.Init(aCx, aLoadURIOptions)) {
3264 return NS_ERROR_INVALID_ARG;
3265 }
3266 return FixupAndLoadURIString(aURIString, loadURIOptions);
3267}
3268
3269void nsDocShell::UnblockEmbedderLoadEventForFailure(bool aFireFrameErrorEvent) {
3270 // If we're not in a content frame, or are at a BrowsingContext tree boundary,
3271 // such as the content-chrome boundary, don't fire the error event.
3272 if (mBrowsingContext->IsTopContent() || mBrowsingContext->IsChrome()) {
3273 return;
3274 }
3275
3276 // If embedder is same-process, then unblocking the load event is already
3277 // handled by nsDocLoader. Fire the error event on our embedder element if
3278 // requested.
3279 //
3280 // XXX: Bug 1440212 is looking into potentially changing this behaviour to act
3281 // more like the remote case when in-process.
3282 RefPtr<Element> element = mBrowsingContext->GetEmbedderElement();
3283 if (element) {
3284 if (aFireFrameErrorEvent) {
3285 if (RefPtr<nsFrameLoaderOwner> flo = do_QueryObject(element)) {
3286 if (RefPtr<nsFrameLoader> fl = flo->GetFrameLoader()) {
3287 fl->FireErrorEvent();
3288 }
3289 }
3290 }
3291 return;
3292 }
3293
3294 // If we have a cross-process parent document, we must notify it that we no
3295 // longer block its load event. This is necessary for OOP sub-documents
3296 // because error documents do not result in a call to
3297 // SendMaybeFireEmbedderLoadEvents via any of the normal call paths.
3298 // (Obviously, we must do this before any of the returns below.)
3299 RefPtr<BrowserChild> browserChild = BrowserChild::GetFrom(this);
3300 if (browserChild &&
3301 !mBrowsingContext->GetParentWindowContext()->IsInProcess()) {
3302 mozilla::Unused << browserChild->SendMaybeFireEmbedderLoadEvents(
3303 aFireFrameErrorEvent ? EmbedderElementEventType::ErrorEvent
3304 : EmbedderElementEventType::NoEvent);
3305 }
3306}
3307
3308NS_IMETHODIMPnsresult
3309nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
3310 const char16_t* aURL, nsIChannel* aFailedChannel,
3311 bool* aDisplayedErrorPage) {
3312 MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p DisplayLoadError %s\n", this,
aURI ? aURI->GetSpecOrDefault().get() : ""); } } while (0
)
3313 ("DOCSHELL %p DisplayLoadError %s\n", this,do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p DisplayLoadError %s\n", this,
aURI ? aURI->GetSpecOrDefault().get() : ""); } } while (0
)
3314 aURI ? aURI->GetSpecOrDefault().get() : ""))do { const ::mozilla::LogModule* moz_real_module = gDocShellLeakLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "DOCSHELL %p DisplayLoadError %s\n", this,
aURI ? aURI->GetSpecOrDefault().get() : ""); } } while (0
)
;
3315
3316 *aDisplayedErrorPage = false;
3317 // Get prompt and string bundle services
3318 nsCOMPtr<nsIPrompt> prompter;
3319 nsCOMPtr<nsIStringBundle> stringBundle;
3320 GetPromptAndStringBundle(getter_AddRefs(prompter),
3321 getter_AddRefs(stringBundle));
3322
3323 NS_ENSURE_TRUE(stringBundle, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(stringBundle)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stringBundle" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3323); return NS_ERROR_FAILURE; } } while (false)
;
3324 NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(prompter)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prompter" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3324); return NS_ERROR_FAILURE; } } while (false)
;
3325
3326 const char* error = nullptr;
3327 // The key used to select the appropriate error message from the properties
3328 // file.
3329 const char* errorDescriptionID = nullptr;
3330 AutoTArray<nsString, 3> formatStrs;
3331 bool addHostPort = false;
3332 bool isBadStsCertError = false;
3333 nsresult rv = NS_OK;
3334 nsAutoString messageStr;
3335 nsAutoCString cssClass;
3336 nsAutoCString errorPage;
3337
3338 errorPage.AssignLiteral("neterror");
3339
3340 // Turn the error code into a human readable error message.
3341 if (NS_ERROR_UNKNOWN_PROTOCOL == aError) {
3342 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3342); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3343
3344 // Extract the schemes into a comma delimited list.
3345 nsAutoCString scheme;
3346 aURI->GetScheme(scheme);
3347 CopyASCIItoUTF16(scheme, *formatStrs.AppendElement());
3348 nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(aURI);
3349 while (nestedURI) {
3350 nsCOMPtr<nsIURI> tempURI;
3351 nsresult rv2;
3352 rv2 = nestedURI->GetInnerURI(getter_AddRefs(tempURI));
3353 if (NS_SUCCEEDED(rv2)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv2)), 1))) && tempURI) {
3354 tempURI->GetScheme(scheme);
3355 formatStrs[0].AppendLiteral(", ");
3356 AppendASCIItoUTF16(scheme, formatStrs[0]);
3357 }
3358 nestedURI = do_QueryInterface(tempURI);
3359 }
3360 error = "unknownProtocolFound";
3361 } else if (NS_ERROR_FILE_NOT_FOUND == aError) {
3362 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3362); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3363 error = "fileNotFound";
3364 } else if (NS_ERROR_FILE_ACCESS_DENIED == aError) {
3365 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3365); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3366 error = "fileAccessDenied";
3367 } else if (NS_ERROR_UNKNOWN_HOST == aError) {
3368 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3368); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3369 // Get the host
3370 nsAutoCString host;
3371 nsCOMPtr<nsIURI> innermostURI = NS_GetInnermostURI(aURI);
3372 innermostURI->GetHost(host);
3373 CopyUTF8toUTF16(host, *formatStrs.AppendElement());
3374 errorDescriptionID = "dnsNotFound2";
3375 error = "dnsNotFound";
3376 } else if (NS_ERROR_CONNECTION_REFUSED == aError ||
3377 NS_ERROR_PROXY_BAD_GATEWAY == aError) {
3378 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3378); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3379 addHostPort = true;
3380 error = "connectionFailure";
3381 } else if (NS_ERROR_NET_INTERRUPT == aError) {
3382 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3382); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3383 addHostPort = true;
3384 error = "netInterrupt";
3385 } else if (NS_ERROR_NET_TIMEOUT == aError ||
3386 NS_ERROR_PROXY_GATEWAY_TIMEOUT == aError ||
3387 NS_ERROR_NET_TIMEOUT_EXTERNAL == aError) {
3388 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3388); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3389 // Get the host
3390 nsAutoCString host;
3391 aURI->GetHost(host);
3392 CopyUTF8toUTF16(host, *formatStrs.AppendElement());
3393 error = "netTimeout";
3394 } else if (NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION == aError ||
3395 NS_ERROR_CSP_FORM_ACTION_VIOLATION == aError) {
3396 // CSP error
3397 cssClass.AssignLiteral("neterror");
3398 error = "cspBlocked";
3399 } else if (NS_ERROR_XFO_VIOLATION == aError) {
3400 // XFO error
3401 cssClass.AssignLiteral("neterror");
3402 error = "xfoBlocked";
3403 } else if (NS_ERROR_GET_MODULE(aError) == NS_ERROR_MODULE_SECURITY21) {
3404 nsCOMPtr<nsINSSErrorsService> nsserr =
3405 do_GetService(NS_NSS_ERRORS_SERVICE_CONTRACTID"@mozilla.org/nss_errors_service;1");
3406
3407 uint32_t errorClass;
3408 if (!nsserr || NS_FAILED(nsserr->GetErrorClass(aError, &errorClass))((bool)(__builtin_expect(!!(NS_FAILED_impl(nsserr->GetErrorClass
(aError, &errorClass))), 0)))
) {
3409 errorClass = nsINSSErrorsService::ERROR_CLASS_SSL_PROTOCOL;
3410 }
3411
3412 nsCOMPtr<nsITransportSecurityInfo> tsi;
3413 if (aFailedChannel) {
3414 aFailedChannel->GetSecurityInfo(getter_AddRefs(tsi));
3415 }
3416 if (tsi) {
3417 uint32_t securityState;
3418 tsi->GetSecurityState(&securityState);
3419 if (securityState & nsIWebProgressListener::STATE_USES_SSL_3) {
3420 error = "sslv3Used";
3421 addHostPort = true;
3422 } else if (securityState &
3423 nsIWebProgressListener::STATE_USES_WEAK_CRYPTO) {
3424 error = "weakCryptoUsed";
Value stored to 'error' is never read
3425 addHostPort = true;
3426 }
3427 } else {
3428 // No channel, let's obtain the generic error message
3429 if (nsserr) {
3430 nsserr->GetErrorMessage(aError, messageStr);
3431 }
3432 }
3433 // We don't have a message string here anymore but DisplayLoadError
3434 // requires a non-empty messageStr.
3435 messageStr.Truncate();
3436 messageStr.AssignLiteral(u" ");
3437 if (errorClass == nsINSSErrorsService::ERROR_CLASS_BAD_CERT) {
3438 error = "nssBadCert";
3439
3440 // If this is an HTTP Strict Transport Security host or a pinned host
3441 // and the certificate is bad, don't allow overrides (RFC 6797 section
3442 // 12.1).
3443 bool isStsHost = false;
3444 bool isPinnedHost = false;
3445 OriginAttributes attrsForHSTS;
3446 if (aFailedChannel) {
3447 StoragePrincipalHelper::GetOriginAttributesForHSTS(aFailedChannel,
3448 attrsForHSTS);
3449 } else {
3450 attrsForHSTS = GetOriginAttributes();
3451 }
3452
3453 if (XRE_IsParentProcess()) {
3454 nsCOMPtr<nsISiteSecurityService> sss =
3455 do_GetService(NS_SSSERVICE_CONTRACTID"@mozilla.org/ssservice;1", &rv);
3456 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3456); return rv; } } while (false)
;
3457 rv = sss->IsSecureURI(aURI, attrsForHSTS, &isStsHost);
3458 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3458); return rv; } } while (false)
;
3459 } else {
3460 mozilla::dom::ContentChild* cc =
3461 mozilla::dom::ContentChild::GetSingleton();
3462 cc->SendIsSecureURI(aURI, attrsForHSTS, &isStsHost);
3463 }
3464 nsCOMPtr<nsIPublicKeyPinningService> pkps =
3465 do_GetService(NS_PKPSERVICE_CONTRACTID"@mozilla.org/security/publickeypinningservice;1", &rv);
3466 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3466); return rv; } } while (false)
;
3467 rv = pkps->HostHasPins(aURI, &isPinnedHost);
3468
3469 if (Preferences::GetBool("browser.xul.error_pages.expert_bad_cert",
3470 false)) {
3471 cssClass.AssignLiteral("expertBadCert");
3472 }
3473
3474 // HSTS/pinning takes precedence over the expert bad cert pref. We
3475 // never want to show the "Add Exception" button for these sites.
3476 // In the future we should differentiate between an HSTS host and a
3477 // pinned host and display a more informative message to the user.
3478 if (isStsHost || isPinnedHost) {
3479 isBadStsCertError = true;
3480 cssClass.AssignLiteral("badStsCert");
3481 }
3482
3483 errorPage.Assign("certerror");
3484 } else {
3485 error = "nssFailure2";
3486 }
3487 } else if (NS_ERROR_PHISHING_URI == aError ||
3488 NS_ERROR_MALWARE_URI == aError ||
3489 NS_ERROR_UNWANTED_URI == aError ||
3490 NS_ERROR_HARMFUL_URI == aError) {
3491 nsAutoCString host;
3492 aURI->GetHost(host);
3493 CopyUTF8toUTF16(host, *formatStrs.AppendElement());
3494
3495 // Malware and phishing detectors may want to use an alternate error
3496 // page, but if the pref's not set, we'll fall back on the standard page
3497 nsAutoCString alternateErrorPage;
3498 nsresult rv = Preferences::GetCString("urlclassifier.alternate_error_page",
3499 alternateErrorPage);
3500 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3501 errorPage.Assign(alternateErrorPage);
3502 }
3503
3504 if (NS_ERROR_PHISHING_URI == aError) {
3505 error = "deceptiveBlocked";
3506 } else if (NS_ERROR_MALWARE_URI == aError) {
3507 error = "malwareBlocked";
3508 } else if (NS_ERROR_UNWANTED_URI == aError) {
3509 error = "unwantedBlocked";
3510 } else if (NS_ERROR_HARMFUL_URI == aError) {
3511 error = "harmfulBlocked";
3512 }
3513
3514 cssClass.AssignLiteral("blacklist");
3515 } else if (NS_ERROR_CONTENT_CRASHED == aError) {
3516 errorPage.AssignLiteral("tabcrashed");
3517 error = "tabcrashed";
3518
3519 RefPtr<EventTarget> handler = mChromeEventHandler;
3520 if (handler) {
3521 nsCOMPtr<Element> element = do_QueryInterface(handler);
3522 element->GetAttribute(u"crashedPageTitle"_ns, messageStr);
3523 }
3524
3525 // DisplayLoadError requires a non-empty messageStr to proceed and call
3526 // LoadErrorPage. If the page doesn't have a title, we will use a blank
3527 // space which will be trimmed and thus treated as empty by the front-end.
3528 if (messageStr.IsEmpty()) {
3529 messageStr.AssignLiteral(u" ");
3530 }
3531 } else if (NS_ERROR_FRAME_CRASHED == aError) {
3532 errorPage.AssignLiteral("framecrashed");
3533 error = "framecrashed";
3534 messageStr.AssignLiteral(u" ");
3535 } else if (NS_ERROR_BUILDID_MISMATCH == aError) {
3536 errorPage.AssignLiteral("restartrequired");
3537 error = "restartrequired";
3538
3539 // DisplayLoadError requires a non-empty messageStr to proceed and call
3540 // LoadErrorPage. If the page doesn't have a title, we will use a blank
3541 // space which will be trimmed and thus treated as empty by the front-end.
3542 if (messageStr.IsEmpty()) {
3543 messageStr.AssignLiteral(u" ");
3544 }
3545 } else {
3546 // Errors requiring simple formatting
3547 switch (aError) {
3548 case NS_ERROR_MALFORMED_URI:
3549 // URI is malformed
3550 error = "malformedURI";
3551 errorDescriptionID = "malformedURI2";
3552 break;
3553 case NS_ERROR_REDIRECT_LOOP:
3554 // Doc failed to load because the server generated too many redirects
3555 error = "redirectLoop";
3556 break;
3557 case NS_ERROR_UNKNOWN_SOCKET_TYPE:
3558 // Doc failed to load because PSM is not installed
3559 error = "unknownSocketType";
3560 break;
3561 case NS_ERROR_NET_RESET:
3562 // Doc failed to load because the server kept reseting the connection
3563 // before we could read any data from it
3564 error = "netReset";
3565 break;
3566 case NS_ERROR_DOCUMENT_NOT_CACHED:
3567 // Doc failed to load because the cache does not contain a copy of
3568 // the document.
3569 error = "notCached";
3570 break;
3571 case NS_ERROR_OFFLINE:
3572 // Doc failed to load because we are offline.
3573 error = "netOffline";
3574 break;
3575 case NS_ERROR_DOCUMENT_IS_PRINTMODE:
3576 // Doc navigation attempted while Printing or Print Preview
3577 error = "isprinting";
3578 break;
3579 case NS_ERROR_PORT_ACCESS_NOT_ALLOWED:
3580 // Port blocked for security reasons
3581 addHostPort = true;
3582 error = "deniedPortAccess";
3583 break;
3584 case NS_ERROR_UNKNOWN_PROXY_HOST:
3585 // Proxy hostname could not be resolved.
3586 error = "proxyResolveFailure";
3587 break;
3588 case NS_ERROR_PROXY_CONNECTION_REFUSED:
3589 case NS_ERROR_PROXY_FORBIDDEN:
3590 case NS_ERROR_PROXY_NOT_IMPLEMENTED:
3591 case NS_ERROR_PROXY_AUTHENTICATION_FAILED:
3592 case NS_ERROR_PROXY_TOO_MANY_REQUESTS:
3593 // Proxy connection was refused.
3594 error = "proxyConnectFailure";
3595 break;
3596 case NS_ERROR_INVALID_CONTENT_ENCODING:
3597 // Bad Content Encoding.
3598 error = "contentEncodingError";
3599 break;
3600 case NS_ERROR_UNSAFE_CONTENT_TYPE:
3601 // Channel refused to load from an unrecognized content type.
3602 error = "unsafeContentType";
3603 break;
3604 case NS_ERROR_CORRUPTED_CONTENT:
3605 // Broken Content Detected. e.g. Content-MD5 check failure.
3606 error = "corruptedContentErrorv2";
3607 break;
3608 case NS_ERROR_INTERCEPTION_FAILED:
3609 // ServiceWorker intercepted request, but something went wrong.
3610 error = "corruptedContentErrorv2";
3611 break;
3612 case NS_ERROR_NET_INADEQUATE_SECURITY:
3613 // Server negotiated bad TLS for HTTP/2.
3614 error = "inadequateSecurityError";
3615 addHostPort = true;
3616 break;
3617 case NS_ERROR_BLOCKED_BY_POLICY:
3618 case NS_ERROR_DOM_COOP_FAILED:
3619 case NS_ERROR_DOM_COEP_FAILED:
3620 // Page blocked by policy
3621 error = "blockedByPolicy";
3622 break;
3623 case NS_ERROR_NET_HTTP2_SENT_GOAWAY:
3624 case NS_ERROR_NET_HTTP3_PROTOCOL_ERROR:
3625 // HTTP/2 or HTTP/3 stack detected a protocol error
3626 error = "networkProtocolError";
3627 break;
3628
3629 default:
3630 break;
3631 }
3632 }
3633
3634 nsresult delegateErrorCode = aError;
3635 // If the HTTPS-Only Mode upgraded this request and the upgrade might have
3636 // caused this error, we replace the error-page with about:httpsonlyerror
3637 if (nsHTTPSOnlyUtils::CouldBeHttpsOnlyError(aFailedChannel, aError)) {
3638 errorPage.AssignLiteral("httpsonlyerror");
3639 delegateErrorCode = NS_ERROR_HTTPS_ONLY;
3640 } else if (isBadStsCertError) {
3641 delegateErrorCode = NS_ERROR_BAD_HSTS_CERT;
3642 }
3643
3644 if (nsCOMPtr<nsILoadURIDelegate> loadURIDelegate = GetLoadURIDelegate()) {
3645 nsCOMPtr<nsIURI> errorPageURI;
3646 rv = loadURIDelegate->HandleLoadError(
3647 aURI, delegateErrorCode, NS_ERROR_GET_MODULE(delegateErrorCode),
3648 getter_AddRefs(errorPageURI));
3649 // If the docshell is going away there's no point in showing an error page.
3650 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || mIsBeingDestroyed) {
3651 *aDisplayedErrorPage = false;
3652 return NS_OK;
3653 }
3654
3655 if (errorPageURI) {
3656 *aDisplayedErrorPage =
3657 NS_SUCCEEDED(LoadErrorPage(errorPageURI, aURI, aFailedChannel))((bool)(__builtin_expect(!!(!NS_FAILED_impl(LoadErrorPage(errorPageURI
, aURI, aFailedChannel))), 1)))
;
3658 return NS_OK;
3659 }
3660 }
3661
3662 // Test if the error should be displayed
3663 if (!error) {
3664 return NS_OK;
3665 }
3666
3667 if (!errorDescriptionID) {
3668 errorDescriptionID = error;
3669 }
3670
3671 Telemetry::AccumulateCategoricalKeyed(
3672 IsSubframe() ? "frame"_ns : "top"_ns,
3673 mozilla::dom::LoadErrorToTelemetryLabel(aError));
3674
3675 // Test if the error needs to be formatted
3676 if (!messageStr.IsEmpty()) {
3677 // already obtained message
3678 } else {
3679 if (addHostPort) {
3680 // Build up the host:port string.
3681 nsAutoCString hostport;
3682 if (aURI) {
3683 aURI->GetHostPort(hostport);
3684 } else {
3685 hostport.Assign('?');
3686 }
3687 CopyUTF8toUTF16(hostport, *formatStrs.AppendElement());
3688 }
3689
3690 nsAutoCString spec;
3691 rv = NS_ERROR_NOT_AVAILABLE;
3692 auto& nextFormatStr = *formatStrs.AppendElement();
3693 if (aURI) {
3694 // displaying "file://" is aesthetically unpleasing and could even be
3695 // confusing to the user
3696 if (SchemeIsFile(aURI)) {
3697 aURI->GetPathQueryRef(spec);
3698 } else {
3699 aURI->GetSpec(spec);
3700 }
3701
3702 nsCOMPtr<nsITextToSubURI> textToSubURI(
3703 do_GetService(NS_ITEXTTOSUBURI_CONTRACTID"@mozilla.org/intl/texttosuburi;1", &rv));
3704 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3705 rv = textToSubURI->UnEscapeURIForUI(spec, nextFormatStr);
3706 }
3707 } else {
3708 spec.Assign('?');
3709 }
3710 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3711 CopyUTF8toUTF16(spec, nextFormatStr);
3712 }
3713 rv = NS_OK;
3714
3715 nsAutoString str;
3716 rv =
3717 stringBundle->FormatStringFromName(errorDescriptionID, formatStrs, str);
3718 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3718); return rv; } } while (false)
;
3719 messageStr.Assign(str);
3720 }
3721
3722 // Display the error as a page or an alert prompt
3723 NS_ENSURE_FALSE(messageStr.IsEmpty(), NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(!(messageStr.IsEmpty()))), 0)
)) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!(messageStr.IsEmpty())"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3723); return NS_ERROR_FAILURE; } } while (false)
;
3724
3725 if ((NS_ERROR_NET_INTERRUPT == aError || NS_ERROR_NET_RESET == aError) &&
3726 SchemeIsHTTPS(aURI)) {
3727 // Maybe TLS intolerant. Treat this as an SSL error.
3728 error = "nssFailure2";
3729 }
3730
3731 if (mBrowsingContext->GetUseErrorPages()) {
3732 // Display an error page
3733 nsresult loadedPage =
3734 LoadErrorPage(aURI, aURL, errorPage.get(), error, messageStr.get(),
3735 cssClass.get(), aFailedChannel);
3736 *aDisplayedErrorPage = NS_SUCCEEDED(loadedPage)((bool)(__builtin_expect(!!(!NS_FAILED_impl(loadedPage)), 1))
)
;
3737 } else {
3738 // The prompter reqires that our private window has a document (or it
3739 // asserts). Satisfy that assertion now since GetDoc will force
3740 // creation of one if it hasn't already been created.
3741 if (mScriptGlobal) {
3742 Unused << mScriptGlobal->GetDoc();
3743 }
3744
3745 // Display a message box
3746 prompter->Alert(nullptr, messageStr.get());
3747 }
3748
3749 return NS_OK;
3750}
3751
3752#define PREF_SAFEBROWSING_ALLOWOVERRIDE"browser.safebrowsing.allowOverride" "browser.safebrowsing.allowOverride"
3753
3754nsresult nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
3755 const char* aErrorPage,
3756 const char* aErrorType,
3757 const char16_t* aDescription,
3758 const char* aCSSClass,
3759 nsIChannel* aFailedChannel) {
3760 if (mIsBeingDestroyed) {
3761 return NS_ERROR_NOT_AVAILABLE;
3762 }
3763
3764#if defined(DEBUG1)
3765 if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gDocShellLog, LogLevel
::Debug)), 0))
) {
3766 nsAutoCString chanName;
3767 if (aFailedChannel) {
3768 aFailedChannel->GetName(chanName);
3769 } else {
3770 chanName.AssignLiteral("<no channel>");
3771 }
3772
3773 MOZ_LOG(gDocShellLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gDocShellLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n"
, this, aURI ? aURI->GetSpecOrDefault().get() : "", NS_ConvertUTF16toUTF8
(aURL).get(), chanName.get()); } } while (0)
3774 ("nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n",do { const ::mozilla::LogModule* moz_real_module = gDocShellLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n"
, this, aURI ? aURI->GetSpecOrDefault().get() : "", NS_ConvertUTF16toUTF8
(aURL).get(), chanName.get()); } } while (0)
3775 this, aURI ? aURI->GetSpecOrDefault().get() : "",do { const ::mozilla::LogModule* moz_real_module = gDocShellLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n"
, this, aURI ? aURI->GetSpecOrDefault().get() : "", NS_ConvertUTF16toUTF8
(aURL).get(), chanName.get()); } } while (0)
3776 NS_ConvertUTF16toUTF8(aURL).get(), chanName.get()))do { const ::mozilla::LogModule* moz_real_module = gDocShellLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n"
, this, aURI ? aURI->GetSpecOrDefault().get() : "", NS_ConvertUTF16toUTF8
(aURL).get(), chanName.get()); } } while (0)
;
3777 }
3778#endif
3779
3780 nsAutoCString url;
3781 if (aURI) {
3782 nsresult rv = aURI->GetSpec(url);
3783 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3783); return rv; } } while (false)
;
3784 } else if (aURL) {
3785 CopyUTF16toUTF8(MakeStringSpan(aURL), url);
3786 } else {
3787 return NS_ERROR_INVALID_POINTER;
3788 }
3789
3790 // Create a URL to pass all the error information through to the page.
3791
3792#undef SAFE_ESCAPE
3793#define SAFE_ESCAPE(output, input, params)if (NS_warn_if_impl(!NS_Escape(input, output, params), "!NS_Escape(input, output, params)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3793)) { return NS_ERROR_OUT_OF_MEMORY; }
\
3794 if (NS_WARN_IF(!NS_Escape(input, output, params))NS_warn_if_impl(!NS_Escape(input, output, params), "!NS_Escape(input, output, params)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3794)
) { \
3795 return NS_ERROR_OUT_OF_MEMORY; \
3796 }
3797
3798 nsCString escapedUrl, escapedError, escapedDescription, escapedCSSClass;
3799 SAFE_ESCAPE(escapedUrl, url, url_Path)if (NS_warn_if_impl(!NS_Escape(url, escapedUrl, url_Path), "!NS_Escape(url, escapedUrl, url_Path)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3799)) { return NS_ERROR_OUT_OF_MEMORY; }
;
3800 SAFE_ESCAPE(escapedError, nsDependentCString(aErrorType), url_Path)if (NS_warn_if_impl(!NS_Escape(nsDependentCString(aErrorType)
, escapedError, url_Path), "!NS_Escape(nsDependentCString(aErrorType), escapedError, url_Path)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3800)) { return NS_ERROR_OUT_OF_MEMORY; }
;
3801 SAFE_ESCAPE(escapedDescription, NS_ConvertUTF16toUTF8(aDescription),if (NS_warn_if_impl(!NS_Escape(NS_ConvertUTF16toUTF8(aDescription
), escapedDescription, url_Path), "!NS_Escape(NS_ConvertUTF16toUTF8(aDescription), escapedDescription, url_Path)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3802)) { return NS_ERROR_OUT_OF_MEMORY; }
3802 url_Path)if (NS_warn_if_impl(!NS_Escape(NS_ConvertUTF16toUTF8(aDescription
), escapedDescription, url_Path), "!NS_Escape(NS_ConvertUTF16toUTF8(aDescription), escapedDescription, url_Path)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3802)) { return NS_ERROR_OUT_OF_MEMORY; }
;
3803 if (aCSSClass) {
3804 nsCString cssClass(aCSSClass);
3805 SAFE_ESCAPE(escapedCSSClass, cssClass, url_Path)if (NS_warn_if_impl(!NS_Escape(cssClass, escapedCSSClass, url_Path
), "!NS_Escape(cssClass, escapedCSSClass, url_Path)", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3805)) { return NS_ERROR_OUT_OF_MEMORY; }
;
3806 }
3807 nsCString errorPageUrl("about:");
3808 errorPageUrl.AppendASCII(aErrorPage);
3809 errorPageUrl.AppendLiteral("?e=");
3810
3811 errorPageUrl.AppendASCII(escapedError.get());
3812 errorPageUrl.AppendLiteral("&u=");
3813 errorPageUrl.AppendASCII(escapedUrl.get());
3814 if ((strcmp(aErrorPage, "blocked") == 0) &&
3815 Preferences::GetBool(PREF_SAFEBROWSING_ALLOWOVERRIDE"browser.safebrowsing.allowOverride", true)) {
3816 errorPageUrl.AppendLiteral("&o=1");
3817 }
3818 if (!escapedCSSClass.IsEmpty()) {
3819 errorPageUrl.AppendLiteral("&s=");
3820 errorPageUrl.AppendASCII(escapedCSSClass.get());
3821 }
3822 errorPageUrl.AppendLiteral("&c=UTF-8");
3823
3824 nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CID{ 0xbdbe0555, 0xfc3d, 0x4f7b, { 0x92, 0x05, 0xc3, 0x09, 0xce,
0xb2, 0xd6, 0x41 } }
);
3825 int32_t cpsState;
3826 if (cps && NS_SUCCEEDED(cps->GetState(&cpsState))((bool)(__builtin_expect(!!(!NS_FAILED_impl(cps->GetState(
&cpsState))), 1)))
&&
3827 cpsState == nsICaptivePortalService::LOCKED_PORTAL) {
3828 errorPageUrl.AppendLiteral("&captive=true");
3829 }
3830
3831 errorPageUrl.AppendLiteral("&d=");
3832 errorPageUrl.AppendASCII(escapedDescription.get());
3833
3834 nsCOMPtr<nsIURI> errorPageURI;
3835 nsresult rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
3836 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3836); return rv; } } while (false)
;
3837
3838 return LoadErrorPage(errorPageURI, aURI, aFailedChannel);
3839}
3840
3841nsresult nsDocShell::LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI,
3842 nsIChannel* aFailedChannel) {
3843 mFailedChannel = aFailedChannel;
3844 mFailedURI = aFailedURI;
3845 mFailedLoadType = mLoadType;
3846
3847 if (mLSHE) {
3848 // Abandon mLSHE's BFCache entry and create a new one. This way, if
3849 // we go back or forward to another SHEntry with the same doc
3850 // identifier, the error page won't persist.
3851 mLSHE->AbandonBFCacheEntry();
3852 }
3853
3854 RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aErrorURI);
3855 loadState->SetTriggeringPrincipal(nsContentUtils::GetSystemPrincipal());
3856 if (mBrowsingContext) {
3857 loadState->SetTriggeringSandboxFlags(mBrowsingContext->GetSandboxFlags());
3858 loadState->SetTriggeringWindowId(
3859 mBrowsingContext->GetCurrentInnerWindowId());
3860 nsPIDOMWindowInner* innerWin = mScriptGlobal->GetCurrentInnerWindow();
3861 if (innerWin) {
3862 loadState->SetTriggeringStorageAccess(innerWin->UsingStorageAccess());
3863 }
3864 }
3865 loadState->SetLoadType(LOAD_ERROR_PAGE);
3866 loadState->SetFirstParty(true);
3867 loadState->SetSourceBrowsingContext(mBrowsingContext);
3868 if (mozilla::SessionHistoryInParent() && mLoadingEntry) {
3869 // We keep the loading entry for the load that failed here. If the user
3870 // reloads we want to try to reload the original load, not the error page.
3871 loadState->SetLoadingSessionHistoryInfo(
3872 MakeUnique<LoadingSessionHistoryInfo>(*mLoadingEntry));
3873 }
3874 return InternalLoad(loadState);
3875}
3876
3877NS_IMETHODIMPnsresult
3878nsDocShell::Reload(uint32_t aReloadFlags) {
3879 if (!IsNavigationAllowed()) {
3880 return NS_OK; // JS may not handle returning of an error code
3881 }
3882
3883 NS_ASSERTION(((aReloadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0),do { if (!(((aReloadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0))) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Reload command not updated to use load flags!"
, "((aReloadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3884); MOZ_PretendNoReturn(); } } while (0)
3884 "Reload command not updated to use load flags!")do { if (!(((aReloadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0))) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Reload command not updated to use load flags!"
, "((aReloadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3884); MOZ_PretendNoReturn(); } } while (0)
;
3885 NS_ASSERTION((aReloadFlags & EXTRA_LOAD_FLAGS) == 0,do { if (!((aReloadFlags & (nsIWebNavigation::LOAD_FLAGS_FROM_EXTERNAL
| nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD | nsIWebNavigation
::LOAD_FLAGS_ALLOW_POPUPS | 0xffff0000)) == 0)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "Don't pass these flags to Reload", "(aReloadFlags & EXTRA_LOAD_FLAGS) == 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3886); MOZ_PretendNoReturn(); } } while (0)
3886 "Don't pass these flags to Reload")do { if (!((aReloadFlags & (nsIWebNavigation::LOAD_FLAGS_FROM_EXTERNAL
| nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD | nsIWebNavigation
::LOAD_FLAGS_ALLOW_POPUPS | 0xffff0000)) == 0)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "Don't pass these flags to Reload", "(aReloadFlags & EXTRA_LOAD_FLAGS) == 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3886); MOZ_PretendNoReturn(); } } while (0)
;
3887
3888 uint32_t loadType = MAKE_LOAD_TYPE(LOAD_RELOAD_NORMAL, aReloadFlags)((LOAD_RELOAD_NORMAL) | ((aReloadFlags) << 16));
3889 NS_ENSURE_TRUE(IsValidLoadType(loadType), NS_ERROR_INVALID_ARG)do { if ((__builtin_expect(!!(!(IsValidLoadType(loadType))), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "IsValidLoadType(loadType)"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3889); return NS_ERROR_INVALID_ARG; } } while (false)
;
3890
3891 // Send notifications to the HistoryListener if any, about the impending
3892 // reload
3893 RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
3894 if (mozilla::SessionHistoryInParent()) {
3895 MOZ_LOG(gSHLog, LogLevel::Debug, ("nsDocShell %p Reload", this))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p Reload", this); } } while (
0)
;
3896 bool forceReload = IsForceReloadType(loadType);
3897 if (!XRE_IsParentProcess()) {
3898 ++mPendingReloadCount;
3899 RefPtr<nsDocShell> docShell(this);
3900 nsCOMPtr<nsIDocumentViewer> viewer(mDocumentViewer);
3901 NS_ENSURE_STATE(viewer)do { if ((__builtin_expect(!!(!(viewer)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "viewer" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 3901); return NS_ERROR_UNEXPECTED; } } while (false)
;
3902
3903 bool okToUnload = true;
3904 MOZ_TRY(viewer->PermitUnload(&okToUnload))do { auto mozTryTempResult_ = ::mozilla::ToResult(viewer->
PermitUnload(&okToUnload)); if ((__builtin_expect(!!(mozTryTempResult_
.isErr()), 0))) { return mozTryTempResult_.propagateErr(); } }
while (0)
;
3905 if (!okToUnload) {
3906 return NS_OK;
3907 }
3908
3909 RefPtr<Document> doc(GetDocument());
3910 RefPtr<BrowsingContext> browsingContext(mBrowsingContext);
3911 nsCOMPtr<nsIURI> currentURI(mCurrentURI);
3912 nsCOMPtr<nsIReferrerInfo> referrerInfo(mReferrerInfo);
3913 RefPtr<StopDetector> stopDetector = new StopDetector();
3914 nsCOMPtr<nsILoadGroup> loadGroup;
3915 GetLoadGroup(getter_AddRefs(loadGroup));
3916 if (loadGroup) {
3917 // loadGroup may be null in theory. In that case stopDetector just
3918 // doesn't do anything.
3919 loadGroup->AddRequest(stopDetector, nullptr);
3920 }
3921
3922 ContentChild::GetSingleton()->SendNotifyOnHistoryReload(
3923 mBrowsingContext, forceReload,
3924 [docShell, doc, loadType, browsingContext, currentURI, referrerInfo,
3925 loadGroup, stopDetector](
3926 std::tuple<bool, Maybe<NotNull<RefPtr<nsDocShellLoadState>>>,
3927 Maybe<bool>>&& aResult) {
3928 auto scopeExit = MakeScopeExit([loadGroup, stopDetector]() {
3929 if (loadGroup) {
3930 loadGroup->RemoveRequest(stopDetector, nullptr, NS_OK);
3931 }
3932 });
3933
3934 // Decrease mPendingReloadCount before any other early returns!
3935 if (--(docShell->mPendingReloadCount) > 0) {
3936 return;
3937 }
3938
3939 if (stopDetector->Canceled()) {
3940 return;
3941 }
3942 bool canReload;
3943 Maybe<NotNull<RefPtr<nsDocShellLoadState>>> loadState;
3944 Maybe<bool> reloadingActiveEntry;
3945
3946 std::tie(canReload, loadState, reloadingActiveEntry) = aResult;
3947
3948 if (!canReload) {
3949 return;
3950 }
3951
3952 if (loadState.isSome()) {
3953 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p Reload - LoadHistoryEntry",
docShell.get()); } } while (0)
3954 gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p Reload - LoadHistoryEntry",
docShell.get()); } } while (0)
3955 ("nsDocShell %p Reload - LoadHistoryEntry", docShell.get()))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p Reload - LoadHistoryEntry",
docShell.get()); } } while (0)
;
3956 loadState.ref()->SetNotifiedBeforeUnloadListeners(true);
3957 docShell->LoadHistoryEntry(loadState.ref(), loadType,
3958 reloadingActiveEntry.ref());
3959 } else {
3960 MOZ_LOG(gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p ReloadDocument", docShell.get
()); } } while (0)
3961 ("nsDocShell %p ReloadDocument", docShell.get()))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p ReloadDocument", docShell.get
()); } } while (0)
;
3962 ReloadDocument(docShell, doc, loadType, browsingContext,
3963 currentURI, referrerInfo,
3964 /* aNotifiedBeforeUnloadListeners */ true);
3965 }
3966 },
3967 [](mozilla::ipc::ResponseRejectReason) {});
3968 } else {
3969 // Parent process
3970 bool canReload = false;
3971 Maybe<NotNull<RefPtr<nsDocShellLoadState>>> loadState;
3972 Maybe<bool> reloadingActiveEntry;
3973 if (!mBrowsingContext->IsDiscarded()) {
3974 mBrowsingContext->Canonical()->NotifyOnHistoryReload(
3975 forceReload, canReload, loadState, reloadingActiveEntry);
3976 }
3977 if (canReload) {
3978 if (loadState.isSome()) {
3979 MOZ_LOG(gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p Reload - LoadHistoryEntry",
this); } } while (0)
3980 ("nsDocShell %p Reload - LoadHistoryEntry", this))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p Reload - LoadHistoryEntry",
this); } } while (0)
;
3981 LoadHistoryEntry(loadState.ref(), loadType,
3982 reloadingActiveEntry.ref());
3983 } else {
3984 MOZ_LOG(gSHLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p ReloadDocument", this); } }
while (0)
3985 ("nsDocShell %p ReloadDocument", this))do { const ::mozilla::LogModule* moz_real_module = gSHLog; if
((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "nsDocShell %p ReloadDocument", this); } }
while (0)
;
3986 RefPtr<Document> doc = GetDocument();
3987 RefPtr<BrowsingContext> bc = mBrowsingContext;
3988 nsCOMPtr<nsIURI> currentURI = mCurrentURI;
3989 nsCOMPtr<nsIReferrerInfo> referrerInfo = mReferrerInfo;
3990 ReloadDocument(this, doc, loadType, bc, currentURI, referrerInfo);
3991 }
3992 }
3993 }
3994 return NS_OK;
3995 }
3996
3997 bool canReload = true;
3998 if (rootSH) {
3999 rootSH->LegacySHistory()->NotifyOnHistoryReload(&canReload);
4000 }
4001
4002 if (!canReload) {
4003 return NS_OK;
4004 }
4005
4006 /* If you change this part of code, make sure bug 45297 does not re-occur */
4007 if (mOSHE) {
4008 nsCOMPtr<nsISHEntry> oshe = mOSHE;
4009 return LoadHistoryEntry(
4010 oshe, loadType,
4011 aReloadFlags & nsIWebNavigation::LOAD_FLAGS_USER_ACTIVATION);
4012 }
4013
4014 if (mLSHE) { // In case a reload happened before the current load is done
4015 nsCOMPtr<nsISHEntry> lshe = mLSHE;
4016 return LoadHistoryEntry(
4017 lshe, loadType,
4018 aReloadFlags & nsIWebNavigation::LOAD_FLAGS_USER_ACTIVATION);
4019 }
4020
4021 RefPtr<Document> doc = GetDocument();
4022 RefPtr<BrowsingContext> bc = mBrowsingContext;
4023 nsCOMPtr<nsIURI> currentURI = mCurrentURI;
4024 nsCOMPtr<nsIReferrerInfo> referrerInfo = mReferrerInfo;
4025 return ReloadDocument(this, doc, loadType, bc, currentURI, referrerInfo);
4026}
4027
4028/* static */
4029nsresult nsDocShell::ReloadDocument(nsDocShell* aDocShell, Document* aDocument,
4030 uint32_t aLoadType,
4031 BrowsingContext* aBrowsingContext,
4032 nsIURI* aCurrentURI,
4033 nsIReferrerInfo* aReferrerInfo,
4034 bool aNotifiedBeforeUnloadListeners) {
4035 if (!aDocument) {
4036 return NS_OK;
4037 }
4038
4039 // Do not inherit owner from document
4040 uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
4041 nsAutoString srcdoc;
4042 nsIURI* baseURI = nullptr;
4043 nsCOMPtr<nsIURI> originalURI;
4044 nsCOMPtr<nsIURI> resultPrincipalURI;
4045 bool loadReplace = false;
4046
4047 nsIPrincipal* triggeringPrincipal = aDocument->NodePrincipal();
4048 nsCOMPtr<nsIContentSecurityPolicy> csp = aDocument->GetCsp();
4049 uint32_t triggeringSandboxFlags = aDocument->GetSandboxFlags();
4050 uint64_t triggeringWindowId = aDocument->InnerWindowID();
4051 bool triggeringStorageAccess = aDocument->UsingStorageAccess();
4052
4053 nsAutoString contentTypeHint;
4054 aDocument->GetContentType(contentTypeHint);
4055
4056 if (aDocument->IsSrcdocDocument()) {
4057 aDocument->GetSrcdocData(srcdoc);
4058 flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
4059 baseURI = aDocument->GetBaseURI();
4060 } else {
4061 srcdoc = VoidString();
4062 }
4063 nsCOMPtr<nsIChannel> chan = aDocument->GetChannel();
4064 if (chan) {
4065 uint32_t loadFlags;
4066 chan->GetLoadFlags(&loadFlags);
4067 loadReplace = loadFlags & nsIChannel::LOAD_REPLACE;
4068 nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
4069 if (httpChan) {
4070 httpChan->GetOriginalURI(getter_AddRefs(originalURI));
4071 }
4072
4073 nsCOMPtr<nsILoadInfo> loadInfo = chan->LoadInfo();
4074 loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
4075 }
4076
4077 if (!triggeringPrincipal) {
4078 MOZ_ASSERT(false, "Reload needs a valid triggeringPrincipal")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Reload needs a valid triggeringPrincipal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4078); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Reload needs a valid triggeringPrincipal" ")"); do { *((volatile
int*)__null) = 4078; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4079 return NS_ERROR_FAILURE;
4080 }
4081
4082 // Stack variables to ensure changes to the member variables don't affect to
4083 // the call.
4084 nsCOMPtr<nsIURI> currentURI = aCurrentURI;
4085
4086 // Reload always rewrites result principal URI.
4087 Maybe<nsCOMPtr<nsIURI>> emplacedResultPrincipalURI;
4088 emplacedResultPrincipalURI.emplace(std::move(resultPrincipalURI));
4089
4090 RefPtr<WindowContext> context = aBrowsingContext->GetCurrentWindowContext();
4091 RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(currentURI);
4092 loadState->SetReferrerInfo(aReferrerInfo);
4093 loadState->SetOriginalURI(originalURI);
4094 loadState->SetMaybeResultPrincipalURI(emplacedResultPrincipalURI);
4095 loadState->SetLoadReplace(loadReplace);
4096 loadState->SetTriggeringPrincipal(triggeringPrincipal);
4097 loadState->SetTriggeringSandboxFlags(triggeringSandboxFlags);
4098 loadState->SetTriggeringWindowId(triggeringWindowId);
4099 loadState->SetTriggeringStorageAccess(triggeringStorageAccess);
4100 loadState->SetPrincipalToInherit(triggeringPrincipal);
4101 loadState->SetCsp(csp);
4102 loadState->SetInternalLoadFlags(flags);
4103 loadState->SetTypeHint(NS_ConvertUTF16toUTF8(contentTypeHint));
4104 loadState->SetLoadType(aLoadType);
4105 loadState->SetFirstParty(true);
4106 loadState->SetSrcdocData(srcdoc);
4107 loadState->SetSourceBrowsingContext(aBrowsingContext);
4108 loadState->SetBaseURI(baseURI);
4109 loadState->SetHasValidUserGestureActivation(
4110 context && context->HasValidTransientUserGestureActivation());
4111 loadState->SetNotifiedBeforeUnloadListeners(aNotifiedBeforeUnloadListeners);
4112 return aDocShell->InternalLoad(loadState);
4113}
4114
4115NS_IMETHODIMPnsresult
4116nsDocShell::Stop(uint32_t aStopFlags) {
4117 // Revoke any pending event related to content viewer restoration
4118 mRestorePresentationEvent.Revoke();
4119
4120 if (mLoadType == LOAD_ERROR_PAGE) {
4121 if (mLSHE) {
4122 // Since error page loads never unset mLSHE, do so now
4123 SetHistoryEntryAndUpdateBC(Some(nullptr), Some<nsISHEntry*>(mLSHE));
4124 }
4125 mActiveEntryIsLoadingFromSessionHistory = false;
4126
4127 mFailedChannel = nullptr;
4128 mFailedURI = nullptr;
4129 }
4130
4131 if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
4132 // Stop the document loading and animations
4133 if (mDocumentViewer) {
4134 nsCOMPtr<nsIDocumentViewer> viewer = mDocumentViewer;
4135 viewer->Stop();
4136 }
4137 } else if (nsIWebNavigation::STOP_NETWORK & aStopFlags) {
4138 // Stop the document loading only
4139 if (mDocumentViewer) {
4140 RefPtr<Document> doc = mDocumentViewer->GetDocument();
4141 if (doc) {
4142 doc->StopDocumentLoad();
4143 }
4144 }
4145 }
4146
4147 if (nsIWebNavigation::STOP_NETWORK & aStopFlags) {
4148 // Suspend any timers that were set for this loader. We'll clear
4149 // them out for good in CreateDocumentViewer.
4150 if (mRefreshURIList) {
4151 SuspendRefreshURIs();
4152 mSavedRefreshURIList.swap(mRefreshURIList);
4153 mRefreshURIList = nullptr;
4154 }
4155
4156 // XXXbz We could also pass |this| to nsIURILoader::Stop. That will
4157 // just call Stop() on us as an nsIDocumentLoader... We need fewer
4158 // redundant apis!
4159 Stop();
4160
4161 // Clear out mChannelToDisconnectOnPageHide. This page won't go in the
4162 // BFCache now, and the Stop above will have removed the DocumentChannel
4163 // from the loadgroup.
4164 mChannelToDisconnectOnPageHide = 0;
4165 }
4166
4167 for (auto* child : mChildList.ForwardRange()) {
4168 nsCOMPtr<nsIWebNavigation> shellAsNav(do_QueryObject(child));
4169 if (shellAsNav) {
4170 shellAsNav->Stop(aStopFlags);
4171 }
4172 }
4173
4174 return NS_OK;
4175}
4176
4177NS_IMETHODIMPnsresult
4178nsDocShell::GetDocument(Document** aDocument) {
4179 NS_ENSURE_ARG_POINTER(aDocument)do { if ((__builtin_expect(!!(!(aDocument)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDocument" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4179); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4180 NS_ENSURE_SUCCESS(EnsureDocumentViewer(), NS_ERROR_FAILURE)do { nsresult __rv = EnsureDocumentViewer(); if (((bool)(__builtin_expect
(!!(NS_FAILED_impl(__rv)), 0)))) { const char* name = mozilla
::GetStaticErrorName(__rv); mozilla::SmprintfPointer msg = mozilla
::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%"
"X" "%s%s%s", "EnsureDocumentViewer()", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4180); return NS_ERROR_FAILURE; } } while (false)
;
4181
4182 RefPtr<Document> doc = mDocumentViewer->GetDocument();
4183 if (!doc) {
4184 return NS_ERROR_NOT_AVAILABLE;
4185 }
4186
4187 doc.forget(aDocument);
4188 return NS_OK;
4189}
4190
4191NS_IMETHODIMPnsresult
4192nsDocShell::GetCurrentURI(nsIURI** aURI) {
4193 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4193); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4194
4195 nsCOMPtr<nsIURI> uri = mCurrentURI;
4196 uri.forget(aURI);
4197 return NS_OK;
4198}
4199
4200NS_IMETHODIMPnsresult
4201nsDocShell::GetSessionHistoryXPCOM(nsISupports** aSessionHistory) {
4202 NS_ENSURE_ARG_POINTER(aSessionHistory)do { if ((__builtin_expect(!!(!(aSessionHistory)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aSessionHistory" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4202); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4203 RefPtr<ChildSHistory> shistory = GetSessionHistory();
4204 shistory.forget(aSessionHistory);
4205 return NS_OK;
4206}
4207
4208//*****************************************************************************
4209// nsDocShell::nsIWebPageDescriptor
4210//*****************************************************************************
4211
4212NS_IMETHODIMPnsresult
4213nsDocShell::LoadPageAsViewSource(nsIDocShell* aOtherDocShell,
4214 const nsAString& aURI) {
4215 if (!aOtherDocShell) {
4216 return NS_ERROR_INVALID_POINTER;
4217 }
4218 nsCOMPtr<nsIURI> newURI;
4219 nsresult rv = NS_NewURI(getter_AddRefs(newURI), aURI);
4220 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4221 return rv;
4222 }
4223
4224 RefPtr<nsDocShellLoadState> loadState;
4225 uint32_t cacheKey;
4226 auto* otherDocShell = nsDocShell::Cast(aOtherDocShell);
4227 if (mozilla::SessionHistoryInParent()) {
4228 loadState = new nsDocShellLoadState(newURI);
4229 if (!otherDocShell->FillLoadStateFromCurrentEntry(*loadState)) {
4230 return NS_ERROR_INVALID_POINTER;
4231 }
4232 cacheKey = otherDocShell->GetCacheKeyFromCurrentEntry().valueOr(0);
4233 } else {
4234 nsCOMPtr<nsISHEntry> entry;
4235 bool isOriginalSHE;
4236 otherDocShell->GetCurrentSHEntry(getter_AddRefs(entry), &isOriginalSHE);
4237 if (!entry) {
4238 return NS_ERROR_INVALID_POINTER;
4239 }
4240 rv = entry->CreateLoadInfo(getter_AddRefs(loadState));
4241 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4241); return rv; } } while (false)
;
4242 entry->GetCacheKey(&cacheKey);
4243 loadState->SetURI(newURI);
4244 loadState->SetSHEntry(nullptr);
4245 }
4246
4247 // We're doing a load of the page, via an API that
4248 // is only exposed to system code. The triggering principal for this load
4249 // should be the system principal.
4250 loadState->SetTriggeringPrincipal(nsContentUtils::GetSystemPrincipal());
4251 loadState->SetOriginalURI(nullptr);
4252 loadState->SetResultPrincipalURI(nullptr);
4253
4254 return InternalLoad(loadState, Some(cacheKey));
4255}
4256
4257NS_IMETHODIMPnsresult
4258nsDocShell::GetCurrentDescriptor(nsISupports** aPageDescriptor) {
4259 MOZ_ASSERT(aPageDescriptor, "Null out param?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPageDescriptor)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPageDescriptor))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aPageDescriptor"
" (" "Null out param?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4259); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPageDescriptor"
") (" "Null out param?" ")"); do { *((volatile int*)__null) =
4259; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
4260
4261 *aPageDescriptor = nullptr;
4262
4263 nsISHEntry* src = mOSHE ? mOSHE : mLSHE;
4264 if (src) {
4265 nsCOMPtr<nsISHEntry> dest;
4266
4267 nsresult rv = src->Clone(getter_AddRefs(dest));
4268 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4269 return rv;
4270 }
4271
4272 // null out inappropriate cloned attributes...
4273 dest->SetParent(nullptr);
4274 dest->SetIsSubFrame(false);
4275
4276 return CallQueryInterface(dest, aPageDescriptor);
4277 }
4278
4279 return NS_ERROR_NOT_AVAILABLE;
4280}
4281
4282already_AddRefed<nsIInputStream> nsDocShell::GetPostDataFromCurrentEntry()
4283 const {
4284 nsCOMPtr<nsIInputStream> postData;
4285 if (mozilla::SessionHistoryInParent()) {
4286 if (mActiveEntry) {
4287 postData = mActiveEntry->GetPostData();
4288 } else if (mLoadingEntry) {
4289 postData = mLoadingEntry->mInfo.GetPostData();
4290 }
4291 } else {
4292 if (mOSHE) {
4293 postData = mOSHE->GetPostData();
4294 } else if (mLSHE) {
4295 postData = mLSHE->GetPostData();
4296 }
4297 }
4298
4299 return postData.forget();
4300}
4301
4302Maybe<uint32_t> nsDocShell::GetCacheKeyFromCurrentEntry() const {
4303 if (mozilla::SessionHistoryInParent()) {
4304 if (mActiveEntry) {
4305 return Some(mActiveEntry->GetCacheKey());
4306 }
4307
4308 if (mLoadingEntry) {
4309 return Some(mLoadingEntry->mInfo.GetCacheKey());
4310 }
4311 } else {
4312 if (mOSHE) {
4313 return Some(mOSHE->GetCacheKey());
4314 }
4315
4316 if (mLSHE) {
4317 return Some(mLSHE->GetCacheKey());
4318 }
4319 }
4320
4321 return Nothing();
4322}
4323
4324bool nsDocShell::FillLoadStateFromCurrentEntry(
4325 nsDocShellLoadState& aLoadState) {
4326 if (mLoadingEntry) {
4327 mLoadingEntry->mInfo.FillLoadInfo(aLoadState);
4328 return true;
4329 }
4330 if (mActiveEntry) {
4331 mActiveEntry->FillLoadInfo(aLoadState);
4332 return true;
4333 }
4334 return false;
4335}
4336
4337//*****************************************************************************
4338// nsDocShell::nsIBaseWindow
4339//*****************************************************************************
4340
4341NS_IMETHODIMPnsresult
4342nsDocShell::InitWindow(nativeWindow aParentNativeWindow,
4343 nsIWidget* aParentWidget, int32_t aX, int32_t aY,
4344 int32_t aWidth, int32_t aHeight) {
4345 SetParentWidget(aParentWidget);
4346 SetPositionAndSize(aX, aY, aWidth, aHeight, 0);
4347 NS_ENSURE_TRUE(Initialize(), NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(Initialize())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "Initialize()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4347); return NS_ERROR_FAILURE; } } while (false)
;
4348
4349 return NS_OK;
4350}
4351
4352NS_IMETHODIMPnsresult
4353nsDocShell::Destroy() {
4354 // XXX: We allow this function to be called just once. If you are going to
4355 // reset new variables in this function, please make sure the variables will
4356 // never be re-initialized. Adding assertions to check |mIsBeingDestroyed|
4357 // in the setter functions for the variables would be enough.
4358 if (mIsBeingDestroyed) {
4359 return NS_ERROR_DOCSHELL_DYING;
4360 }
4361
4362 NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome,do { if (!(mItemType == typeContent || mItemType == typeChrome
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Unexpected item type in docshell"
, "mItemType == typeContent || mItemType == typeChrome", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4363); MOZ_PretendNoReturn(); } } while (0)
4363 "Unexpected item type in docshell")do { if (!(mItemType == typeContent || mItemType == typeChrome
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Unexpected item type in docshell"
, "mItemType == typeContent || mItemType == typeChrome", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4363); MOZ_PretendNoReturn(); } } while (0)
;
4364
4365 nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
4366 if (serv) {
4367 const char* msg = mItemType == typeContent
4368 ? NS_WEBNAVIGATION_DESTROY"webnavigation-destroy"
4369 : NS_CHROME_WEBNAVIGATION_DESTROY"chrome-webnavigation-destroy";
4370 serv->NotifyObservers(GetAsSupports(this), msg, nullptr);
4371 }
4372
4373 mIsBeingDestroyed = true;
4374
4375 // Brak the cycle with the initial client, if present.
4376 mInitialClientSource.reset();
4377
4378 // Make sure to blow away our mLoadingURI just in case. No loads
4379 // from inside this pagehide.
4380 mLoadingURI = nullptr;
4381
4382 // Fire unload event before we blow anything away.
4383 (void)FirePageHideNotification(true);
4384
4385 // Clear pointers to any detached nsEditorData that's lying
4386 // around in shistory entries. Breaks cycle. See bug 430921.
4387 if (mOSHE) {
4388 mOSHE->SetEditorData(nullptr);
4389 }
4390 if (mLSHE) {
4391 mLSHE->SetEditorData(nullptr);
4392 }
4393
4394 // Note: mContentListener can be null if Init() failed and we're being
4395 // called from the destructor.
4396 if (mContentListener) {
4397 mContentListener->DropDocShellReference();
4398 mContentListener->SetParentContentListener(nullptr);
4399 // Note that we do NOT set mContentListener to null here; that
4400 // way if someone tries to do a load in us after this point
4401 // the nsDSURIContentListener will block it. All of which
4402 // means that we should do this before calling Stop(), of
4403 // course.
4404 }
4405
4406 // Stop any URLs that are currently being loaded...
4407 Stop(nsIWebNavigation::STOP_ALL);
4408
4409 mEditorData = nullptr;
4410
4411 // Save the state of the current document, before destroying the window.
4412 // This is needed to capture the state of a frameset when the new document
4413 // causes the frameset to be destroyed...
4414 PersistLayoutHistoryState();
4415
4416 // Remove this docshell from its parent's child list
4417 nsCOMPtr<nsIDocShellTreeItem> docShellParentAsItem =
4418 do_QueryInterface(GetAsSupports(mParent));
4419 if (docShellParentAsItem) {
4420 docShellParentAsItem->RemoveChild(this);
4421 }
4422
4423 if (mDocumentViewer) {
4424 mDocumentViewer->Close(nullptr);
4425 mDocumentViewer->Destroy();
4426 mDocumentViewer = nullptr;
4427 }
4428
4429 nsDocLoader::Destroy();
4430
4431 mParentWidget = nullptr;
4432 SetCurrentURIInternal(nullptr);
4433
4434 if (mScriptGlobal) {
4435 mScriptGlobal->DetachFromDocShell(!mWillChangeProcess);
4436 mScriptGlobal = nullptr;
4437 }
4438
4439 if (GetSessionHistory()) {
4440 // We want to destroy these content viewers now rather than
4441 // letting their destruction wait for the session history
4442 // entries to get garbage collected. (Bug 488394)
4443 GetSessionHistory()->EvictLocalDocumentViewers();
4444 }
4445
4446 if (mWillChangeProcess && !mBrowsingContext->IsDiscarded()) {
4447 mBrowsingContext->PrepareForProcessChange();
4448 }
4449
4450 SetTreeOwner(nullptr);
4451
4452 mBrowserChild = nullptr;
4453
4454 mChromeEventHandler = nullptr;
4455
4456 // Cancel any timers that were set for this docshell; this is needed
4457 // to break the cycle between us and the timers.
4458 CancelRefreshURITimers();
4459
4460 return NS_OK;
4461}
4462
4463double nsDocShell::GetWidgetCSSToDeviceScale() {
4464 if (mParentWidget) {
4465 return mParentWidget->GetDefaultScale().scale;
4466 }
4467 if (nsCOMPtr<nsIBaseWindow> ownerWindow = do_QueryInterface(mTreeOwner)) {
4468 return ownerWindow->GetWidgetCSSToDeviceScale();
4469 }
4470 return 1.0;
4471}
4472
4473NS_IMETHODIMPnsresult
4474nsDocShell::GetDevicePixelsPerDesktopPixel(double* aScale) {
4475 if (mParentWidget) {
4476 *aScale = mParentWidget->GetDesktopToDeviceScale().scale;
4477 return NS_OK;
4478 }
4479
4480 nsCOMPtr<nsIBaseWindow> ownerWindow(do_QueryInterface(mTreeOwner));
4481 if (ownerWindow) {
4482 return ownerWindow->GetDevicePixelsPerDesktopPixel(aScale);
4483 }
4484
4485 *aScale = 1.0;
4486 return NS_OK;
4487}
4488
4489NS_IMETHODIMPnsresult
4490nsDocShell::SetPosition(int32_t aX, int32_t aY) {
4491 mBounds.MoveTo(aX, aY);
4492
4493 if (mDocumentViewer) {
4494 NS_ENSURE_SUCCESS(mDocumentViewer->Move(aX, aY), NS_ERROR_FAILURE)do { nsresult __rv = mDocumentViewer->Move(aX, aY); if (((
bool)(__builtin_expect(!!(NS_FAILED_impl(__rv)), 0)))) { const
char* name = mozilla::GetStaticErrorName(__rv); mozilla::SmprintfPointer
msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "mDocumentViewer->Move(aX, aY)"
, "NS_ERROR_FAILURE", static_cast<uint32_t>(__rv), name
? " (" : "", name ? name : "", name ? ")" : ""); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4494); return NS_ERROR_FAILURE; } } while (false)
;
4495 }
4496
4497 return NS_OK;
4498}
4499
4500NS_IMETHODIMPnsresult
4501nsDocShell::SetPositionDesktopPix(int32_t aX, int32_t aY) {
4502 nsCOMPtr<nsIBaseWindow> ownerWindow(do_QueryInterface(mTreeOwner));
4503 if (ownerWindow) {
4504 return ownerWindow->SetPositionDesktopPix(aX, aY);
4505 }
4506
4507 double scale = 1.0;
4508 GetDevicePixelsPerDesktopPixel(&scale);
4509 return SetPosition(NSToIntRound(aX * scale), NSToIntRound(aY * scale));
4510}
4511
4512NS_IMETHODIMPnsresult
4513nsDocShell::GetPosition(int32_t* aX, int32_t* aY) {
4514 return GetPositionAndSize(aX, aY, nullptr, nullptr);
4515}
4516
4517NS_IMETHODIMPnsresult
4518nsDocShell::SetSize(int32_t aWidth, int32_t aHeight, bool aRepaint) {
4519 int32_t x = 0, y = 0;
4520 GetPosition(&x, &y);
4521 return SetPositionAndSize(x, y, aWidth, aHeight,
4522 aRepaint ? nsIBaseWindow::eRepaint : 0);
4523}
4524
4525NS_IMETHODIMPnsresult
4526nsDocShell::GetSize(int32_t* aWidth, int32_t* aHeight) {
4527 return GetPositionAndSize(nullptr, nullptr, aWidth, aHeight);
4528}
4529
4530NS_IMETHODIMPnsresult
4531nsDocShell::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aWidth,
4532 int32_t aHeight, uint32_t aFlags) {
4533 mBounds.SetRect(aX, aY, aWidth, aHeight);
4534
4535 // Hold strong ref, since SetBounds can make us null out mDocumentViewer
4536 nsCOMPtr<nsIDocumentViewer> viewer = mDocumentViewer;
4537 if (viewer) {
4538 uint32_t cvflags = (aFlags & nsIBaseWindow::eDelayResize)
4539 ? nsIDocumentViewer::eDelayResize
4540 : 0;
4541 // XXX Border figured in here or is that handled elsewhere?
4542 nsresult rv = viewer->SetBoundsWithFlags(mBounds, cvflags);
4543 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4543); return NS_ERROR_FAILURE; } } while (false)
;
4544 }
4545
4546 return NS_OK;
4547}
4548
4549NS_IMETHODIMPnsresult
4550nsDocShell::GetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aWidth,
4551 int32_t* aHeight) {
4552 if (mParentWidget) {
4553 // ensure size is up-to-date if window has changed resolution
4554 LayoutDeviceIntRect r = mParentWidget->GetClientBounds();
4555 SetPositionAndSize(mBounds.X(), mBounds.Y(), r.Width(), r.Height(), 0);
4556 }
4557
4558 // We should really consider just getting this information from
4559 // our window instead of duplicating the storage and code...
4560 if (aWidth || aHeight) {
4561 // Caller wants to know our size; make sure to give them up to
4562 // date information.
4563 RefPtr<Document> doc(do_GetInterface(GetAsSupports(mParent)));
4564 if (doc) {
4565 doc->FlushPendingNotifications(FlushType::Layout);
4566 }
4567 }
4568
4569 DoGetPositionAndSize(aX, aY, aWidth, aHeight);
4570 return NS_OK;
4571}
4572
4573void nsDocShell::DoGetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aWidth,
4574 int32_t* aHeight) {
4575 if (aX) {
4576 *aX = mBounds.X();
4577 }
4578 if (aY) {
4579 *aY = mBounds.Y();
4580 }
4581 if (aWidth) {
4582 *aWidth = mBounds.Width();
4583 }
4584 if (aHeight) {
4585 *aHeight = mBounds.Height();
4586 }
4587}
4588
4589NS_IMETHODIMPnsresult
4590nsDocShell::SetDimensions(DimensionRequest&& aRequest) {
4591 return NS_ERROR_NOT_IMPLEMENTED;
4592}
4593
4594NS_IMETHODIMPnsresult
4595nsDocShell::GetDimensions(DimensionKind aDimensionKind, int32_t* aX,
4596 int32_t* aY, int32_t* aCX, int32_t* aCY) {
4597 return NS_ERROR_NOT_IMPLEMENTED;
4598}
4599
4600NS_IMETHODIMPnsresult
4601nsDocShell::Repaint(bool aForce) {
4602 PresShell* presShell = GetPresShell();
4603 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(presShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "presShell" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4603); return NS_ERROR_FAILURE; } } while (false)
;
4604
4605 RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
4606 NS_ENSURE_TRUE(viewManager, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(viewManager)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "viewManager" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4606); return NS_ERROR_FAILURE; } } while (false)
;
4607
4608 viewManager->InvalidateAllViews();
4609 return NS_OK;
4610}
4611
4612NS_IMETHODIMPnsresult
4613nsDocShell::GetParentWidget(nsIWidget** aParentWidget) {
4614 NS_ENSURE_ARG_POINTER(aParentWidget)do { if ((__builtin_expect(!!(!(aParentWidget)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aParentWidget" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4614); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4615
4616 *aParentWidget = mParentWidget;
4617 NS_IF_ADDREF(*aParentWidget)ns_if_addref(*aParentWidget);
4618
4619 return NS_OK;
4620}
4621
4622NS_IMETHODIMPnsresult
4623nsDocShell::SetParentWidget(nsIWidget* aParentWidget) {
4624 MOZ_ASSERT(!mIsBeingDestroyed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIsBeingDestroyed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIsBeingDestroyed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mIsBeingDestroyed"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4624); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIsBeingDestroyed"
")"); do { *((volatile int*)__null) = 4624; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4625 mParentWidget = aParentWidget;
4626
4627 return NS_OK;
4628}
4629
4630NS_IMETHODIMPnsresult
4631nsDocShell::GetParentNativeWindow(nativeWindow* aParentNativeWindow) {
4632 NS_ENSURE_ARG_POINTER(aParentNativeWindow)do { if ((__builtin_expect(!!(!(aParentNativeWindow)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aParentNativeWindow"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4632); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4633
4634 if (mParentWidget) {
4635 *aParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET3);
4636 } else {
4637 *aParentNativeWindow = nullptr;
4638 }
4639
4640 return NS_OK;
4641}
4642
4643NS_IMETHODIMPnsresult
4644nsDocShell::SetParentNativeWindow(nativeWindow aParentNativeWindow) {
4645 return NS_ERROR_NOT_IMPLEMENTED;
4646}
4647
4648NS_IMETHODIMPnsresult
4649nsDocShell::GetNativeHandle(nsAString& aNativeHandle) {
4650 // the nativeHandle should be accessed from nsIAppWindow
4651 return NS_ERROR_NOT_IMPLEMENTED;
4652}
4653
4654NS_IMETHODIMPnsresult
4655nsDocShell::GetVisibility(bool* aVisibility) {
4656 NS_ENSURE_ARG_POINTER(aVisibility)do { if ((__builtin_expect(!!(!(aVisibility)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aVisibility" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4656); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4657
4658 *aVisibility = false;
4659
4660 if (!mDocumentViewer) {
4661 return NS_OK;
4662 }
4663
4664 PresShell* presShell = GetPresShell();
4665 if (!presShell) {
4666 return NS_OK;
4667 }
4668
4669 // get the view manager
4670 nsViewManager* vm = presShell->GetViewManager();
4671 NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(vm)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "vm" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4671); return NS_ERROR_FAILURE; } } while (false)
;
4672
4673 // get the root view
4674 nsView* view = vm->GetRootView(); // views are not ref counted
4675 NS_ENSURE_TRUE(view, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(view)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "view" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4675); return NS_ERROR_FAILURE; } } while (false)
;
4676
4677 // if our root view is hidden, we are not visible
4678 if (view->GetVisibility() == ViewVisibility::Hide) {
4679 return NS_OK;
4680 }
4681
4682 // otherwise, we must walk up the document and view trees checking
4683 // for a hidden view, unless we're an off screen browser, which
4684 // would make this test meaningless.
4685
4686 RefPtr<nsDocShell> docShell = this;
4687 RefPtr<nsDocShell> parentItem = docShell->GetInProcessParentDocshell();
4688 while (parentItem) {
4689 // Null-check for crash in bug 267804
4690 if (!parentItem->GetPresShell()) {
4691 MOZ_ASSERT_UNREACHABLE("parent docshell has null pres shell")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"parent docshell has null pres shell" ")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4691); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "parent docshell has null pres shell"
")"); do { *((volatile int*)__null) = 4691; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4692 return NS_OK;
4693 }
4694
4695 vm = docShell->GetPresShell()->GetViewManager();
4696 if (vm) {
4697 view = vm->GetRootView();
4698 }
4699
4700 if (view) {
4701 view = view->GetParent(); // anonymous inner view
4702 if (view) {
4703 view = view->GetParent(); // subdocumentframe's view
4704 }
4705 }
4706
4707 nsIFrame* frame = view ? view->GetFrame() : nullptr;
4708 if (frame && !frame->IsVisibleConsideringAncestors(
4709 nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY)) {
4710 return NS_OK;
4711 }
4712
4713 docShell = parentItem;
4714 parentItem = docShell->GetInProcessParentDocshell();
4715 }
4716
4717 nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(mTreeOwner));
4718 if (!treeOwnerAsWin) {
4719 *aVisibility = true;
4720 return NS_OK;
4721 }
4722
4723 // Check with the tree owner as well to give embedders a chance to
4724 // expose visibility as well.
4725 nsresult rv = treeOwnerAsWin->GetVisibility(aVisibility);
4726 if (rv == NS_ERROR_NOT_IMPLEMENTED) {
4727 // The tree owner had no opinion on our visibility.
4728 *aVisibility = true;
4729 return NS_OK;
4730 }
4731 return rv;
4732}
4733
4734void nsDocShell::ActivenessMaybeChanged() {
4735 const bool isActive = mBrowsingContext->IsActive();
4736 if (RefPtr<PresShell> presShell = GetPresShell()) {
4737 presShell->ActivenessMaybeChanged();
4738 }
4739
4740 // Tell the window about it
4741 if (mScriptGlobal) {
4742 mScriptGlobal->SetIsBackground(!isActive);
4743 if (RefPtr<Document> doc = mScriptGlobal->GetExtantDoc()) {
4744 // Update orientation when the top-level browsing context becomes active.
4745 if (isActive && mBrowsingContext->IsTop()) {
4746 // We only care about the top-level browsing context.
4747 auto orientation = mBrowsingContext->GetOrientationLock();
4748 ScreenOrientation::UpdateActiveOrientationLock(orientation);
4749 }
4750
4751 doc->PostVisibilityUpdateEvent();
4752 }
4753 }
4754
4755 // Tell the nsDOMNavigationTiming about it
4756 RefPtr<nsDOMNavigationTiming> timing = mTiming;
4757 if (!timing && mDocumentViewer) {
4758 if (Document* doc = mDocumentViewer->GetDocument()) {
4759 timing = doc->GetNavigationTiming();
4760 }
4761 }
4762 if (timing) {
4763 timing->NotifyDocShellStateChanged(
4764 isActive ? nsDOMNavigationTiming::DocShellState::eActive
4765 : nsDOMNavigationTiming::DocShellState::eInactive);
4766 }
4767
4768 // Restart or stop meta refresh timers if necessary
4769 if (mDisableMetaRefreshWhenInactive) {
4770 if (isActive) {
4771 ResumeRefreshURIs();
4772 } else {
4773 SuspendRefreshURIs();
4774 }
4775 }
4776
4777 if (InputTaskManager::CanSuspendInputEvent()) {
4778 mBrowsingContext->Group()->UpdateInputTaskManagerIfNeeded(isActive);
4779 }
4780}
4781
4782NS_IMETHODIMPnsresult
4783nsDocShell::SetDefaultLoadFlags(uint32_t aDefaultLoadFlags) {
4784 if (!mWillChangeProcess) {
4785 // Intentionally ignoring handling discarded browsing contexts.
4786 Unused << mBrowsingContext->SetDefaultLoadFlags(aDefaultLoadFlags);
4787 } else {
4788 // Bug 1623565: DevTools tries to clean up defaultLoadFlags on
4789 // shutdown. Sorry DevTools, your DocShell is in another process.
4790 NS_WARNING("nsDocShell::SetDefaultLoadFlags called on Zombie DocShell")NS_DebugBreak(NS_DEBUG_WARNING, "nsDocShell::SetDefaultLoadFlags called on Zombie DocShell"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4790)
;
4791 }
4792 return NS_OK;
4793}
4794
4795NS_IMETHODIMPnsresult
4796nsDocShell::GetDefaultLoadFlags(uint32_t* aDefaultLoadFlags) {
4797 *aDefaultLoadFlags = mBrowsingContext->GetDefaultLoadFlags();
4798 return NS_OK;
4799}
4800
4801NS_IMETHODIMPnsresult
4802nsDocShell::GetFailedChannel(nsIChannel** aFailedChannel) {
4803 NS_ENSURE_ARG_POINTER(aFailedChannel)do { if ((__builtin_expect(!!(!(aFailedChannel)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aFailedChannel" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4803); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4804 Document* doc = GetDocument();
4805 if (!doc) {
4806 *aFailedChannel = nullptr;
4807 return NS_OK;
4808 }
4809 NS_IF_ADDREF(*aFailedChannel = doc->GetFailedChannel())ns_if_addref(*aFailedChannel = doc->GetFailedChannel());
4810 return NS_OK;
4811}
4812
4813NS_IMETHODIMPnsresult
4814nsDocShell::SetVisibility(bool aVisibility) {
4815 // Show()/Hide() may change mDocumentViewer.
4816 nsCOMPtr<nsIDocumentViewer> viewer = mDocumentViewer;
4817 if (!viewer) {
4818 return NS_OK;
4819 }
4820 if (aVisibility) {
4821 viewer->Show();
4822 } else {
4823 viewer->Hide();
4824 }
4825
4826 return NS_OK;
4827}
4828
4829NS_IMETHODIMPnsresult
4830nsDocShell::GetEnabled(bool* aEnabled) {
4831 NS_ENSURE_ARG_POINTER(aEnabled)do { if ((__builtin_expect(!!(!(aEnabled)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aEnabled" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4831); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4832 *aEnabled = true;
4833 return NS_ERROR_NOT_IMPLEMENTED;
4834}
4835
4836NS_IMETHODIMPnsresult
4837nsDocShell::SetEnabled(bool aEnabled) { return NS_ERROR_NOT_IMPLEMENTED; }
4838
4839NS_IMETHODIMPnsresult
4840nsDocShell::GetMainWidget(nsIWidget** aMainWidget) {
4841 // We don't create our own widget, so simply return the parent one.
4842 return GetParentWidget(aMainWidget);
4843}
4844
4845NS_IMETHODIMPnsresult
4846nsDocShell::GetTitle(nsAString& aTitle) {
4847 aTitle = mTitle;
4848 return NS_OK;
4849}
4850
4851NS_IMETHODIMPnsresult
4852nsDocShell::SetTitle(const nsAString& aTitle) {
4853 // Avoid unnecessary updates of the title if the URI and the title haven't
4854 // changed.
4855 if (mTitleValidForCurrentURI && mTitle == aTitle) {
4856 return NS_OK;
4857 }
4858
4859 // Store local title
4860 mTitle = aTitle;
4861 mTitleValidForCurrentURI = true;
4862
4863 // When title is set on the top object it should then be passed to the
4864 // tree owner.
4865 if (mBrowsingContext->IsTop()) {
4866 nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(mTreeOwner));
4867 if (treeOwnerAsWin) {
4868 treeOwnerAsWin->SetTitle(aTitle);
4869 }
4870 }
4871
4872 if (mCurrentURI && mLoadType != LOAD_ERROR_PAGE) {
4873 UpdateGlobalHistoryTitle(mCurrentURI);
4874 }
4875
4876 // Update SessionHistory with the document's title.
4877 if (mLoadType != LOAD_BYPASS_HISTORY && mLoadType != LOAD_ERROR_PAGE) {
4878 SetTitleOnHistoryEntry(true);
4879 }
4880
4881 return NS_OK;
4882}
4883
4884void nsDocShell::SetTitleOnHistoryEntry(bool aUpdateEntryInSessionHistory) {
4885 if (mOSHE) {
4886 mOSHE->SetTitle(mTitle);
4887 }
4888
4889 if (mActiveEntry && mBrowsingContext) {
4890 mActiveEntry->SetTitle(mTitle);
4891 if (aUpdateEntryInSessionHistory) {
4892 if (XRE_IsParentProcess()) {
4893 SessionHistoryEntry* entry =
4894 mBrowsingContext->Canonical()->GetActiveSessionHistoryEntry();
4895 if (entry) {
4896 entry->SetTitle(mTitle);
4897 }
4898 } else {
4899 mozilla::Unused
4900 << ContentChild::GetSingleton()->SendSessionHistoryEntryTitle(
4901 mBrowsingContext, mTitle);
4902 }
4903 }
4904 }
4905}
4906
4907nsPoint nsDocShell::GetCurScrollPos() {
4908 nsPoint scrollPos;
4909 if (nsIScrollableFrame* sf = GetRootScrollFrame()) {
4910 scrollPos = sf->GetVisualViewportOffset();
4911 }
4912 return scrollPos;
4913}
4914
4915nsresult nsDocShell::SetCurScrollPosEx(int32_t aCurHorizontalPos,
4916 int32_t aCurVerticalPos) {
4917 nsIScrollableFrame* sf = GetRootScrollFrame();
4918 NS_ENSURE_TRUE(sf, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sf)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sf" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4918); return NS_ERROR_FAILURE; } } while (false)
;
4919
4920 ScrollMode scrollMode =
4921 sf->IsSmoothScroll() ? ScrollMode::SmoothMsd : ScrollMode::Instant;
4922
4923 nsPoint targetPos(aCurHorizontalPos, aCurVerticalPos);
4924 sf->ScrollTo(targetPos, scrollMode);
4925
4926 // Set the visual viewport offset as well.
4927
4928 RefPtr<PresShell> presShell = GetPresShell();
4929 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(presShell)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "presShell" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4929); return NS_ERROR_FAILURE; } } while (false)
;
4930
4931 nsPresContext* presContext = presShell->GetPresContext();
4932 NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(presContext)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "presContext" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4932); return NS_ERROR_FAILURE; } } while (false)
;
4933
4934 // Only the root content document can have a distinct visual viewport offset.
4935 if (!presContext->IsRootContentDocumentCrossProcess()) {
4936 return NS_OK;
4937 }
4938
4939 // Not on a platform with a distinct visual viewport - don't bother setting
4940 // the visual viewport offset.
4941 if (!presShell->IsVisualViewportSizeSet()) {
4942 return NS_OK;
4943 }
4944
4945 presShell->ScrollToVisual(targetPos, layers::FrameMetrics::eMainThread,
4946 scrollMode);
4947
4948 return NS_OK;
4949}
4950
4951void nsDocShell::SetScrollbarPreference(mozilla::ScrollbarPreference aPref) {
4952 if (mScrollbarPref == aPref) {
4953 return;
4954 }
4955 mScrollbarPref = aPref;
4956 auto* ps = GetPresShell();
4957 if (!ps) {
4958 return;
4959 }
4960 nsIFrame* scrollFrame = ps->GetRootScrollFrame();
4961 if (!scrollFrame) {
4962 return;
4963 }
4964 ps->FrameNeedsReflow(scrollFrame,
4965 IntrinsicDirty::FrameAncestorsAndDescendants,
4966 NS_FRAME_IS_DIRTY);
4967}
4968
4969//*****************************************************************************
4970// nsDocShell::nsIRefreshURI
4971//*****************************************************************************
4972
4973NS_IMETHODIMPnsresult
4974nsDocShell::RefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
4975 uint32_t aDelay) {
4976 MOZ_ASSERT(!mIsBeingDestroyed)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIsBeingDestroyed)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIsBeingDestroyed))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mIsBeingDestroyed"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4976); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mIsBeingDestroyed"
")"); do { *((volatile int*)__null) = 4976; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4977
4978 NS_ENSURE_ARG(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 4978); return NS_ERROR_INVALID_ARG; } } while (false)
;
4979
4980 /* Check if Meta refresh/redirects are permitted. Some
4981 * embedded applications may not want to do this.
4982 * Must do this before sending out NOTIFY_REFRESH events
4983 * because listeners may have side effects (e.g. displaying a
4984 * button to manually trigger the refresh later).
4985 */
4986 bool allowRedirects = true;
4987 GetAllowMetaRedirects(&allowRedirects);
4988 if (!allowRedirects) {
4989 return NS_OK;
4990 }
4991
4992 // If any web progress listeners are listening for NOTIFY_REFRESH events,
4993 // give them a chance to block this refresh.
4994 bool sameURI;
4995 nsresult rv = aURI->Equals(mCurrentURI, &sameURI);
4996 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4997 sameURI = false;
4998 }
4999 if (!RefreshAttempted(this, aURI, aDelay, sameURI)) {
5000 return NS_OK;
5001 }
5002
5003 nsCOMPtr<nsITimerCallback> refreshTimer =
5004 new nsRefreshTimer(this, aURI, aPrincipal, aDelay);
5005
5006 BusyFlags busyFlags = GetBusyFlags();
5007
5008 if (!mRefreshURIList) {
5009 mRefreshURIList = nsArray::Create();
5010 }
5011
5012 if (busyFlags & BUSY_FLAGS_BUSY ||
5013 (!mBrowsingContext->IsActive() && mDisableMetaRefreshWhenInactive)) {
5014 // We don't want to create the timer right now. Instead queue up the
5015 // request and trigger the timer in EndPageLoad() or whenever we become
5016 // active.
5017 mRefreshURIList->AppendElement(refreshTimer);
5018 } else {
5019 // There is no page loading going on right now. Create the
5020 // timer and fire it right away.
5021 nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
5022 NS_ENSURE_TRUE(win, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(win)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "win" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5022); return NS_ERROR_FAILURE; } } while (false)
;
5023
5024 nsCOMPtr<nsITimer> timer;
5025 MOZ_TRY_VAR(timer, NS_NewTimerWithCallback(refreshTimer, aDelay,do { auto mozTryVarTempResult_ = (NS_NewTimerWithCallback(refreshTimer
, aDelay, nsITimer::TYPE_ONE_SHOT)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (timer) = mozTryVarTempResult_.unwrap(); }
while (0)
5026 nsITimer::TYPE_ONE_SHOT))do { auto mozTryVarTempResult_ = (NS_NewTimerWithCallback(refreshTimer
, aDelay, nsITimer::TYPE_ONE_SHOT)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (timer) = mozTryVarTempResult_.unwrap(); }
while (0)
;
5027
5028 mRefreshURIList->AppendElement(timer); // owning timer ref
5029 }
5030 return NS_OK;
5031}
5032
5033nsresult nsDocShell::ForceRefreshURIFromTimer(nsIURI* aURI,
5034 nsIPrincipal* aPrincipal,
5035 uint32_t aDelay,
5036 nsITimer* aTimer) {
5037 MOZ_ASSERT(aTimer, "Must have a timer here")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aTimer)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aTimer))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aTimer" " (" "Must have a timer here"
")", "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5037); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTimer" ") ("
"Must have a timer here" ")"); do { *((volatile int*)__null)
= 5037; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
5038
5039 // Remove aTimer from mRefreshURIList if needed
5040 if (mRefreshURIList) {
5041 uint32_t n = 0;
5042 mRefreshURIList->GetLength(&n);
5043
5044 for (uint32_t i = 0; i < n; ++i) {
5045 nsCOMPtr<nsITimer> timer = do_QueryElementAt(mRefreshURIList, i);
5046 if (timer == aTimer) {
5047 mRefreshURIList->RemoveElementAt(i);
5048 break;
5049 }
5050 }
5051 }
5052
5053 return ForceRefreshURI(aURI, aPrincipal, aDelay);
5054}
5055
5056NS_IMETHODIMPnsresult
5057nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
5058 uint32_t aDelay) {
5059 NS_ENSURE_ARG(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5059); return NS_ERROR_INVALID_ARG; } } while (false)
;
5060
5061 RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aURI);
5062 loadState->SetOriginalURI(mCurrentURI);
5063 loadState->SetResultPrincipalURI(aURI);
5064 loadState->SetResultPrincipalURIIsSome(true);
5065 loadState->SetKeepResultPrincipalURIIfSet(true);
5066 loadState->SetIsMetaRefresh(true);
5067
5068 // Set the triggering pricipal to aPrincipal if available, or current
5069 // document's principal otherwise.
5070 nsCOMPtr<nsIPrincipal> principal = aPrincipal;
5071 RefPtr<Document> doc = GetDocument();
5072 if (!principal) {
5073 if (!doc) {
5074 return NS_ERROR_FAILURE;
5075 }
5076 principal = doc->NodePrincipal();
5077 }
5078 loadState->SetTriggeringPrincipal(principal);
5079 if (doc) {
5080 loadState->SetCsp(doc->GetCsp());
5081 loadState->SetHasValidUserGestureActivation(
5082 doc->HasValidTransientUserGestureActivation());
5083 loadState->SetTriggeringSandboxFlags(doc->GetSandboxFlags());
5084 loadState->SetTriggeringWindowId(doc->InnerWindowID());
5085 loadState->SetTriggeringStorageAccess(doc->UsingStorageAccess());
5086 }
5087
5088 loadState->SetPrincipalIsExplicit(true);
5089
5090 /* Check if this META refresh causes a redirection
5091 * to another site.
5092 */
5093 bool equalUri = false;
5094 nsresult rv = aURI->Equals(mCurrentURI, &equalUri);
5095
5096 nsCOMPtr<nsIReferrerInfo> referrerInfo;
5097 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !equalUri && aDelay <= REFRESH_REDIRECT_TIMER15000) {
5098 /* It is a META refresh based redirection within the threshold time
5099 * we have in mind (15000 ms as defined by REFRESH_REDIRECT_TIMER).
5100 * Pass a REPLACE flag to LoadURI().
5101 */
5102 loadState->SetLoadType(LOAD_REFRESH_REPLACE);
5103
5104 /* For redirects we mimic HTTP, which passes the
5105 * original referrer.
5106 * We will pass in referrer but will not send to server
5107 */
5108 if (mReferrerInfo) {
5109 referrerInfo = static_cast<ReferrerInfo*>(mReferrerInfo.get())
5110 ->CloneWithNewSendReferrer(false);
5111 }
5112 } else {
5113 loadState->SetLoadType(LOAD_REFRESH);
5114 /* We do need to pass in a referrer, but we don't want it to
5115 * be sent to the server.
5116 * For most refreshes the current URI is an appropriate
5117 * internal referrer.
5118 */
5119 referrerInfo = new ReferrerInfo(mCurrentURI, ReferrerPolicy::_empty, false);
5120 }
5121
5122 loadState->SetReferrerInfo(referrerInfo);
5123 loadState->SetLoadFlags(
5124 nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL);
5125 loadState->SetFirstParty(true);
5126
5127 /*
5128 * LoadURI(...) will cancel all refresh timers... This causes the
5129 * Timer and its refreshData instance to be released...
5130 */
5131 LoadURI(loadState, false);
5132
5133 return NS_OK;
5134}
5135
5136static const char16_t* SkipASCIIWhitespace(const char16_t* aStart,
5137 const char16_t* aEnd) {
5138 const char16_t* iter = aStart;
5139 while (iter != aEnd && mozilla::IsAsciiWhitespace(*iter)) {
5140 ++iter;
5141 }
5142 return iter;
5143}
5144
5145static std::tuple<const char16_t*, const char16_t*> ExtractURLString(
5146 const char16_t* aPosition, const char16_t* aEnd) {
5147 MOZ_ASSERT(aPosition != aEnd)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPosition != aEnd)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPosition != aEnd))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("aPosition != aEnd"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5147); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPosition != aEnd"
")"); do { *((volatile int*)__null) = 5147; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5148
5149 // 1. Let urlString be the substring of input from the code point at
5150 // position to the end of the string.
5151 const char16_t* urlStart = aPosition;
5152 const char16_t* urlEnd = aEnd;
5153
5154 // 2. If the code point in input pointed to by position is U+0055 (U) or
5155 // U+0075 (u), then advance position to the next code point.
5156 // Otherwise, jump to the step labeled skip quotes.
5157 if (*aPosition == 'U' || *aPosition == 'u') {
5158 ++aPosition;
5159
5160 // 3. If the code point in input pointed to by position is U+0052 (R) or
5161 // U+0072 (r), then advance position to the next code point.
5162 // Otherwise, jump to the step labeled parse.
5163 if (aPosition == aEnd || (*aPosition != 'R' && *aPosition != 'r')) {
5164 return std::make_tuple(urlStart, urlEnd);
5165 }
5166
5167 ++aPosition;
5168
5169 // 4. If the code point in input pointed to by position is U+004C (L) or
5170 // U+006C (l), then advance position to the next code point.
5171 // Otherwise, jump to the step labeled parse.
5172 if (aPosition == aEnd || (*aPosition != 'L' && *aPosition != 'l')) {
5173 return std::make_tuple(urlStart, urlEnd);
5174 }
5175
5176 ++aPosition;
5177
5178 // 5. Skip ASCII whitespace within input given position.
5179 aPosition = SkipASCIIWhitespace(aPosition, aEnd);
5180
5181 // 6. If the code point in input pointed to by position is U+003D (=),
5182 // then advance position to the next code point. Otherwise, jump to
5183 // the step labeled parse.
5184 if (aPosition == aEnd || *aPosition != '=') {
5185 return std::make_tuple(urlStart, urlEnd);
5186 }
5187
5188 ++aPosition;
5189
5190 // 7. Skip ASCII whitespace within input given position.
5191 aPosition = SkipASCIIWhitespace(aPosition, aEnd);
5192 }
5193
5194 // 8. Skip quotes: If the code point in input pointed to by position is
5195 // U+0027 (') or U+0022 ("), then let quote be that code point, and
5196 // advance position to the next code point. Otherwise, let quote be
5197 // the empty string.
5198 Maybe<char> quote;
5199 if (aPosition != aEnd && (*aPosition == '\'' || *aPosition == '"')) {
5200 quote.emplace(*aPosition);
5201 ++aPosition;
5202 }
5203
5204 // 9. Set urlString to the substring of input from the code point at
5205 // position to the end of the string.
5206 urlStart = aPosition;
5207 urlEnd = aEnd;
5208
5209 // 10. If quote is not the empty string, and there is a code point in
5210 // urlString equal to quote, then truncate urlString at that code
5211 // point, so that it and all subsequent code points are removed.
5212 const char16_t* quotePos;
5213 if (quote.isSome() &&
5214 (quotePos = nsCharTraits<char16_t>::find(
5215 urlStart, std::distance(urlStart, aEnd), quote.value()))) {
5216 urlEnd = quotePos;
5217 }
5218
5219 return std::make_tuple(urlStart, urlEnd);
5220}
5221
5222void nsDocShell::SetupRefreshURIFromHeader(Document* aDocument,
5223 const nsAString& aHeader) {
5224 if (mIsBeingDestroyed) {
5225 return;
5226 }
5227
5228 const char16_t* position = aHeader.BeginReading();
5229 const char16_t* end = aHeader.EndReading();
5230
5231 // See
5232 // https://html.spec.whatwg.org/#pragma-directives:shared-declarative-refresh-steps.
5233
5234 // 3. Skip ASCII whitespace
5235 position = SkipASCIIWhitespace(position, end);
5236
5237 // 4. Let time be 0.
5238 CheckedInt<uint32_t> milliSeconds;
5239
5240 // 5. Collect a sequence of code points that are ASCII digits
5241 const char16_t* digitsStart = position;
5242 while (position != end && mozilla::IsAsciiDigit(*position)) {
5243 ++position;
5244 }
5245
5246 if (position == digitsStart) {
5247 // 6. If timeString is the empty string, then:
5248 // 1. If the code point in input pointed to by position is not U+002E
5249 // (.), then return.
5250 if (position == end || *position != '.') {
5251 return;
5252 }
5253 } else {
5254 // 7. Otherwise, set time to the result of parsing timeString using the
5255 // rules for parsing non-negative integers.
5256 nsContentUtils::ParseHTMLIntegerResultFlags result;
5257 uint32_t seconds =
5258 nsContentUtils::ParseHTMLInteger(digitsStart, position, &result);
5259 MOZ_ASSERT(!(result & nsContentUtils::eParseHTMLInteger_Negative))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(result & nsContentUtils::eParseHTMLInteger_Negative
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!(result & nsContentUtils::eParseHTMLInteger_Negative
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!(result & nsContentUtils::eParseHTMLInteger_Negative)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5259); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(result & nsContentUtils::eParseHTMLInteger_Negative)"
")"); do { *((volatile int*)__null) = 5259; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5260 if (result & nsContentUtils::eParseHTMLInteger_Error) {
5261 // The spec assumes no errors here (since we only pass ASCII digits in),
5262 // but we can still overflow, so this block should deal with that (and
5263 // only that).
5264 MOZ_ASSERT(!(result & nsContentUtils::eParseHTMLInteger_ErrorOverflow))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(result & nsContentUtils::eParseHTMLInteger_ErrorOverflow
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!(result & nsContentUtils::eParseHTMLInteger_ErrorOverflow
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!(result & nsContentUtils::eParseHTMLInteger_ErrorOverflow)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(result & nsContentUtils::eParseHTMLInteger_ErrorOverflow)"
")"); do { *((volatile int*)__null) = 5264; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5265 return;
5266 }
5267 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5268); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput)"
")"); do { *((volatile int*)__null) = 5268; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5268 !(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput)"
, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5268); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput)"
")"); do { *((volatile int*)__null) = 5268; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5269
5270 milliSeconds = seconds;
5271 milliSeconds *= 1000;
5272 if (!milliSeconds.isValid()) {
5273 return;
5274 }
5275 }
5276
5277 // 8. Collect a sequence of code points that are ASCII digits and U+002E FULL
5278 // STOP characters (.) from input given position. Ignore any collected
5279 // characters.
5280 while (position != end &&
5281 (mozilla::IsAsciiDigit(*position) || *position == '.')) {
5282 ++position;
5283 }
5284
5285 // 9. Let urlRecord be document's URL.
5286 nsCOMPtr<nsIURI> urlRecord(aDocument->GetDocumentURI());
5287
5288 // 10. If position is not past the end of input
5289 if (position != end) {
5290 // 1. If the code point in input pointed to by position is not U+003B (;),
5291 // U+002C (,), or ASCII whitespace, then return.
5292 if (*position != ';' && *position != ',' &&
5293 !mozilla::IsAsciiWhitespace(*position)) {
5294 return;
5295 }
5296
5297 // 2. Skip ASCII whitespace within input given position.
5298 position = SkipASCIIWhitespace(position, end);
5299
5300 // 3. If the code point in input pointed to by position is U+003B (;) or
5301 // U+002C (,), then advance position to the next code point.
5302 if (position != end && (*position == ';' || *position == ',')) {
5303 ++position;
5304
5305 // 4. Skip ASCII whitespace within input given position.
5306 position = SkipASCIIWhitespace(position, end);
5307 }
5308
5309 // 11. If position is not past the end of input, then:
5310 if (position != end) {
5311 const char16_t* urlStart;
5312 const char16_t* urlEnd;
5313
5314 // 1-10. See ExtractURLString.
5315 std::tie(urlStart, urlEnd) = ExtractURLString(position, end);
5316
5317 // 11. Parse: Parse urlString relative to document. If that fails, return.
5318 // Otherwise, set urlRecord to the resulting URL record.
5319 nsresult rv =
5320 NS_NewURI(getter_AddRefs(urlRecord),
5321 Substring(urlStart, std::distance(urlStart, urlEnd)),
5322 /* charset = */ nullptr, aDocument->GetDocBaseURI());
5323 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5323); return; } } while (false)
;
5324 }
5325 }
5326
5327 nsIPrincipal* principal = aDocument->NodePrincipal();
5328 nsCOMPtr<nsIScriptSecurityManager> securityManager =
5329 nsContentUtils::GetSecurityManager();
5330 nsresult rv = securityManager->CheckLoadURIWithPrincipal(
5331 principal, urlRecord,
5332 nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT,
5333 aDocument->InnerWindowID());
5334 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5334); return; } } while (false)
;
5335
5336 bool isjs = true;
5337 rv = NS_URIChainHasFlags(
5338 urlRecord, nsIProtocolHandler::URI_OPENING_EXECUTES_SCRIPT, &isjs);
5339 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/docshell/base/nsDocShell.cpp"
, 5339); return; } } while (false)
;
5340
5341 if (isjs) {
5342 return;
5343 }
5344
5345 RefreshURI(urlRecord, principal, milliSeconds.value());
5346}
5347
5348static void DoCancelRefreshURITimers(nsIMutableArray* aTimerList) {
5349 if (!aTimerList) {
5350 return;
5351 }
5352
5353 uint32_t n = 0;
5354 aTimerList->GetLength(&n);
5355
5356 while (n) {
5357 nsCOMPtr<nsITimer> timer(do_QueryElementAt(aTimerList, --n));
5358
5359 aTimerList->RemoveElementAt(n); // bye bye owning timer ref
5360
5361 if (timer) {
5362 timer->Cancel();
5363 }
5364 }
5365}
5366
5367NS_IMETHODIMPnsresult
5368nsDocShell::CancelRefreshURITimers() {
5369 DoCancelRefreshURITimers(mRefreshURIList);
5370 DoCancelRefreshURITimers(mSavedRefreshURIList);
5371 DoCancelRefreshURITimers(mBFCachedRefreshURIList);
5372 mRefreshURIList = nullptr;
5373 mSavedRefreshURIList = nullptr;
5374 mBFCachedRefreshURIList = nullptr;
5375
5376 return NS_OK;
5377}
5378
5379NS_IMETHODIMPnsresult
5380nsDocShell::GetRefreshPending(bool* aResult) {
5381 if (!mRefreshURIList) {
5382 *aResult = false;
5383 return NS_OK;
5384 }
5385
5386 uint32_t count;
5387 nsresult rv = mRefreshURIList->GetLength(&count);
5388 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5389 *aResult = (count != 0);
5390 }
5391 return rv;
5392}
5393
5394void nsDocShell::RefreshURIToQueue() {
5395 if (mRefreshURIList) {
5396 uint32_t n = 0;
5397 mRefreshURIList->GetLength(&n);
5398
5399 for (uint32_t i = 0; i < n; ++i) {
5400 nsCOMPtr<nsITimer> timer = do_QueryElementAt(mRefreshURIList, i);
5401 if (!timer) {
5402 continue; // this must be a nsRefreshURI already
5403 }
5404
5405 // Replace this timer object with a nsRefreshTimer object.
5406 nsCOMPtr<nsITimerCallback> callback;
5407 timer->GetCallback(getter_AddRefs(callback));
5408
5409 timer->Cancel();
5410
5411 mRefreshURIList->ReplaceElementAt(callback, i);
5412 }
5413 }
5414}
5415
5416NS_IMETHODIMPnsresult
5417nsDocShell::SuspendRefreshURIs() {
5418 RefreshURIToQueue();
5419
5420 // Suspend refresh URIs for our child shells as well.
5421 for (auto* child : mChildList.ForwardRange()) {
5422 nsCOMPtr<nsIDocShell> shell = do_QueryObject(child);
5423 if (shell) {
5424 shell->SuspendRefreshURIs();
5425 }
5426 }
5427
5428 return NS_OK;
5429}
5430
5431NS_IMETHODIMPnsresult
5432nsDocShell::ResumeRefreshURIs() {
5433 RefreshURIFromQueue();
5434
5435 // Resume refresh URIs for our child shells as well.
5436 for (auto* child : mChildList.ForwardRange()) {
5437 nsCOMPtr<nsIDocShell> shell = do_QueryObject(child);
5438 if (shell) {
5439 shell->ResumeRefreshURIs();
5440 }
5441 }
5442
5443 return NS_OK;
5444}
5445
5446nsresult nsDocShell::RefreshURIFromQueue() {
5447 if (!mRefreshURIList) {
5448 return NS_OK;
5449 }
5450 uint32_t n = 0;
5451 mRefreshURIList->GetLength(&n);
5452
5453 while (n) {
5454 nsCOMPtr<nsITimerCallback> refreshInfo =
5455 do_QueryElementAt(mRefreshURIList, --n);
5456
5457 if (refreshInfo) {
5458 // This is the nsRefreshTimer object, waiting to be
5459 // setup in a timer object and fired.
5460 // Create the timer and trigger it.
5461 uint32_t delay = static_cast<nsRefreshTimer*>(
5462 static_cast<nsITimerCallback*>(refreshInfo))
5463 ->GetDelay();
5464 nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
5465 if (win) {
5466 nsCOMPtr<nsITimer> timer;
5467 NS_NewTimerWithCallback(getter_AddRefs(timer), refreshInfo, delay,
5468 nsITimer::TYPE_ONE_SHOT);
5469
5470 if (timer) {
5471 // Replace the nsRefreshTimer element in the queue with
5472 // its corresponding timer object, so that in case another
5473 // load comes through before the timer can go off, the timer will
5474 // get cancelled in CancelRefreshURITimer()
5475 mRefreshURIList->ReplaceElementAt(timer, n);
5476 }
5477 }
5478 }
5479 }
5480
5481 return NS_OK;
5482}
5483
5484static bool IsFollowupPartOfMultipart(nsIRequest* aRequest) {
5485 nsCOMPtr<nsIMultiPartChannel> multiPartChannel = do_QueryInterface(aRequest);
5486 bool firstPart = false;
5487 return multiPartChannel &&
5488 NS_SUCCEEDED(multiPartChannel->GetIsFirstPart(&firstPart))((bool)(__builtin_expect(!!(!NS_FAILED_impl(multiPartChannel->
GetIsFirstPart(&firstPart))), 1)))
&&
5489 !firstPart;
5490}
5491
5492nsresult nsDocShell::Embed(nsIDocumentViewer* aDocumentViewer,
5493 WindowGlobalChild* aWindowActor,