Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/CmdLineAndEnvUtils.h
Warning:line 710, column 1
Potential leak of memory pointed to by 'expr'

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 nsAppRunner.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/toolkit/xre -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/xre -resource-dir /usr/lib/llvm-20/lib/clang/20 -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 _GLIBCXX_ASSERTIONS -D DEBUG=1 -D TELEMETRY_PING_FORMAT_VERSION=4 -D PROXY_PRINTING=1 -D USE_GLX_TEST -D MOZ_APP_NAME="firefox" -D MOZ_APP_BASENAME="Firefox" -D MOZ_APP_DISPLAYNAME="Nightly" -D MOZ_APP_VENDOR="Mozilla" -D MOZ_APP_VERSION="136.0a1" -D OS_TARGET="Linux" -D MOZ_WIDGET_TOOLKIT="gtk" -D MOZ_UPDATER -D MOZ_DISTRIBUTION_ID="org.mozilla" -D TARGET_OS_ABI="Linux_x86_64-gcc3" -D GRE_MILESTONE=136.0a1 -D MOZ_APP_VERSION_DISPLAY=136.0a1 -D APP_VERSION=136.0a1 -D APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384} -D MOZ_BUILD_APP_IS_BROWSER -D MAR_NSS -D TOPOBJDIR=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/xre -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/remote -I /var/lib/jenkins/workspace/firefox-scan-build/widget -I /var/lib/jenkins/workspace/firefox-scan-build/widget/gtk -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/printingui -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/other-licenses/nsis/Contrib/CityHash/cityhash -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/find -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/printingui/ipc -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/windowwatcher -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/mozapps/update/common -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/profile -I /var/lib/jenkins/workspace/firefox-scan-build/config -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler -I /var/lib/jenkins/workspace/firefox-scan-build/dom/ipc -I /var/lib/jenkins/workspace/firefox-scan-build/dom/webbrowserpersist -I /var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/loader -I /var/lib/jenkins/workspace/firefox-scan-build/testing/gtest/mozilla -I /var/lib/jenkins/workspace/firefox-scan-build/third_party/sqlite3/ext -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/crashreporter -I /var/lib/jenkins/workspace/firefox-scan-build/xpcom/build -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 -I /usr/include/uuid -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gtk-3.0/unix-print -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../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 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -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-2025-01-20-090804-167946-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp

/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp

1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6#include "mozilla/dom/ContentParent.h"
7#include "mozilla/dom/ContentChild.h"
8#include "mozilla/ipc/GeckoChildProcessHost.h"
9
10#include "mozilla/AppShutdown.h"
11#include "mozilla/ArrayUtils.h"
12#include "mozilla/Assertions.h"
13#include "mozilla/Attributes.h"
14#include "mozilla/Components.h"
15#include "mozilla/FilePreferences.h"
16#include "mozilla/ChaosMode.h"
17#include "mozilla/CmdLineAndEnvUtils.h"
18#include "mozilla/IOInterposer.h"
19#include "mozilla/ipc/UtilityProcessChild.h"
20#include "mozilla/Likely.h"
21#include "mozilla/MemoryChecking.h"
22#include "mozilla/Poison.h"
23#include "mozilla/Preferences.h"
24#include "mozilla/PreferenceSheet.h"
25#include "mozilla/Printf.h"
26#include "mozilla/ProcessType.h"
27#include "mozilla/ResultExtensions.h"
28#include "mozilla/RuntimeExceptionModule.h"
29#include "mozilla/ScopeExit.h"
30#include "mozilla/StaticPrefs_browser.h"
31#include "mozilla/StaticPrefs_fission.h"
32#include "mozilla/StaticPrefs_webgl.h"
33#include "mozilla/StaticPrefs_widget.h"
34#include "mozilla/Telemetry.h"
35#include "mozilla/Try.h"
36#include "mozilla/Utf8.h"
37#include "mozilla/intl/LocaleService.h"
38#include "mozilla/JSONWriter.h"
39#include "mozilla/gfx/gfxVars.h"
40#include "mozilla/glean/GleanMetrics.h"
41#include "mozilla/glean/GleanPings.h"
42#include "mozilla/widget/TextRecognition.h"
43#include "BaseProfiler.h"
44#include "mozJSModuleLoader.h"
45
46#include "nsAppRunner.h"
47#include "mozilla/XREAppData.h"
48#include "mozilla/Bootstrap.h"
49#if defined(MOZ_UPDATER1) && !defined(MOZ_WIDGET_ANDROID)
50# include "nsUpdateDriver.h"
51# include "nsUpdateSyncManager.h"
52#endif
53#include "ProfileReset.h"
54
55#ifdef XP_MACOSX
56# include "nsVersionComparator.h"
57# include "MacLaunchHelper.h"
58# include "MacApplicationDelegate.h"
59# include "MacAutoreleasePool.h"
60# include "MacRunFromDmgUtils.h"
61// these are needed for sysctl
62# include <sys/types.h>
63# include <sys/sysctl.h>
64#endif
65
66#include "prnetdb.h"
67#include "prprf.h"
68#include "prproces.h"
69#include "prenv.h"
70#include "prtime.h"
71
72#include "nsIAppStartup.h"
73#include "nsCategoryManagerUtils.h"
74#include "nsIMutableArray.h"
75#include "nsCommandLine.h"
76#include "nsIComponentRegistrar.h"
77#include "nsIDialogParamBlock.h"
78#include "mozilla/ModuleUtils.h"
79#include "nsIIOService.h"
80#include "nsIObserverService.h"
81#include "nsINativeAppSupport.h"
82#include "nsIPlatformInfo.h"
83#include "nsIProcess.h"
84#include "nsIProfileUnlocker.h"
85#include "nsIPromptService.h"
86#include "nsIPropertyBag2.h"
87#include "nsIServiceManager.h"
88#include "nsIStringBundle.h"
89#include "nsISupportsPrimitives.h"
90#include "nsIToolkitProfile.h"
91#include "nsToolkitProfileService.h"
92#include "nsIURI.h"
93#include "nsIURL.h"
94#include "nsIWindowCreator.h"
95#include "nsIWindowWatcher.h"
96#include "nsIXULAppInfo.h"
97#include "nsIXULRuntime.h"
98#include "nsPIDOMWindow.h"
99#include "nsIWidget.h"
100#include "nsAppShellCID.h"
101#include "mozilla/dom/quota/QuotaManager.h"
102#include "mozilla/scache/StartupCache.h"
103#include "gfxPlatform.h"
104#include "PDMFactory.h"
105#ifdef XP_MACOSX
106# include "gfxPlatformMac.h"
107#endif
108
109#include "mozilla/Unused.h"
110
111#ifdef XP_WIN
112# include "nsIWinAppHelper.h"
113# include <windows.h>
114# include <intrin.h>
115# include <math.h>
116# include "cairo/cairo-features.h"
117# include "detect_win32k_conflicts.h"
118# include "mozilla/PreXULSkeletonUI.h"
119# include "mozilla/DllPrefetchExperimentRegistryInfo.h"
120# include "mozilla/WindowsBCryptInitialization.h"
121# include "mozilla/WindowsDllBlocklist.h"
122# include "mozilla/WindowsMsctfInitialization.h"
123# include "mozilla/WindowsOleAut32Initialization.h"
124# include "mozilla/WindowsProcessMitigations.h"
125# include "mozilla/WindowsVersion.h"
126# include "mozilla/WinHeaderOnlyUtils.h"
127# include "mozilla/mscom/ProcessRuntime.h"
128# include "mozilla/mscom/ProfilerMarkers.h"
129# include "WinTokenUtils.h"
130
131# if defined(MOZ_LAUNCHER_PROCESS)
132# include "mozilla/LauncherRegistryInfo.h"
133# endif
134
135# if defined(MOZ_DEFAULT_BROWSER_AGENT)
136# include "nsIWindowsRegKey.h"
137# endif
138
139# ifndef PROCESS_DEP_ENABLE
140# define PROCESS_DEP_ENABLE 0x1
141# endif
142#endif
143
144#if defined(MOZ_SANDBOX1)
145# include "mozilla/SandboxSettings.h"
146#endif
147
148#ifdef ACCESSIBILITY1
149# include "nsAccessibilityService.h"
150# if defined(XP_WIN)
151# include "mozilla/a11y/Compatibility.h"
152# include "mozilla/a11y/Platform.h"
153# endif
154#endif
155
156#include "nsCRT.h"
157#include "nsCOMPtr.h"
158#include "nsDirectoryServiceDefs.h"
159#include "nsDirectoryServiceUtils.h"
160#include "nsEmbedCID.h"
161#include "nsIDUtils.h"
162#include "nsNetUtil.h"
163#include "nsReadableUtils.h"
164#include "nsXPCOM.h"
165#include "nsXPCOMCIDInternal.h"
166#include "nsString.h"
167#include "nsPrintfCString.h"
168#include "nsVersionComparator.h"
169
170#include "nsAppDirectoryServiceDefs.h"
171#include "nsXULAppAPI.h"
172#include "nsXREDirProvider.h"
173
174#include "nsINIParser.h"
175#include "mozilla/Omnijar.h"
176#include "mozilla/StartupTimeline.h"
177#include "mozilla/LateWriteChecks.h"
178
179#include <stdlib.h>
180#include <locale.h>
181
182#ifdef XP_UNIX1
183# include <errno(*__errno_location ()).h>
184# include <pwd.h>
185# include <string.h>
186# include <sys/resource.h>
187# include <sys/stat.h>
188# include <unistd.h>
189#endif
190
191#ifdef XP_WIN
192# include <process.h>
193# include <shlobj.h>
194# include "mozilla/WinDllServices.h"
195# include "nsThreadUtils.h"
196# include "WinUtils.h"
197#endif
198
199#ifdef XP_MACOSX
200# include "nsILocalFileMac.h"
201# include "nsCommandLineServiceMac.h"
202#endif
203
204// for X remote support
205#if defined(MOZ_HAS_REMOTE1)
206# include "nsRemoteService.h"
207#endif
208
209#if defined(DEBUG1) && defined(XP_WIN)
210# include <malloc.h>
211#endif
212
213#if defined(XP_MACOSX)
214# include <Carbon/Carbon.h>
215#endif
216
217#ifdef DEBUG1
218# include "mozilla/Logging.h"
219#endif
220
221#include "nsExceptionHandler.h"
222#include "nsICrashReporter.h"
223#include "nsIPrefService.h"
224#include "nsIMemoryInfoDumper.h"
225#include "js/String.h"
226#if defined(XP_LINUX1) && !defined(ANDROID)
227# include "mozilla/widget/LSBUtils.h"
228#endif
229
230#include "base/command_line.h"
231#include "GTestRunner.h"
232
233#ifdef MOZ_WIDGET_ANDROID
234# include "gfxAndroidPlatform.h"
235# include "mozilla/java/GeckoAppShellWrappers.h"
236#endif
237
238#if defined(MOZ_SANDBOX1)
239# if defined(XP_LINUX1) && !defined(ANDROID)
240# include "mozilla/SandboxInfo.h"
241# elif defined(XP_WIN)
242# include "sandboxBroker.h"
243# endif
244#endif
245
246#ifdef MOZ_CODE_COVERAGE
247# include "mozilla/CodeCoverageHandler.h"
248#endif
249
250#include "GMPProcessChild.h"
251#include "SafeMode.h"
252
253#ifdef MOZ_BACKGROUNDTASKS1
254# include "mozilla/BackgroundTasks.h"
255# include "nsIPowerManagerService.h"
256# include "nsIStringBundle.h"
257#endif
258
259#ifdef USE_GLX_TEST1
260# include "mozilla/GUniquePtr.h"
261# include "mozilla/GfxInfo.h"
262#endif
263
264#ifdef MOZ_WIDGET_GTK1
265# include "nsAppShell.h"
266#endif
267#ifdef MOZ_ENABLE_DBUS1
268# include "DBusService.h"
269#endif
270
271extern uint32_t gRestartMode;
272extern void InstallSignalHandlers(const char* ProgramName);
273
274#define FILE_COMPATIBILITY_INFO"compatibility.ini"_ns "compatibility.ini"_ns
275#define FILE_INVALIDATE_CACHES".purgecaches"_ns ".purgecaches"_ns
276#define FILE_STARTUP_INCOMPLETEu".startup-incomplete"_ns u".startup-incomplete"_ns
277
278#if defined(MOZ_BLOCK_PROFILE_DOWNGRADE1) || defined(MOZ_LAUNCHER_PROCESS) || \
279 defined(MOZ_DEFAULT_BROWSER_AGENT)
280static const char kPrefHealthReportUploadEnabled[] =
281 "datareporting.healthreport.uploadEnabled";
282#endif // defined(MOZ_BLOCK_PROFILE_DOWNGRADE) || defined(MOZ_LAUNCHER_PROCESS)
283 // || defined(MOZ_DEFAULT_BROWSER_AGENT)
284#if defined(MOZ_DEFAULT_BROWSER_AGENT)
285static const char kPrefDefaultAgentEnabled[] = "default-browser-agent.enabled";
286
287static const char kPrefServicesSettingsServer[] = "services.settings.server";
288static const char kPrefSetDefaultBrowserUserChoicePref[] =
289 "browser.shell.setDefaultBrowserUserChoice";
290#endif // defined(MOZ_DEFAULT_BROWSER_AGENT)
291
292#if defined(XP_WIN)
293static const char kPrefThemeId[] = "extensions.activeThemeID";
294static const char kPrefBrowserStartupBlankWindow[] =
295 "browser.startup.blankWindow";
296static const char kPrefPreXulSkeletonUI[] = "browser.startup.preXulSkeletonUI";
297#endif // defined(XP_WIN)
298
299#if defined(MOZ_WIDGET_GTK1)
300constexpr nsLiteralCString kStartupTokenNames[] = {
301 "XDG_ACTIVATION_TOKEN"_ns,
302 "DESKTOP_STARTUP_ID"_ns,
303};
304#endif
305
306int gArgc;
307char** gArgv;
308
309static const char gToolkitVersion[] = MOZ_STRINGIFY(GRE_MILESTONE)"136.0a1";
310// The gToolkitBuildID global is defined to MOZ_BUILDID via gen_buildid.py
311// in toolkit/library. See related comment in toolkit/library/moz.build.
312extern const char gToolkitBuildID[];
313
314static nsIProfileLock* gProfileLock;
315#if defined(MOZ_HAS_REMOTE1)
316MOZ_RUNINIT static RefPtr<nsRemoteService> gRemoteService;
317MOZ_RUNINIT static RefPtr<nsStartupLock> gStartupLock;
318#endif
319
320int gRestartArgc;
321char** gRestartArgv;
322
323// If gRestartedByOS is set, we were automatically restarted by the OS.
324bool gRestartedByOS = false;
325
326bool gIsGtest = false;
327
328bool gKioskMode = false;
329int gKioskMonitor = -1;
330
331bool gAllowContentAnalysisArgPresent = false;
332
333MOZ_CONSTINIT[[clang::require_constant_initialization]] nsString gAbsoluteArgv0Path;
334
335#if defined(XP_WIN)
336MOZ_CONSTINIT[[clang::require_constant_initialization]] nsString gProcessStartupShortcut;
337#endif
338
339#if defined(MOZ_WIDGET_GTK1)
340# include <glib.h>
341# include "mozilla/WidgetUtilsGtk.h"
342# include <gtk/gtk.h>
343# ifdef MOZ_WAYLAND1
344# include <gdk/gdkwayland.h>
345# include "mozilla/widget/nsWaylandDisplay.h"
346# include "wayland-proxy.h"
347# endif
348# ifdef MOZ_X111
349# include <gdk/gdkx.h>
350# endif /* MOZ_X11 */
351#endif
352
353#if defined(MOZ_WAYLAND1)
354MOZ_RUNINIT std::unique_ptr<WaylandProxy> gWaylandProxy;
355#endif
356
357#include "BinaryPath.h"
358
359#ifdef FUZZING
360# include "FuzzerRunner.h"
361
362namespace mozilla {
363FuzzerRunner* fuzzerRunner = 0;
364} // namespace mozilla
365
366# ifdef LIBFUZZER
367void XRE_LibFuzzerSetDriver(LibFuzzerDriver aDriver) {
368 mozilla::fuzzerRunner->setParams(aDriver);
369}
370# endif
371#endif // FUZZING
372
373// Undo X11/X.h's definition of None
374#undef None
375
376namespace mozilla {
377int (*RunGTest)(int*, char**) = 0;
378
379bool RunningGTest() { return RunGTest; }
380} // namespace mozilla
381
382using namespace mozilla;
383using namespace mozilla::widget;
384using namespace mozilla::startup;
385using mozilla::Unused;
386using mozilla::dom::ContentChild;
387using mozilla::dom::ContentParent;
388using mozilla::dom::quota::QuotaManager;
389using mozilla::intl::LocaleService;
390using mozilla::scache::StartupCache;
391
392// Save the given word to the specified environment variable.
393static void MOZ_NEVER_INLINE__attribute__((noinline)) SaveWordToEnv(const char* name,
394 const nsACString& word) {
395 char* expr =
396 Smprintf("%s=%s", name, PromiseFlatCStringTPromiseFlatString<char>(word).get()).release();
397 if (expr) PR_SetEnv(expr);
398 // We intentionally leak |expr| here since it is required by PR_SetEnv.
399}
400
401// Save the path of the given file to the specified environment variable.
402static void SaveFileToEnv(const char* name, nsIFile* file) {
403#ifdef XP_WIN
404 nsAutoString path;
405 file->GetPath(path);
406 SetEnvironmentVariableW(NS_ConvertASCIItoUTF16(name).get(), path.get());
407#else
408 nsAutoCString path;
409 file->GetNativePath(path);
410 SaveWordToEnv(name, path);
411#endif
412}
413
414static bool gIsExpectedExit = false;
415
416void MozExpectedExit() { gIsExpectedExit = true; }
417
418/**
419 * Runs atexit() to catch unexpected exit from 3rd party libraries like the
420 * Intel graphics driver calling exit in an error condition. When they
421 * call exit() to report an error we won't shutdown correctly and wont catch
422 * the issue with our crash reporter.
423 */
424static void UnexpectedExit() {
425 if (!gIsExpectedExit) {
426 gIsExpectedExit = true; // Don't risk re-entrency issues when crashing.
427 MOZ_CRASH("Exit called by third party code.")do { do { } while (false); MOZ_ReportCrash("" "Exit called by third party code."
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 427); AnnotateMozCrashReason("MOZ_CRASH(" "Exit called by third party code."
")"); do { *((volatile int*)__null) = 427; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
428 }
429}
430
431#if defined(MOZ_WAYLAND1)
432bool IsWaylandEnabled() {
433 static bool isWaylandEnabled = []() {
434 const char* waylandDisplay = PR_GetEnv("WAYLAND_DISPLAY");
435 if (!waylandDisplay) {
436 return false;
437 }
438 if (!PR_GetEnv("DISPLAY")) {
439 // No X11 display, so try to run wayland.
440 return true;
441 }
442 // MOZ_ENABLE_WAYLAND is our primary Wayland on/off switch.
443 if (const char* waylandPref = PR_GetEnv("MOZ_ENABLE_WAYLAND")) {
444 return *waylandPref == '1';
445 }
446 if (const char* backendPref = PR_GetEnv("GDK_BACKEND")) {
447 if (!strncmp(backendPref, "wayland", 7)) {
448 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."
"GDK_BACKEND is a Gtk3 debug variable and may cause issues."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 450)
449 "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."NS_DebugBreak(NS_DEBUG_WARNING, "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."
"GDK_BACKEND is a Gtk3 debug variable and may cause issues."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 450)
450 "GDK_BACKEND is a Gtk3 debug variable and may cause issues.")NS_DebugBreak(NS_DEBUG_WARNING, "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."
"GDK_BACKEND is a Gtk3 debug variable and may cause issues."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 450)
;
451 return true;
452 }
453 }
454 // Enable by default when we're running on a recent enough GTK version. We'd
455 // like to check further details like compositor version and so on ideally
456 // to make sure we don't enable it on old Mutter or what not, but we can't,
457 // so let's assume that if the user is running on a Wayland session by
458 // default we're ok, since either the distro has enabled Wayland by default,
459 // or the user has gone out of their way to use Wayland.
460 return !gtk_check_version(3, 24, 30);
461 }();
462 return isWaylandEnabled;
463}
464#else
465bool IsWaylandEnabled() { return false; }
466#endif
467
468/**
469 * Output a string to the user. This method is really only meant to be used to
470 * output last-ditch error messages designed for developers NOT END USERS.
471 *
472 * @param isError
473 * Pass true to indicate severe errors.
474 * @param fmt
475 * printf-style format string followed by arguments.
476 */
477static MOZ_FORMAT_PRINTF(2, 3)__attribute__((format(printf, 2, 3))) void Output(bool isError, const char* fmt, ...) {
478 va_list ap;
479 va_start(ap, fmt)__builtin_va_start(ap, fmt);
480
481#if defined(XP_WIN) && !MOZ_WINCONSOLE
482 SmprintfPointer msg = mozilla::Vsmprintf(fmt, ap);
483 if (msg) {
484 UINT flags = MB_OK;
485 if (isError)
486 flags |= MB_ICONERROR;
487 else
488 flags |= MB_ICONINFORMATION;
489
490 wchar_t wide_msg[1024];
491 MultiByteToWideChar(CP_ACP, 0, msg.get(), -1, wide_msg,
492 sizeof(wide_msg) / sizeof(wchar_t));
493
494 wchar_t wide_caption[128];
495 MultiByteToWideChar(CP_ACP, 0, gAppData ? gAppData->name : "XULRunner", -1,
496 wide_caption, sizeof(wide_caption) / sizeof(wchar_t));
497 MessageBoxW(nullptr, wide_msg, wide_caption, flags);
498 }
499#elif defined(MOZ_WIDGET_ANDROID)
500 SmprintfPointer msg = mozilla::Vsmprintf(fmt, ap);
501 if (msg) {
502 __android_log_print(isError ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO,
503 "GeckoRuntime", "%s", msg.get());
504 }
505#else
506 vfprintf(stderrstderr, fmt, ap);
507#endif
508
509 va_end(ap)__builtin_va_end(ap);
510}
511
512/**
513 * Check for a commandline flag. If the flag takes a parameter, the
514 * parameter is returned in aParam. Flags may be in the form -arg or
515 * --arg (or /arg on win32).
516 *
517 * @param aArg the parameter to check. Must be lowercase.
518 * @param aParam if non-null, the -arg <data> will be stored in this pointer.
519 * This is *not* allocated, but rather a pointer to the argv data.
520 * @param aFlags flags @see CheckArgFlag
521 */
522static ArgResult CheckArg(const char* aArg, const char** aParam = nullptr,
523 CheckArgFlag aFlags = CheckArgFlag::RemoveArg) {
524 MOZ_ASSERT(gArgv, "gArgv must be initialized before CheckArg()")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gArgv)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(gArgv))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("gArgv" " (" "gArgv must be initialized before CheckArg()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 524); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gArgv" ") ("
"gArgv must be initialized before CheckArg()" ")"); do { *((
volatile int*)__null) = 524; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
525 return CheckArg(gArgc, gArgv, aArg, aParam, aFlags);
526}
527
528/**
529 * Check for a commandline flag. Ignore data that's passed in with the flag.
530 * Flags may be in the form -arg or --arg (or /arg on win32).
531 * Will not remove flag if found.
532 *
533 * @param aArg the parameter to check. Must be lowercase.
534 */
535static ArgResult CheckArgExists(const char* aArg) {
536 return CheckArg(aArg, nullptr, CheckArgFlag::None);
537}
538
539bool gSafeMode = false;
540bool gFxREmbedded = false;
541
542enum E10sStatus {
543 kE10sEnabledByDefault,
544 kE10sForceDisabled,
545};
546
547static bool gBrowserTabsRemoteAutostart = false;
548static E10sStatus gBrowserTabsRemoteStatus;
549static bool gBrowserTabsRemoteAutostartInitialized = false;
550
551namespace mozilla {
552
553bool BrowserTabsRemoteAutostart() {
554 if (gBrowserTabsRemoteAutostartInitialized) {
555 return gBrowserTabsRemoteAutostart;
556 }
557 gBrowserTabsRemoteAutostartInitialized = true;
558
559 // If we're not in the parent process, we are running E10s.
560 if (!XRE_IsParentProcess()) {
561 gBrowserTabsRemoteAutostart = true;
562 return gBrowserTabsRemoteAutostart;
563 }
564
565 gBrowserTabsRemoteAutostart = true;
566 E10sStatus status = kE10sEnabledByDefault;
567
568// We are checking to ensure that either MOZILLA_OFFICIAL is undefined or that
569// xpc::AreNonLocalConnectionsDisabled() is true. If either check matches,
570// we move on to check the MOZ_FORCE_DISABLE_E10S environment variable which
571// must equal "1" to proceed with disabling e10s.
572#if defined(MOZILLA_OFFICIAL)
573 bool allowDisablingE10s = xpc::AreNonLocalConnectionsDisabled();
574#else
575 bool allowDisablingE10s = true;
576#endif
577
578 if (gBrowserTabsRemoteAutostart && allowDisablingE10s) {
579 const char* forceDisable = PR_GetEnv("MOZ_FORCE_DISABLE_E10S");
580 if (forceDisable && !strcmp(forceDisable, "1")) {
581 gBrowserTabsRemoteAutostart = false;
582 status = kE10sForceDisabled;
583 }
584 }
585
586 gBrowserTabsRemoteStatus = status;
587
588 return gBrowserTabsRemoteAutostart;
589}
590
591} // namespace mozilla
592
593// Win32k Infrastructure ==============================================
594
595// This bool tells us if we have initialized the following two statics
596// upon startup.
597
598static bool gWin32kInitialized = false;
599
600// Win32k Lockdown for the current session is determined once, at startup,
601// and then remains the same for the duration of the session.
602
603static nsIXULRuntime::ContentWin32kLockdownState gWin32kStatus;
604
605// The status of the win32k experiment. It is determined once, at startup,
606// and then remains the same for the duration of the session.
607
608static nsIXULRuntime::ExperimentStatus gWin32kExperimentStatus =
609 nsIXULRuntime::eExperimentStatusUnenrolled;
610
611#ifdef XP_WIN
612// The states for win32k lockdown can be generalized to:
613// - User doesn't meet requirements (bad OS, webrender, remotegl) aka
614// PersistentRequirement
615// - User has Safe Mode enabled, Win32k Disabled by Env Var, or E10S disabled
616// by Env Var aka TemporaryRequirement
617// - User has set the win32k pref to something non-default aka NonDefaultPref
618// - User has been enrolled in the experiment and does what it says aka
619// Enrolled
620// - User does the default aka Default
621//
622// We expect the below behvaior. In the code, there may be references to these
623// behaviors (e.g. [A]) but not always.
624//
625// [A] Becoming enrolled in the experiment while NonDefaultPref disqualifies
626// you upon next browser start
627// [B] Becoming enrolled in the experiment while PersistentRequirement
628// disqualifies you upon next browser start
629// [C] Becoming enrolled in the experiment while TemporaryRequirement does not
630// disqualify you
631// [D] Becoming enrolled in the experiment will only take effect after restart
632// [E] While enrolled, becoming PersistentRequirement will not disqualify you
633// until browser restart, but if the state is present at browser start,
634// will disqualify you. Additionally, it will not affect the session value
635// of gWin32kStatus.
636// XXX(bobowen): I hope both webrender and wbgl.out-of-process require a
637// restart to take effect!
638// [F] While enrolled, becoming NonDefaultPref will disqualify you upon next
639// browser start
640// [G] While enrolled, becoming TemporaryRequirement will _not_ disqualify you,
641// but the session status will prevent win32k lockdown from taking effect.
642
643// The win32k pref
644static const char kPrefWin32k[] = "security.sandbox.content.win32k-disable";
645
646// The current enrollment status as controlled by Normandy. This value is only
647// stored in the default preference branch, and is not persisted across
648// sessions by the preference service. It therefore isn't available early
649// enough at startup, and needs to be synced to a preference in the user
650// branch which is persisted across sessions.
651static const char kPrefWin32kExperimentEnrollmentStatus[] =
652 "security.sandbox.content.win32k-experiment.enrollmentStatus";
653
654// The enrollment status to be used at browser startup. This automatically
655// synced from the above enrollmentStatus preference whenever the latter is
656// changed. We reused the Fission experiment enum - it can have any of the
657// values defined in the `nsIXULRuntime_ExperimentStatus` enum _except_ rollout.
658// Meanings are documented in the declaration of
659// `nsIXULRuntime.fissionExperimentStatus`
660static const char kPrefWin32kExperimentStartupEnrollmentStatus[] =
661 "security.sandbox.content.win32k-experiment.startupEnrollmentStatus";
662
663namespace mozilla {
664
665bool Win32kExperimentEnrolled() {
666 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 666; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
667 return gWin32kExperimentStatus == nsIXULRuntime::eExperimentStatusControl ||
668 gWin32kExperimentStatus == nsIXULRuntime::eExperimentStatusTreatment;
669}
670
671} // namespace mozilla
672
673static bool Win32kRequirementsUnsatisfied(
674 nsIXULRuntime::ContentWin32kLockdownState aStatus) {
675 return aStatus == nsIXULRuntime::ContentWin32kLockdownState::
676 OperatingSystemNotSupported ||
677 aStatus ==
678 nsIXULRuntime::ContentWin32kLockdownState::MissingWebRender ||
679 aStatus ==
680 nsIXULRuntime::ContentWin32kLockdownState::MissingRemoteWebGL ||
681 aStatus ==
682 nsIXULRuntime::ContentWin32kLockdownState::DecodersArentRemote;
683}
684
685static void Win32kExperimentDisqualify() {
686 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 686); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 686; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
687 Preferences::SetUint(kPrefWin32kExperimentEnrollmentStatus,
688 nsIXULRuntime::eExperimentStatusDisqualified);
689}
690
691static void OnWin32kEnrollmentStatusChanged(const char* aPref, void* aData) {
692 auto newStatusInt =
693 Preferences::GetUint(kPrefWin32kExperimentEnrollmentStatus,
694 nsIXULRuntime::eExperimentStatusUnenrolled);
695 auto newStatus = newStatusInt < nsIXULRuntime::eExperimentStatusCount
696 ? nsIXULRuntime::ExperimentStatus(newStatusInt)
697 : nsIXULRuntime::eExperimentStatusDisqualified;
698
699 // Set the startup pref for next browser start [D]
700 Preferences::SetUint(kPrefWin32kExperimentStartupEnrollmentStatus, newStatus);
701}
702
703namespace {
704// This observer is notified during `profile-before-change`, and ensures that
705// the experiment enrollment status is synced over before the browser shuts
706// down, even if it was not modified since win32k was initialized.
707class Win32kEnrollmentStatusShutdownObserver final : public nsIObserver {
708 public:
709 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:
710
711 NS_IMETHODvirtual nsresult Observe(nsISupports* aSubject, const char* aTopic,
712 const char16_t* aData) override {
713 MOZ_ASSERT(!strcmp("profile-before-change", aTopic))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!strcmp("profile-before-change", aTopic))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!strcmp("profile-before-change", aTopic)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!strcmp(\"profile-before-change\", aTopic)"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 713); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!strcmp(\"profile-before-change\", aTopic)"
")"); do { *((volatile int*)__null) = 713; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
714 OnWin32kEnrollmentStatusChanged(kPrefWin32kExperimentEnrollmentStatus,
715 nullptr);
716 return NS_OK;
717 }
718
719 private:
720 ~Win32kEnrollmentStatusShutdownObserver() = default;
721};
722NS_IMPL_ISUPPORTS(Win32kEnrollmentStatusShutdownObserver, nsIObserver)MozExternalRefCountType Win32kEnrollmentStatusShutdownObserver
::AddRef(void) { static_assert(!std::is_destructible_v<Win32kEnrollmentStatusShutdownObserver
>, "Reference-counted class " "Win32kEnrollmentStatusShutdownObserver"
" 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/toolkit/xre/nsAppRunner.cpp"
, 722); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
722; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("Win32kEnrollmentStatusShutdownObserver" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("Win32kEnrollmentStatusShutdownObserver" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 722); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 722; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("Win32kEnrollmentStatusShutdownObserver" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"Win32kEnrollmentStatusShutdownObserver"), (uint32_t)(sizeof(
*this))); return count; } MozExternalRefCountType Win32kEnrollmentStatusShutdownObserver
::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/toolkit/xre/nsAppRunner.cpp"
, 722); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 722
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("Win32kEnrollmentStatusShutdownObserver" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("Win32kEnrollmentStatusShutdownObserver" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 722); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 722; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("Win32kEnrollmentStatusShutdownObserver" " not thread-safe"
); const char* const nametmp = "Win32kEnrollmentStatusShutdownObserver"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult Win32kEnrollmentStatusShutdownObserver
::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/toolkit/xre/nsAppRunner.cpp"
, 722); 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<Win32kEnrollmentStatusShutdownObserver, nsIObserver
>, int32_t( reinterpret_cast<char*>(static_cast<nsIObserver
*>((Win32kEnrollmentStatusShutdownObserver*)0x1000)) - reinterpret_cast
<char*>((Win32kEnrollmentStatusShutdownObserver*)0x1000
))}, {&mozilla::detail::kImplementedIID<Win32kEnrollmentStatusShutdownObserver
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIObserver*>((Win32kEnrollmentStatusShutdownObserver
*)0x1000))) - reinterpret_cast<char*>((Win32kEnrollmentStatusShutdownObserver
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
723} // namespace
724
725static void OnWin32kChanged(const char* aPref, void* aData) {
726 // If we're actively enrolled in the Win32k experiment, disqualify the user
727 // from the experiment if the Win32k pref is modified. [F]
728 if (Win32kExperimentEnrolled() && Preferences::HasUserValue(kPrefWin32k)) {
729 Win32kExperimentDisqualify();
730 }
731}
732
733#endif // XP_WIN
734
735namespace mozilla {
736void EnsureWin32kInitialized();
737}
738
739nsIXULRuntime::ContentWin32kLockdownState GetLiveWin32kLockdownState() {
740#ifdef XP_WIN
741
742 // HasUserValue The Pref functions can only be called on main thread
743 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 743); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 743; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
744
745# ifdef MOZ_BACKGROUNDTASKS1
746 if (BackgroundTasks::IsBackgroundTaskMode()) {
747 // Let's bail out before loading all the graphics libs.
748 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByDefault;
749 }
750# endif
751
752 mozilla::EnsureWin32kInitialized();
753 gfxPlatform::GetPlatform();
754
755 if (gSafeMode) {
756 return nsIXULRuntime::ContentWin32kLockdownState::DisabledBySafeMode;
757 }
758
759 if (EnvHasValue("MOZ_ENABLE_WIN32K")) {
760 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByEnvVar;
761 }
762
763 if (!mozilla::BrowserTabsRemoteAutostart()) {
764 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByE10S;
765 }
766
767 // Win32k lockdown is available on Win8+, but we are initially limiting it to
768 // Windows 10 v1709 (build 16299) or later. Before this COM initialization
769 // currently fails if user32.dll has loaded before it is called.
770 if (!IsWin10FallCreatorsUpdateOrLater()) {
771 return nsIXULRuntime::ContentWin32kLockdownState::
772 OperatingSystemNotSupported;
773 }
774
775 {
776 ConflictingMitigationStatus conflictingMitigationStatus = {};
777 if (!detect_win32k_conflicting_mitigations(&conflictingMitigationStatus)) {
778 return nsIXULRuntime::ContentWin32kLockdownState::
779 IncompatibleMitigationPolicy;
780 }
781 if (conflictingMitigationStatus.caller_check ||
782 conflictingMitigationStatus.sim_exec ||
783 conflictingMitigationStatus.stack_pivot) {
784 return nsIXULRuntime::ContentWin32kLockdownState::
785 IncompatibleMitigationPolicy;
786 }
787 }
788
789 // Win32k Lockdown requires Remote WebGL, but it may be disabled on
790 // certain hardware or virtual machines.
791 if (!gfx::gfxVars::AllowWebglOop() || !StaticPrefs::webgl_out_of_process()) {
792 return nsIXULRuntime::ContentWin32kLockdownState::MissingRemoteWebGL;
793 }
794
795 // Some (not sure exactly which) decoders are not compatible
796 if (!PDMFactory::AllDecodersAreRemote()) {
797 return nsIXULRuntime::ContentWin32kLockdownState::DecodersArentRemote;
798 }
799
800 bool prefSetByUser =
801 Preferences::HasUserValue("security.sandbox.content.win32k-disable");
802 bool prefValue = Preferences::GetBool(
803 "security.sandbox.content.win32k-disable", false, PrefValueKind::User);
804 bool defaultValue = Preferences::GetBool(
805 "security.sandbox.content.win32k-disable", false, PrefValueKind::Default);
806
807 if (prefSetByUser) {
808 if (prefValue) {
809 return nsIXULRuntime::ContentWin32kLockdownState::EnabledByUserPref;
810 } else {
811 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByUserPref;
812 }
813 }
814
815 if (gWin32kExperimentStatus ==
816 nsIXULRuntime::ExperimentStatus::eExperimentStatusControl) {
817 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByControlGroup;
818 } else if (gWin32kExperimentStatus ==
819 nsIXULRuntime::ExperimentStatus::eExperimentStatusTreatment) {
820 return nsIXULRuntime::ContentWin32kLockdownState::EnabledByTreatmentGroup;
821 }
822
823 if (defaultValue) {
824 return nsIXULRuntime::ContentWin32kLockdownState::EnabledByDefault;
825 } else {
826 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByDefault;
827 }
828
829#else
830
831 return nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
832
833#endif
834}
835
836namespace mozilla {
837
838void EnsureWin32kInitialized() {
839 if (gWin32kInitialized) {
840 return;
841 }
842 gWin32kInitialized = true;
843
844#ifdef XP_WIN
845
846 // Initialize the Win32k experiment, configuring win32k's
847 // default, before checking other overrides. This allows opting-out of a
848 // Win32k experiment through about:preferences or about:config from a
849 // safemode session.
850 uint32_t experimentRaw =
851 Preferences::GetUint(kPrefWin32kExperimentStartupEnrollmentStatus,
852 nsIXULRuntime::eExperimentStatusUnenrolled);
853 gWin32kExperimentStatus =
854 experimentRaw < nsIXULRuntime::eExperimentStatusCount
855 ? nsIXULRuntime::ExperimentStatus(experimentRaw)
856 : nsIXULRuntime::eExperimentStatusDisqualified;
857
858 // Watch the experiment enrollment status pref to detect experiment
859 // disqualification, and ensure it is propagated for the next restart.
860 Preferences::RegisterCallback(&OnWin32kEnrollmentStatusChanged,
861 kPrefWin32kExperimentEnrollmentStatus);
862 if (nsCOMPtr<nsIObserverService> observerService =
863 mozilla::services::GetObserverService()) {
864 nsCOMPtr<nsIObserver> shutdownObserver =
865 new Win32kEnrollmentStatusShutdownObserver();
866 observerService->AddObserver(shutdownObserver, "profile-before-change",
867 false);
868 }
869
870 // If the user no longer qualifies because they edited a required pref, check
871 // that. [B] [E]
872 auto tmpStatus = GetLiveWin32kLockdownState();
873 if (Win32kExperimentEnrolled() && Win32kRequirementsUnsatisfied(tmpStatus)) {
874 Win32kExperimentDisqualify();
875 gWin32kExperimentStatus = nsIXULRuntime::eExperimentStatusDisqualified;
876 }
877
878 // If the user has overridden an active experiment by setting a user value for
879 // "security.sandbox.content.win32k-disable", disqualify the user from the
880 // experiment. [A] [F]
881 if (Preferences::HasUserValue(kPrefWin32k) && Win32kExperimentEnrolled()) {
882 Win32kExperimentDisqualify();
883 gWin32kExperimentStatus = nsIXULRuntime::eExperimentStatusDisqualified;
884 }
885
886 // Unlike Fission, we do not configure the default branch based on experiment
887 // enrollment status. Instead we check the startupEnrollmentPref in
888 // GetContentWin32kLockdownState()
889
890 Preferences::RegisterCallback(&OnWin32kChanged, kPrefWin32k);
891
892 // Set the state
893 gWin32kStatus = GetLiveWin32kLockdownState();
894
895#else
896 gWin32kStatus =
897 nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
898 gWin32kExperimentStatus = nsIXULRuntime::eExperimentStatusUnenrolled;
899
900#endif // XP_WIN
901}
902
903nsIXULRuntime::ContentWin32kLockdownState GetWin32kLockdownState() {
904#ifdef XP_WIN
905
906 mozilla::EnsureWin32kInitialized();
907 return gWin32kStatus;
908
909#else
910
911 return nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
912
913#endif
914}
915
916} // namespace mozilla
917
918// End Win32k Infrastructure ==========================================
919
920// Fission Infrastructure =============================================
921
922// Fission enablement for the current session is determined once, at startup,
923// and then remains the same for the duration of the session.
924//
925// The following factors determine whether or not Fission is enabled for a
926// session, in order of precedence:
927//
928// - Safe mode: In safe mode, Fission is never enabled.
929//
930// - The MOZ_FORCE_ENABLE_FISSION environment variable: If set to any value,
931// Fission will be enabled.
932//
933// - The 'fission.autostart' preference, if it has been configured by the user.
934static const char kPrefFissionAutostart[] = "fission.autostart";
935
936// The computed FissionAutostart value for the session, read by content
937// processes to initialize gFissionAutostart.
938//
939// This pref is locked, and only configured on the default branch, so should
940// never be persisted in a profile.
941static const char kPrefFissionAutostartSession[] = "fission.autostart.session";
942
943//
944// The computed FissionAutostart value for the session, read by content
945// processes to initialize gFissionAutostart.
946
947static bool gFissionAutostart = false;
948static bool gFissionAutostartInitialized = false;
949static nsIXULRuntime::FissionDecisionStatus gFissionDecisionStatus;
950static void EnsureFissionAutostartInitialized() {
951 if (gFissionAutostartInitialized) {
952 return;
953 }
954 gFissionAutostartInitialized = true;
955
956 if (!XRE_IsParentProcess()) {
957 // This pref is configured for the current session by the parent process.
958 gFissionAutostart = Preferences::GetBool(kPrefFissionAutostartSession,
959 false, PrefValueKind::Default);
960 return;
961 }
962
963 if (!BrowserTabsRemoteAutostart()) {
964 gFissionAutostart = false;
965 if (gBrowserTabsRemoteStatus == kE10sForceDisabled) {
966 gFissionDecisionStatus = nsIXULRuntime::eFissionDisabledByE10sEnv;
967 } else {
968 gFissionDecisionStatus = nsIXULRuntime::eFissionDisabledByE10sOther;
969 }
970 } else if (EnvHasValue("MOZ_FORCE_ENABLE_FISSION")) {
971 gFissionAutostart = true;
972 gFissionDecisionStatus = nsIXULRuntime::eFissionEnabledByEnv;
973 } else if (EnvHasValue("MOZ_FORCE_DISABLE_FISSION")) {
974 gFissionAutostart = false;
975 gFissionDecisionStatus = nsIXULRuntime::eFissionDisabledByEnv;
976 } else {
977 // NOTE: This will take into account changes to the default due to
978 // `InitializeFissionExperimentStatus`.
979 gFissionAutostart = Preferences::GetBool(kPrefFissionAutostart, false);
980 if (Preferences::HasUserValue(kPrefFissionAutostart)) {
981 gFissionDecisionStatus = gFissionAutostart
982 ? nsIXULRuntime::eFissionEnabledByUserPref
983 : nsIXULRuntime::eFissionDisabledByUserPref;
984 } else {
985 gFissionDecisionStatus = gFissionAutostart
986 ? nsIXULRuntime::eFissionEnabledByDefault
987 : nsIXULRuntime::eFissionDisabledByDefault;
988 }
989 }
990
991 // Content processes cannot run the same logic as we're running in the parent
992 // process, as the current value of various preferences may have changed
993 // between launches. Instead, the content process will read the default branch
994 // of the locked `fission.autostart.session` preference to determine the value
995 // determined by this method.
996 Preferences::Unlock(kPrefFissionAutostartSession);
997 Preferences::ClearUser(kPrefFissionAutostartSession);
998 Preferences::SetBool(kPrefFissionAutostartSession, gFissionAutostart,
999 PrefValueKind::Default);
1000 Preferences::Lock(kPrefFissionAutostartSession);
1001}
1002
1003namespace mozilla {
1004
1005bool FissionAutostart() {
1006 EnsureFissionAutostartInitialized();
1007 return gFissionAutostart;
1008}
1009
1010} // namespace mozilla
1011
1012// End Fission Infrastructure =========================================
1013
1014namespace mozilla {
1015
1016bool SessionHistoryInParent() {
1017 return FissionAutostart() ||
1018 !StaticPrefs::
1019 fission_disableSessionHistoryInParent_AtStartup_DoNotUseDirectly();
1020}
1021
1022bool SessionStorePlatformCollection() {
1023 return SessionHistoryInParent() &&
1024 !StaticPrefs::
1025 browser_sessionstore_disable_platform_collection_AtStartup_DoNotUseDirectly();
1026}
1027
1028bool BFCacheInParent() {
1029 return SessionHistoryInParent() &&
1030 StaticPrefs::fission_bfcacheInParent_DoNotUseDirectly();
1031}
1032
1033} // namespace mozilla
1034
1035/**
1036 * The nsXULAppInfo object implements nsIFactory so that it can be its own
1037 * singleton.
1038 */
1039class nsXULAppInfo : public nsIXULAppInfo,
1040#ifdef XP_WIN
1041 public nsIWinAppHelper,
1042#endif
1043 public nsICrashReporter,
1044 public nsIFinishDumpingCallback,
1045 public nsIXULRuntime
1046
1047{
1048 public:
1049 constexpr nsXULAppInfo() = default;
1050 NS_DECL_ISUPPORTS_INHERITEDpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override;
1051 NS_DECL_NSIPLATFORMINFOvirtual nsresult GetPlatformVersion(nsACString& aPlatformVersion
) override; virtual nsresult GetPlatformBuildID(nsACString&
aPlatformBuildID) override;
1052 NS_DECL_NSIXULAPPINFOvirtual nsresult GetVendor(nsACString& aVendor) override;
virtual nsresult GetName(nsACString& aName) override; virtual
nsresult GetID(nsACString& aID) override; virtual nsresult
GetVersion(nsACString& aVersion) override; virtual nsresult
GetAppBuildID(nsACString& aAppBuildID) override; virtual
nsresult GetUAName(nsACString& aUAName) override; virtual
nsresult GetSourceURL(nsACString& aSourceURL) override; virtual
nsresult GetUpdateURL(nsACString& aUpdateURL) override;
1053 NS_DECL_NSIXULRUNTIMEvirtual nsresult GetInSafeMode(bool *aInSafeMode) override; virtual
nsresult GetWin32kExperimentStatus(nsIXULRuntime::ExperimentStatus
*aWin32kExperimentStatus) override; virtual nsresult GetWin32kLiveStatusTestingOnly
(nsIXULRuntime::ContentWin32kLockdownState *aWin32kLiveStatusTestingOnly
) override; virtual nsresult GetWin32kSessionStatus(nsIXULRuntime
::ContentWin32kLockdownState *aWin32kSessionStatus) override;
virtual nsresult GetFissionAutostart(bool *aFissionAutostart
) override; virtual nsresult GetFissionDecisionStatus(nsIXULRuntime
::FissionDecisionStatus *aFissionDecisionStatus) override; virtual
nsresult GetFissionDecisionStatusString(nsACString& aFissionDecisionStatusString
) override; virtual nsresult GetSessionHistoryInParent(bool *
aSessionHistoryInParent) override; virtual nsresult GetSessionStorePlatformCollection
(bool *aSessionStorePlatformCollection) override; virtual nsresult
GetLogConsoleErrors(bool *aLogConsoleErrors) override; virtual
nsresult SetLogConsoleErrors(bool aLogConsoleErrors) override
; virtual nsresult GetOS(nsACString& aOS) override; virtual
nsresult GetXPCOMABI(nsACString& aXPCOMABI) override; virtual
nsresult GetWidgetToolkit(nsACString& aWidgetToolkit) override
; virtual nsresult GetProcessType(uint32_t *aProcessType) override
; virtual nsresult GetProcessID(uint32_t *aProcessID) override
; virtual nsresult GetUniqueProcessID(uint64_t *aUniqueProcessID
) override; virtual nsresult GetRemoteType(nsACString& aRemoteType
) override; virtual nsresult GetBrowserTabsRemoteAutostart(bool
*aBrowserTabsRemoteAutostart) override; virtual nsresult GetMaxWebProcessCount
(uint32_t *aMaxWebProcessCount) override; virtual nsresult GetAccessibilityEnabled
(bool *aAccessibilityEnabled) override; virtual nsresult GetAccessibilityInstantiator
(nsAString& aAccessibilityInstantiator) override; virtual
nsresult GetIs64Bit(bool *aIs64Bit) override; virtual nsresult
GetIsTextRecognitionSupported(bool *aIsTextRecognitionSupported
) override; virtual nsresult InvalidateCachesOnRestart(void) override
; virtual nsresult GetReplacedLockTime(PRTime *aReplacedLockTime
) override; virtual nsresult GetDefaultUpdateChannel(nsACString
& aDefaultUpdateChannel) override; virtual nsresult GetDistributionID
(nsACString& aDistributionID) override; virtual nsresult GetWindowsDLLBlocklistStatus
(bool *aWindowsDLLBlocklistStatus) override; virtual nsresult
GetRestartedByOS(bool *aRestartedByOS) override; virtual nsresult
GetChromeColorSchemeIsDark(bool *aChromeColorSchemeIsDark) override
; virtual nsresult GetContentThemeDerivedColorSchemeIsDark(bool
*aContentThemeDerivedColorSchemeIsDark) override; virtual nsresult
GetPrefersReducedMotion(bool *aPrefersReducedMotion) override
; virtual nsresult GetDrawInTitlebar(bool *aDrawInTitlebar) override
; virtual nsresult GetDesktopEnvironment(nsACString& aDesktopEnvironment
) override; virtual nsresult GetIsWayland(bool *aIsWayland) override
; virtual nsresult GetProcessStartupShortcut(nsAString& aProcessStartupShortcut
) override; virtual nsresult GetLauncherProcessState(uint32_t
*aLauncherProcessState) override; virtual nsresult GetLastAppVersion
(nsACString& aLastAppVersion) override; virtual nsresult GetLastAppBuildID
(nsACString& aLastAppBuildID) override;
1054 NS_DECL_NSICRASHREPORTERvirtual nsresult GetCrashReporterEnabled(bool *aCrashReporterEnabled
) override; virtual nsresult SetEnabled(bool enabled) override
; virtual nsresult GetServerURL(nsIURL **aServerURL) override
; virtual nsresult SetServerURL(nsIURL *aServerURL) override;
virtual nsresult GetMinidumpPath(nsIFile **aMinidumpPath) override
; virtual nsresult SetMinidumpPath(nsIFile *aMinidumpPath) override
; virtual nsresult GetMinidumpForID(const nsAString& id, nsIFile
**_retval) override; virtual nsresult GetExtraFileForID(const
nsAString& id, nsIFile **_retval) override; virtual nsresult
AnnotateCrashReport(const nsACString& key, JS::Handle<
JS::Value> data, JSContext* cx) override; virtual nsresult
RemoveCrashReportAnnotation(const nsACString& key) override
; virtual nsresult IsAnnotationAllowedForPing(const nsACString
& value, bool *_retval) override; virtual nsresult AppendAppNotesToCrashReport
(const nsACString& data) override; virtual nsresult RegisterAppMemory
(uint64_t ptr, uint64_t size) override; virtual nsresult WriteMinidumpForException
(void * aExceptionInfo) override; virtual nsresult AppendObjCExceptionInfoToAppNotes
(void * aException) override; virtual nsresult GetSubmitReports
(bool *aSubmitReports) override; virtual nsresult SetSubmitReports
(bool aSubmitReports) override; virtual nsresult UpdateCrashEventsDir
(void) override; virtual nsresult SaveMemoryReport(void) override
;
1055 NS_DECL_NSIFINISHDUMPINGCALLBACKvirtual nsresult Callback(nsISupports *data) override;
1056#ifdef XP_WIN
1057 NS_DECL_NSIWINAPPHELPER
1058#endif
1059};
1060
1061NS_INTERFACE_MAP_BEGIN(nsXULAppInfo)nsresult nsXULAppInfo::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/toolkit/xre/nsAppRunner.cpp"
, 1061); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
1062 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULRuntime)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIXULRuntime*>(this))
; else
1063 NS_INTERFACE_MAP_ENTRY(nsIXULRuntime)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIXULRuntime>)) foundInterface =
static_cast<nsIXULRuntime*>(this); else
1064#ifdef XP_WIN
1065 NS_INTERFACE_MAP_ENTRY(nsIWinAppHelper)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIWinAppHelper>)) foundInterface
= static_cast<nsIWinAppHelper*>(this); else
1066#endif
1067 NS_INTERFACE_MAP_ENTRY(nsICrashReporter)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICrashReporter>)) foundInterface
= static_cast<nsICrashReporter*>(this); else
1068 NS_INTERFACE_MAP_ENTRY(nsIFinishDumpingCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFinishDumpingCallback>)) foundInterface
= static_cast<nsIFinishDumpingCallback*>(this); else
1069 NS_INTERFACE_MAP_ENTRY(nsIPlatformInfo)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIPlatformInfo>)) foundInterface
= static_cast<nsIPlatformInfo*>(this); else
1070 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIXULAppInfo,if ((gAppData || XRE_IsContentProcess()) && aIID.Equals
(mozilla::detail::kImplementedIID<std::remove_reference_t<
decltype(*this)>, nsIXULAppInfo>)) foundInterface = static_cast
<nsIXULAppInfo*>(this); else
1071 gAppData || XRE_IsContentProcess())if ((gAppData || XRE_IsContentProcess()) && aIID.Equals
(mozilla::detail::kImplementedIID<std::remove_reference_t<
decltype(*this)>, nsIXULAppInfo>)) foundInterface = static_cast
<nsIXULAppInfo*>(this); else
1072NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::COMTypeInfo<nsISupports
, void>::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::COMTypeInfo
<nsISupports, void>::kIID))))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1072); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 1072; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1073
1074NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
1075nsXULAppInfo::AddRef() { return 1; }
1076
1077NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
1078nsXULAppInfo::Release() { return 1; }
1079
1080NS_IMETHODIMPnsresult
1081nsXULAppInfo::GetVendor(nsACString& aResult) {
1082 if (XRE_IsContentProcess()) {
1083 ContentChild* cc = ContentChild::GetSingleton();
1084 aResult = cc->GetAppInfo().vendor;
1085 return NS_OK;
1086 }
1087 aResult.Assign(gAppData->vendor);
1088
1089 return NS_OK;
1090}
1091
1092NS_IMETHODIMPnsresult
1093nsXULAppInfo::GetName(nsACString& aResult) {
1094 if (XRE_IsContentProcess()) {
1095 ContentChild* cc = ContentChild::GetSingleton();
1096 aResult = cc->GetAppInfo().name;
1097 return NS_OK;
1098 }
1099
1100#ifdef MOZ_WIDGET_ANDROID
1101 nsCString name = java::GeckoAppShell::GetAppName()->ToCString();
1102 aResult.Assign(std::move(name));
1103#else
1104 aResult.Assign(gAppData->name);
1105#endif
1106
1107 return NS_OK;
1108}
1109
1110NS_IMETHODIMPnsresult
1111nsXULAppInfo::GetID(nsACString& aResult) {
1112 if (XRE_IsContentProcess()) {
1113 ContentChild* cc = ContentChild::GetSingleton();
1114 aResult = cc->GetAppInfo().ID;
1115 return NS_OK;
1116 }
1117 aResult.Assign(gAppData->ID);
1118
1119 return NS_OK;
1120}
1121
1122NS_IMETHODIMPnsresult
1123nsXULAppInfo::GetVersion(nsACString& aResult) {
1124 if (XRE_IsContentProcess()) {
1125 ContentChild* cc = ContentChild::GetSingleton();
1126 aResult = cc->GetAppInfo().version;
1127 return NS_OK;
1128 }
1129 aResult.Assign(gAppData->version);
1130
1131 return NS_OK;
1132}
1133
1134NS_IMETHODIMPnsresult
1135nsXULAppInfo::GetPlatformVersion(nsACString& aResult) {
1136 aResult.Assign(gToolkitVersion);
1137
1138 return NS_OK;
1139}
1140
1141NS_IMETHODIMPnsresult
1142nsXULAppInfo::GetAppBuildID(nsACString& aResult) {
1143 if (XRE_IsContentProcess()) {
1144 ContentChild* cc = ContentChild::GetSingleton();
1145 aResult = cc->GetAppInfo().buildID;
1146 return NS_OK;
1147 }
1148 aResult.Assign(gAppData->buildID);
1149
1150 return NS_OK;
1151}
1152
1153NS_IMETHODIMPnsresult
1154nsXULAppInfo::GetPlatformBuildID(nsACString& aResult) {
1155 aResult.Assign(gToolkitBuildID);
1156
1157 return NS_OK;
1158}
1159
1160NS_IMETHODIMPnsresult
1161nsXULAppInfo::GetUAName(nsACString& aResult) {
1162 if (XRE_IsContentProcess()) {
1163 ContentChild* cc = ContentChild::GetSingleton();
1164 aResult = cc->GetAppInfo().UAName;
1165 return NS_OK;
1166 }
1167 aResult.Assign(gAppData->UAName);
1168
1169 return NS_OK;
1170}
1171
1172NS_IMETHODIMPnsresult
1173nsXULAppInfo::GetSourceURL(nsACString& aResult) {
1174 if (XRE_IsContentProcess()) {
1175 ContentChild* cc = ContentChild::GetSingleton();
1176 aResult = cc->GetAppInfo().sourceURL;
1177 return NS_OK;
1178 }
1179 aResult.Assign(gAppData->sourceURL);
1180
1181 return NS_OK;
1182}
1183
1184NS_IMETHODIMPnsresult
1185nsXULAppInfo::GetUpdateURL(nsACString& aResult) {
1186 if (XRE_IsContentProcess()) {
1187 ContentChild* cc = ContentChild::GetSingleton();
1188 aResult = cc->GetAppInfo().updateURL;
1189 return NS_OK;
1190 }
1191 aResult.Assign(gAppData->updateURL);
1192
1193 return NS_OK;
1194}
1195
1196NS_IMETHODIMPnsresult
1197nsXULAppInfo::GetLogConsoleErrors(bool* aResult) {
1198 *aResult = gLogConsoleErrors;
1199 return NS_OK;
1200}
1201
1202NS_IMETHODIMPnsresult
1203nsXULAppInfo::SetLogConsoleErrors(bool aValue) {
1204 gLogConsoleErrors = aValue;
1205 return NS_OK;
1206}
1207
1208NS_IMETHODIMPnsresult
1209nsXULAppInfo::GetInSafeMode(bool* aResult) {
1210 *aResult = gSafeMode;
1211 return NS_OK;
1212}
1213
1214NS_IMETHODIMPnsresult
1215nsXULAppInfo::GetOS(nsACString& aResult) {
1216 aResult.AssignLiteral(OS_TARGET"Linux");
1217 return NS_OK;
1218}
1219
1220NS_IMETHODIMPnsresult
1221nsXULAppInfo::GetXPCOMABI(nsACString& aResult) {
1222#ifdef TARGET_XPCOM_ABI"x86_64-gcc3"
1223 aResult.AssignLiteral(TARGET_XPCOM_ABI"x86_64-gcc3");
1224 return NS_OK;
1225#else
1226 return NS_ERROR_NOT_AVAILABLE;
1227#endif
1228}
1229
1230NS_IMETHODIMPnsresult
1231nsXULAppInfo::GetWidgetToolkit(nsACString& aResult) {
1232 aResult.AssignLiteral(MOZ_WIDGET_TOOLKIT"gtk");
1233 return NS_OK;
1234}
1235
1236// Ensure that the GeckoProcessType enum, defined in xpcom/build/nsXULAppAPI.h,
1237// is synchronized with the const unsigned longs defined in
1238// xpcom/system/nsIXULRuntime.idl.
1239#define GECKO_PROCESS_TYPE(enum_value, enum_name, string_name, proc_typename, \
1240 process_bin_type, procinfo_typename, \
1241 webidl_typename, allcaps_name) \
1242 static_assert(nsIXULRuntime::PROCESS_TYPE_##allcaps_name == \
1243 static_cast<int>(GeckoProcessType_##enum_name), \
1244 "GeckoProcessType in nsXULAppAPI.h not synchronized with " \
1245 "nsIXULRuntime.idl");
1246#include "mozilla/GeckoProcessTypes.h"
1247#undef GECKO_PROCESS_TYPE
1248
1249// .. and ensure that that is all of them:
1250static_assert(GeckoProcessType_Utility + 1 == GeckoProcessType_End,
1251 "Did not find the final GeckoProcessType");
1252
1253NS_IMETHODIMPnsresult
1254nsXULAppInfo::GetProcessType(uint32_t* aResult) {
1255 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/toolkit/xre/nsAppRunner.cpp"
, 1255); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1256 *aResult = XRE_GetProcessType();
1257 return NS_OK;
1258}
1259
1260NS_IMETHODIMPnsresult
1261nsXULAppInfo::GetProcessID(uint32_t* aResult) {
1262#ifdef XP_WIN
1263 *aResult = GetCurrentProcessId();
1264#else
1265 *aResult = getpid();
1266#endif
1267 return NS_OK;
1268}
1269
1270NS_IMETHODIMPnsresult
1271nsXULAppInfo::GetUniqueProcessID(uint64_t* aResult) {
1272 if (XRE_IsContentProcess()) {
1273 ContentChild* cc = ContentChild::GetSingleton();
1274 *aResult = cc->GetID();
1275 } else {
1276 *aResult = 0;
1277 }
1278 return NS_OK;
1279}
1280
1281NS_IMETHODIMPnsresult
1282nsXULAppInfo::GetRemoteType(nsACString& aRemoteType) {
1283 if (XRE_IsContentProcess()) {
1284 aRemoteType = ContentChild::GetSingleton()->GetRemoteType();
1285 } else {
1286 aRemoteType = NOT_REMOTE_TYPEVoidCString();
1287 }
1288
1289 return NS_OK;
1290}
1291
1292MOZ_CONSTINIT[[clang::require_constant_initialization]] static nsCString gLastAppVersion;
1293MOZ_CONSTINIT[[clang::require_constant_initialization]] static nsCString gLastAppBuildID;
1294
1295NS_IMETHODIMPnsresult
1296nsXULAppInfo::GetLastAppVersion(nsACString& aResult) {
1297 if (XRE_IsContentProcess()) {
1298 return NS_ERROR_NOT_AVAILABLE;
1299 }
1300
1301 if (!gLastAppVersion.IsVoid() && gLastAppVersion.IsEmpty()) {
1302 NS_WARNING("Attempt to retrieve lastAppVersion before it has been set.")NS_DebugBreak(NS_DEBUG_WARNING, "Attempt to retrieve lastAppVersion before it has been set."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1302)
;
1303 return NS_ERROR_NOT_AVAILABLE;
1304 }
1305
1306 aResult.Assign(gLastAppVersion);
1307 return NS_OK;
1308}
1309
1310NS_IMETHODIMPnsresult
1311nsXULAppInfo::GetLastAppBuildID(nsACString& aResult) {
1312 if (XRE_IsContentProcess()) {
1313 return NS_ERROR_NOT_AVAILABLE;
1314 }
1315
1316 if (!gLastAppBuildID.IsVoid() && gLastAppBuildID.IsEmpty()) {
1317 NS_WARNING("Attempt to retrieve lastAppBuildID before it has been set.")NS_DebugBreak(NS_DEBUG_WARNING, "Attempt to retrieve lastAppBuildID before it has been set."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1317)
;
1318 return NS_ERROR_NOT_AVAILABLE;
1319 }
1320
1321 aResult.Assign(gLastAppBuildID);
1322 return NS_OK;
1323}
1324
1325NS_IMETHODIMPnsresult
1326nsXULAppInfo::GetFissionAutostart(bool* aResult) {
1327 *aResult = FissionAutostart();
1328 return NS_OK;
1329}
1330
1331NS_IMETHODIMPnsresult
1332nsXULAppInfo::GetWin32kExperimentStatus(ExperimentStatus* aResult) {
1333 if (!XRE_IsParentProcess()) {
1334 return NS_ERROR_NOT_AVAILABLE;
1335 }
1336
1337 EnsureWin32kInitialized();
1338 *aResult = gWin32kExperimentStatus;
1339 return NS_OK;
1340}
1341
1342NS_IMETHODIMPnsresult
1343nsXULAppInfo::GetWin32kLiveStatusTestingOnly(
1344 nsIXULRuntime::ContentWin32kLockdownState* aResult) {
1345 if (!XRE_IsParentProcess()) {
1346 return NS_ERROR_NOT_AVAILABLE;
1347 }
1348
1349 EnsureWin32kInitialized();
1350 *aResult = GetLiveWin32kLockdownState();
1351 return NS_OK;
1352}
1353
1354NS_IMETHODIMPnsresult
1355nsXULAppInfo::GetWin32kSessionStatus(
1356 nsIXULRuntime::ContentWin32kLockdownState* aResult) {
1357 if (!XRE_IsParentProcess()) {
1358 return NS_ERROR_NOT_AVAILABLE;
1359 }
1360
1361 EnsureWin32kInitialized();
1362 *aResult = gWin32kStatus;
1363 return NS_OK;
1364}
1365
1366NS_IMETHODIMPnsresult
1367nsXULAppInfo::GetFissionDecisionStatus(FissionDecisionStatus* aResult) {
1368 if (!XRE_IsParentProcess()) {
1369 return NS_ERROR_NOT_AVAILABLE;
1370 }
1371
1372 EnsureFissionAutostartInitialized();
1373
1374 MOZ_ASSERT(gFissionDecisionStatus != eFissionStatusUnknown)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gFissionDecisionStatus != eFissionStatusUnknown)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(gFissionDecisionStatus != eFissionStatusUnknown))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("gFissionDecisionStatus != eFissionStatusUnknown"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gFissionDecisionStatus != eFissionStatusUnknown"
")"); do { *((volatile int*)__null) = 1374; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1375 *aResult = gFissionDecisionStatus;
1376 return NS_OK;
1377}
1378
1379NS_IMETHODIMPnsresult
1380nsXULAppInfo::GetFissionDecisionStatusString(nsACString& aResult) {
1381 if (!XRE_IsParentProcess()) {
1382 return NS_ERROR_NOT_AVAILABLE;
1383 }
1384
1385 EnsureFissionAutostartInitialized();
1386 switch (gFissionDecisionStatus) {
1387 case eFissionDisabledByE10sEnv:
1388 aResult = "disabledByE10sEnv";
1389 break;
1390 case eFissionEnabledByEnv:
1391 aResult = "enabledByEnv";
1392 break;
1393 case eFissionDisabledByEnv:
1394 aResult = "disabledByEnv";
1395 break;
1396 case eFissionEnabledByDefault:
1397 aResult = "enabledByDefault";
1398 break;
1399 case eFissionDisabledByDefault:
1400 aResult = "disabledByDefault";
1401 break;
1402 case eFissionEnabledByUserPref:
1403 aResult = "enabledByUserPref";
1404 break;
1405 case eFissionDisabledByUserPref:
1406 aResult = "disabledByUserPref";
1407 break;
1408 case eFissionDisabledByE10sOther:
1409 aResult = "disabledByE10sOther";
1410 break;
1411 default:
1412 MOZ_ASSERT_UNREACHABLE("Unexpected enum value")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: "
"Unexpected enum value" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1412); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected enum value" ")"); do {
*((volatile int*)__null) = 1412; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1413 }
1414 return NS_OK;
1415}
1416
1417NS_IMETHODIMPnsresult
1418nsXULAppInfo::GetSessionHistoryInParent(bool* aResult) {
1419 *aResult = SessionHistoryInParent();
1420 return NS_OK;
1421}
1422
1423NS_IMETHODIMPnsresult
1424nsXULAppInfo::GetSessionStorePlatformCollection(bool* aResult) {
1425 *aResult = SessionStorePlatformCollection();
1426 return NS_OK;
1427}
1428
1429NS_IMETHODIMPnsresult
1430nsXULAppInfo::GetBrowserTabsRemoteAutostart(bool* aResult) {
1431 *aResult = BrowserTabsRemoteAutostart();
1432 return NS_OK;
1433}
1434
1435NS_IMETHODIMPnsresult
1436nsXULAppInfo::GetMaxWebProcessCount(uint32_t* aResult) {
1437 *aResult = mozilla::GetMaxWebProcessCount();
1438 return NS_OK;
1439}
1440
1441NS_IMETHODIMPnsresult
1442nsXULAppInfo::GetAccessibilityEnabled(bool* aResult) {
1443#ifdef ACCESSIBILITY1
1444 *aResult = GetAccService() != nullptr;
1445#else
1446 *aResult = false;
1447#endif
1448 return NS_OK;
1449}
1450
1451NS_IMETHODIMPnsresult
1452nsXULAppInfo::GetAccessibilityInstantiator(nsAString& aInstantiator) {
1453#if defined(ACCESSIBILITY1) && defined(XP_WIN)
1454 if (!GetAccService()) {
1455 aInstantiator.Truncate();
1456 return NS_OK;
1457 }
1458 nsAutoString ipClientInfo;
1459 a11y::Compatibility::GetHumanReadableConsumersStr(ipClientInfo);
1460 aInstantiator.Append(ipClientInfo);
1461 aInstantiator.AppendLiteral("|");
1462
1463 nsCOMPtr<nsIFile> oopClientExe;
1464 if (a11y::GetInstantiator(getter_AddRefs(oopClientExe))) {
1465 nsAutoString oopClientInfo;
1466 if (NS_SUCCEEDED(oopClientExe->GetPath(oopClientInfo))((bool)(__builtin_expect(!!(!NS_FAILED_impl(oopClientExe->
GetPath(oopClientInfo))), 1)))
) {
1467 aInstantiator.Append(oopClientInfo);
1468 }
1469 }
1470#else
1471 aInstantiator.Truncate();
1472#endif
1473 return NS_OK;
1474}
1475
1476NS_IMETHODIMPnsresult
1477nsXULAppInfo::GetIs64Bit(bool* aResult) {
1478#ifdef HAVE_64BIT_BUILD1
1479 *aResult = true;
1480#else
1481 *aResult = false;
1482#endif
1483 return NS_OK;
1484}
1485
1486NS_IMETHODIMPnsresult
1487nsXULAppInfo::GetIsTextRecognitionSupported(bool* aResult) {
1488 *aResult = widget::TextRecognition::IsSupported();
1489 return NS_OK;
1490}
1491
1492NS_IMETHODIMPnsresult
1493nsXULAppInfo::InvalidateCachesOnRestart() {
1494 nsCOMPtr<nsIFile> file;
1495 nsresult rv =
1496 NS_GetSpecialDirectory(NS_APP_PROFILE_DIR_STARTUP"ProfDS", getter_AddRefs(file));
1497 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1498 if (!file) return NS_ERROR_NOT_AVAILABLE;
1499
1500 file->AppendNative(FILE_COMPATIBILITY_INFO"compatibility.ini"_ns);
1501
1502 nsINIParsernsINIParser_internal parser;
1503 rv = parser.Init(file);
1504 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1505 // This fails if compatibility.ini is not there, so we'll
1506 // flush the caches on the next restart anyways.
1507 return NS_OK;
1508 }
1509
1510 nsAutoCString buf;
1511 rv = parser.GetString("Compatibility", "InvalidateCaches", buf);
1512
1513 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1514 PRFileDesc* fd;
1515 rv = file->OpenNSPRFileDesc(PR_RDWR0x04 | PR_APPEND0x10, 0600, &fd);
1516 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1517 NS_ERROR("could not create output stream")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "could not create output stream"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1517); MOZ_PretendNoReturn(); } while (0)
;
1518 return NS_ERROR_NOT_AVAILABLE;
1519 }
1520 static const char kInvalidationHeader[] =
1521 NS_LINEBREAK"\012" "InvalidateCaches=1" NS_LINEBREAK"\012";
1522 PR_Write(fd, kInvalidationHeader, sizeof(kInvalidationHeader) - 1);
1523 PR_Close(fd);
1524 }
1525 return NS_OK;
1526}
1527
1528NS_IMETHODIMPnsresult
1529nsXULAppInfo::GetReplacedLockTime(PRTime* aReplacedLockTime) {
1530 if (!gProfileLock) return NS_ERROR_NOT_AVAILABLE;
1531 gProfileLock->GetReplacedLockTime(aReplacedLockTime);
1532 return NS_OK;
1533}
1534
1535NS_IMETHODIMPnsresult
1536nsXULAppInfo::GetDefaultUpdateChannel(nsACString& aResult) {
1537 aResult.AssignLiteral(MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default");
1538 return NS_OK;
1539}
1540
1541NS_IMETHODIMPnsresult
1542nsXULAppInfo::GetDistributionID(nsACString& aResult) {
1543 aResult.AssignLiteral(MOZ_DISTRIBUTION_ID"org.mozilla");
1544 return NS_OK;
1545}
1546
1547NS_IMETHODIMPnsresult
1548nsXULAppInfo::GetWindowsDLLBlocklistStatus(bool* aResult) {
1549#if defined(HAS_DLL_BLOCKLIST)
1550 *aResult = DllBlocklist_CheckStatus();
1551#else
1552 *aResult = false;
1553#endif
1554 return NS_OK;
1555}
1556
1557NS_IMETHODIMPnsresult
1558nsXULAppInfo::GetRestartedByOS(bool* aResult) {
1559 *aResult = gRestartedByOS;
1560 return NS_OK;
1561}
1562
1563NS_IMETHODIMPnsresult
1564nsXULAppInfo::GetChromeColorSchemeIsDark(bool* aResult) {
1565 PreferenceSheet::EnsureInitialized();
1566 *aResult = PreferenceSheet::ColorSchemeForChrome() == ColorScheme::Dark;
1567 return NS_OK;
1568}
1569
1570NS_IMETHODIMPnsresult
1571nsXULAppInfo::GetContentThemeDerivedColorSchemeIsDark(bool* aResult) {
1572 *aResult =
1573 PreferenceSheet::ThemeDerivedColorSchemeForContent() == ColorScheme::Dark;
1574 return NS_OK;
1575}
1576
1577NS_IMETHODIMPnsresult
1578nsXULAppInfo::GetPrefersReducedMotion(bool* aResult) {
1579 *aResult =
1580 LookAndFeel::GetInt(LookAndFeel::IntID::PrefersReducedMotion, 0) == 1;
1581 return NS_OK;
1582}
1583
1584NS_IMETHODIMPnsresult
1585nsXULAppInfo::GetDrawInTitlebar(bool* aResult) {
1586 *aResult = LookAndFeel::DrawInTitlebar();
1587 return NS_OK;
1588}
1589
1590NS_IMETHODIMPnsresult
1591nsXULAppInfo::GetDesktopEnvironment(nsACString& aDesktopEnvironment) {
1592#ifdef MOZ_WIDGET_GTK1
1593 aDesktopEnvironment.Assign(GetDesktopEnvironmentIdentifier());
1594#endif
1595 return NS_OK;
1596}
1597
1598NS_IMETHODIMPnsresult
1599nsXULAppInfo::GetIsWayland(bool* aResult) {
1600#ifdef MOZ_WIDGET_GTK1
1601 *aResult = GdkIsWaylandDisplay();
1602#else
1603 *aResult = false;
1604#endif
1605 return NS_OK;
1606}
1607
1608NS_IMETHODIMPnsresult
1609nsXULAppInfo::GetProcessStartupShortcut(nsAString& aShortcut) {
1610#if defined(XP_WIN)
1611 if (XRE_IsParentProcess()) {
1612 aShortcut.Assign(gProcessStartupShortcut);
1613 return NS_OK;
1614 }
1615#endif
1616 return NS_ERROR_NOT_AVAILABLE;
1617}
1618
1619#if defined(XP_WIN) && defined(MOZ_LAUNCHER_PROCESS)
1620// Forward declaration
1621void SetupLauncherProcessPref();
1622
1623static Maybe<LauncherRegistryInfo::EnabledState> gLauncherProcessState;
1624#endif // defined(XP_WIN) && defined(MOZ_LAUNCHER_PROCESS)
1625
1626NS_IMETHODIMPnsresult
1627nsXULAppInfo::GetLauncherProcessState(uint32_t* aResult) {
1628#if defined(XP_WIN) && defined(MOZ_LAUNCHER_PROCESS)
1629 SetupLauncherProcessPref();
1630
1631 if (!gLauncherProcessState) {
1632 return NS_ERROR_UNEXPECTED;
1633 }
1634
1635 *aResult = static_cast<uint32_t>(gLauncherProcessState.value());
1636 return NS_OK;
1637#else
1638 return NS_ERROR_NOT_AVAILABLE;
1639#endif
1640}
1641
1642#ifdef XP_WIN
1643NS_IMETHODIMPnsresult
1644nsXULAppInfo::GetUserCanElevate(bool* aUserCanElevate) {
1645 HANDLE rawToken;
1646 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &rawToken)) {
1647 *aUserCanElevate = false;
1648 return NS_OK;
1649 }
1650
1651 nsAutoHandle token(rawToken);
1652 LauncherResult<TOKEN_ELEVATION_TYPE> elevationType = GetElevationType(token);
1653 if (elevationType.isErr()) {
1654 *aUserCanElevate = false;
1655 return NS_OK;
1656 }
1657
1658 // The possible values returned for elevationType and their meanings are:
1659 // TokenElevationTypeDefault: The token does not have a linked token
1660 // (e.g. UAC disabled or a standard user, so they can't be elevated)
1661 // TokenElevationTypeFull: The token is linked to an elevated token
1662 // (e.g. UAC is enabled and the user is already elevated so they can't
1663 // be elevated again)
1664 // TokenElevationTypeLimited: The token is linked to a limited token
1665 // (e.g. UAC is enabled and the user is not elevated, so they can be
1666 // elevated)
1667 *aUserCanElevate = (elevationType.inspect() == TokenElevationTypeLimited);
1668 return NS_OK;
1669}
1670#endif
1671
1672NS_IMETHODIMPnsresult
1673nsXULAppInfo::GetCrashReporterEnabled(bool* aEnabled) {
1674 *aEnabled = CrashReporter::GetEnabled();
1675 return NS_OK;
1676}
1677
1678NS_IMETHODIMPnsresult
1679nsXULAppInfo::SetEnabled(bool aEnabled) {
1680 if (aEnabled) {
1681 if (CrashReporter::GetEnabled()) {
1682 // no point in erroring for double-enabling
1683 return NS_OK;
1684 }
1685
1686 nsCOMPtr<nsIFile> greBinDir;
1687 NS_GetSpecialDirectory(NS_GRE_BIN_DIR"GreBinD", getter_AddRefs(greBinDir));
1688 if (!greBinDir) {
1689 return NS_ERROR_FAILURE;
1690 }
1691
1692 nsCOMPtr<nsIFile> xreBinDirectory = greBinDir;
1693 if (!xreBinDirectory) {
1694 return NS_ERROR_FAILURE;
1695 }
1696
1697 return CrashReporter::SetExceptionHandler(xreBinDirectory, true);
1698 }
1699
1700 if (!CrashReporter::GetEnabled()) {
1701 // no point in erroring for double-disabling
1702 return NS_OK;
1703 }
1704
1705 return CrashReporter::UnsetExceptionHandler();
1706}
1707
1708NS_IMETHODIMPnsresult
1709nsXULAppInfo::GetServerURL(nsIURL** aServerURL) {
1710 NS_ENSURE_ARG_POINTER(aServerURL)do { if ((__builtin_expect(!!(!(aServerURL)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aServerURL" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1710); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1711 if (!CrashReporter::GetEnabled()) return NS_ERROR_NOT_INITIALIZED;
1712
1713 nsAutoCString data;
1714 if (!CrashReporter::GetServerURL(data)) {
1715 return NS_ERROR_FAILURE;
1716 }
1717 nsCOMPtr<nsIURI> uri;
1718 NS_NewURI(getter_AddRefs(uri), data);
1719 if (!uri) return NS_ERROR_FAILURE;
1720
1721 nsCOMPtr<nsIURL> url;
1722 url = do_QueryInterface(uri);
1723 NS_ADDREF(*aServerURL = url)(*aServerURL = url)->AddRef();
1724
1725 return NS_OK;
1726}
1727
1728NS_IMETHODIMPnsresult
1729nsXULAppInfo::SetServerURL(nsIURL* aServerURL) {
1730 // Only allow https or http URLs
1731 if (!aServerURL->SchemeIs("http") && !aServerURL->SchemeIs("https")) {
1732 return NS_ERROR_INVALID_ARG;
1733 }
1734
1735 nsAutoCString spec;
1736 nsresult rv = aServerURL->GetSpec(spec);
1737 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/toolkit/xre/nsAppRunner.cpp"
, 1737); return rv; } } while (false)
;
1738
1739 return CrashReporter::SetServerURL(spec);
1740}
1741
1742NS_IMETHODIMPnsresult
1743nsXULAppInfo::GetMinidumpPath(nsIFile** aMinidumpPath) {
1744 if (!CrashReporter::GetEnabled()) {
1745 return NS_ERROR_NOT_INITIALIZED;
1746 }
1747
1748 nsAutoString path;
1749 if (!CrashReporter::GetMinidumpPath(path)) {
1750 return NS_ERROR_FAILURE;
1751 }
1752
1753 return NS_NewLocalFile(path, aMinidumpPath);
1754}
1755
1756NS_IMETHODIMPnsresult
1757nsXULAppInfo::SetMinidumpPath(nsIFile* aMinidumpPath) {
1758 nsAutoString path;
1759 nsresult rv = aMinidumpPath->GetPath(path);
1760 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/toolkit/xre/nsAppRunner.cpp"
, 1760); return rv; } } while (false)
;
1761 return CrashReporter::SetMinidumpPath(path);
1762}
1763
1764NS_IMETHODIMPnsresult
1765nsXULAppInfo::GetMinidumpForID(const nsAString& aId, nsIFile** aMinidump) {
1766 if (!CrashReporter::GetMinidumpForID(aId, aMinidump)) {
1767 return NS_ERROR_FILE_NOT_FOUND;
1768 }
1769
1770 return NS_OK;
1771}
1772
1773NS_IMETHODIMPnsresult
1774nsXULAppInfo::GetExtraFileForID(const nsAString& aId, nsIFile** aExtraFile) {
1775 if (!CrashReporter::GetExtraFileForID(aId, aExtraFile)) {
1776 return NS_ERROR_FILE_NOT_FOUND;
1777 }
1778
1779 return NS_OK;
1780}
1781
1782NS_IMETHODIMPnsresult
1783nsXULAppInfo::AnnotateCrashReport(const nsACString& key,
1784 JS::Handle<JS::Value> data, JSContext* cx) {
1785 auto annotation = CrashReporter::AnnotationFromString(key);
1786 NS_ENSURE_TRUE(annotation.isSome(), NS_ERROR_INVALID_ARG)do { if ((__builtin_expect(!!(!(annotation.isSome())), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "annotation.isSome()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1786); return NS_ERROR_INVALID_ARG; } } while (false)
;
1787 switch (data.type()) {
1788 case JS::ValueType::Int32:
1789 CrashReporter::RecordAnnotationU32(*annotation, data.toInt32());
1790 break;
1791 case JS::ValueType::Boolean:
1792 CrashReporter::RecordAnnotationBool(*annotation, data.toBoolean());
1793 break;
1794 case JS::ValueType::String: {
1795 JSString* value = data.toString();
1796 size_t length = (JS_GetStringLength(value) * 3) + 1;
1797 nsCString buffer;
1798 auto res = JS_EncodeStringToUTF8BufferPartial(
1799 cx, value, buffer.GetMutableData(length));
1800
1801 if (!res) {
1802 return NS_ERROR_OUT_OF_MEMORY;
1803 }
1804
1805 size_t written;
1806 std::tie(std::ignore, written) = *res;
1807
1808 buffer.SetLength(written);
1809
1810 CrashReporter::RecordAnnotationNSCString(*annotation, buffer);
1811 } break;
1812 default:
1813 return NS_ERROR_INVALID_ARG;
1814 }
1815 return NS_OK;
1816}
1817
1818NS_IMETHODIMPnsresult
1819nsXULAppInfo::RemoveCrashReportAnnotation(const nsACString& key) {
1820 auto annotation = CrashReporter::AnnotationFromString(key);
1821 NS_ENSURE_TRUE(annotation.isSome(), NS_ERROR_INVALID_ARG)do { if ((__builtin_expect(!!(!(annotation.isSome())), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "annotation.isSome()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1821); return NS_ERROR_INVALID_ARG; } } while (false)
;
1822 CrashReporter::UnrecordAnnotation(*annotation);
1823 return NS_OK;
1824}
1825
1826NS_IMETHODIMPnsresult
1827nsXULAppInfo::IsAnnotationAllowedForPing(const nsACString& aValue,
1828 bool* aIsAllowed) {
1829 auto annotation = CrashReporter::AnnotationFromString(aValue);
1830 NS_ENSURE_TRUE(annotation.isSome(), NS_ERROR_INVALID_ARG)do { if ((__builtin_expect(!!(!(annotation.isSome())), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "annotation.isSome()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1830); return NS_ERROR_INVALID_ARG; } } while (false)
;
1831 *aIsAllowed = CrashReporter::IsAnnotationAllowedForPing(*annotation);
1832
1833 return NS_OK;
1834}
1835
1836NS_IMETHODIMPnsresult
1837nsXULAppInfo::AppendAppNotesToCrashReport(const nsACString& data) {
1838 return CrashReporter::AppendAppNotesToCrashReport(data);
1839}
1840
1841NS_IMETHODIMPnsresult
1842nsXULAppInfo::RegisterAppMemory(uint64_t pointer, uint64_t len) {
1843 return CrashReporter::RegisterAppMemory((void*)pointer, len);
1844}
1845
1846NS_IMETHODIMPnsresult
1847nsXULAppInfo::WriteMinidumpForException(void* aExceptionInfo) {
1848#ifdef XP_WIN
1849 return CrashReporter::WriteMinidumpForException(
1850 static_cast<EXCEPTION_POINTERS*>(aExceptionInfo));
1851#else
1852 return NS_ERROR_NOT_IMPLEMENTED;
1853#endif
1854}
1855
1856NS_IMETHODIMPnsresult
1857nsXULAppInfo::AppendObjCExceptionInfoToAppNotes(void* aException) {
1858#ifdef XP_MACOSX
1859 return CrashReporter::AppendObjCExceptionInfoToAppNotes(aException);
1860#else
1861 return NS_ERROR_NOT_IMPLEMENTED;
1862#endif
1863}
1864
1865NS_IMETHODIMPnsresult
1866nsXULAppInfo::GetSubmitReports(bool* aEnabled) {
1867 return CrashReporter::GetSubmitReports(aEnabled);
1868}
1869
1870NS_IMETHODIMPnsresult
1871nsXULAppInfo::SetSubmitReports(bool aEnabled) {
1872 return CrashReporter::SetSubmitReports(aEnabled);
1873}
1874
1875NS_IMETHODIMPnsresult
1876nsXULAppInfo::UpdateCrashEventsDir() {
1877 CrashReporter::UpdateCrashEventsDir();
1878 return NS_OK;
1879}
1880
1881NS_IMETHODIMPnsresult
1882nsXULAppInfo::SaveMemoryReport() {
1883 if (!CrashReporter::GetEnabled()) {
1884 return NS_ERROR_NOT_INITIALIZED;
1885 }
1886 nsCOMPtr<nsIFile> file;
1887 nsresult rv = CrashReporter::GetDefaultMemoryReportFile(getter_AddRefs(file));
1888 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/toolkit/xre/nsAppRunner.cpp"
, 1888)
) {
1889 return rv;
1890 }
1891
1892 nsString path;
1893 file->GetPath(path);
1894
1895 nsCOMPtr<nsIMemoryInfoDumper> dumper =
1896 do_GetService("@mozilla.org/memory-info-dumper;1");
1897 if (NS_WARN_IF(!dumper)NS_warn_if_impl(!dumper, "!dumper", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1897)
) {
1898 return NS_ERROR_UNEXPECTED;
1899 }
1900
1901 rv = dumper->DumpMemoryReportsToNamedFile(
1902 path, this, file, true /* anonymize */, false /* minimizeMemoryUsage */);
1903 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/toolkit/xre/nsAppRunner.cpp"
, 1903)
) {
1904 return rv;
1905 }
1906 return NS_OK;
1907}
1908
1909// This method is from nsIFInishDumpingCallback.
1910NS_IMETHODIMPnsresult
1911nsXULAppInfo::Callback(nsISupports* aData) {
1912 nsCOMPtr<nsIFile> file = do_QueryInterface(aData);
1913 MOZ_ASSERT(file)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(file)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(file))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("file", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1913); AnnotateMozCrashReason("MOZ_ASSERT" "(" "file" ")");
do { *((volatile int*)__null) = 1913; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1914
1915 CrashReporter::SetMemoryReportFile(file);
1916 return NS_OK;
1917}
1918
1919static const nsXULAppInfo kAppInfo;
1920namespace mozilla {
1921nsresult AppInfoConstructor(REFNSIIDconst nsIID& aIID, void** aResult) {
1922 return const_cast<nsXULAppInfo*>(&kAppInfo)->QueryInterface(aIID, aResult);
1923}
1924} // namespace mozilla
1925
1926bool gLogConsoleErrors = false;
1927
1928#define NS_ENSURE_TRUE_LOG(x, ret)do { if ((__builtin_expect(!!(!(x)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "x" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1928); gLogConsoleErrors = true; return ret; } } while (0)
\
1929 PR_BEGIN_MACROdo { \
1930 if (MOZ_UNLIKELY(!(x))(__builtin_expect(!!(!(x)), 0))) { \
1931 NS_WARNING("NS_ENSURE_TRUE(" #x ") failed")NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" #x ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1931)
; \
1932 gLogConsoleErrors = true; \
1933 return ret; \
1934 } \
1935 PR_END_MACRO} while (0)
1936
1937#define NS_ENSURE_SUCCESS_LOG(res, ret)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(res)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(res)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1937); gLogConsoleErrors = true; return ret; } } while (0)
\
1938 NS_ENSURE_TRUE_LOG(NS_SUCCEEDED(res), ret)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(res)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(res)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1938); gLogConsoleErrors = true; return ret; } } while (0)
1939
1940/**
1941 * Because we're starting/stopping XPCOM several times in different scenarios,
1942 * this class is a stack-based critter that makes sure that XPCOM is shut down
1943 * during early returns.
1944 */
1945
1946class ScopedXPCOMStartup {
1947 public:
1948 ScopedXPCOMStartup() : mServiceManager(nullptr) {}
1949 ~ScopedXPCOMStartup();
1950
1951 nsresult Initialize(bool aInitJSContext = true);
1952 nsresult SetWindowCreator(nsINativeAppSupport* native);
1953
1954 private:
1955 nsIServiceManager* mServiceManager;
1956 static nsINativeAppSupport* gNativeAppSupport;
1957
1958 friend already_AddRefed<nsINativeAppSupport> NS_GetNativeAppSupport();
1959};
1960
1961ScopedXPCOMStartup::~ScopedXPCOMStartup() {
1962 NS_IF_RELEASE(gNativeAppSupport)do { if (gNativeAppSupport) { (gNativeAppSupport)->Release
(); (gNativeAppSupport) = 0; } } while (0)
;
1963
1964 if (mServiceManager) {
1965#ifdef XP_MACOSX
1966 // On OS X, we need a pool to catch cocoa objects that are autoreleased
1967 // during teardown.
1968 mozilla::MacAutoreleasePool pool;
1969#endif
1970
1971 nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service());
1972 if (appStartup) appStartup->DestroyHiddenWindow();
1973
1974 gDirServiceProvider->DoShutdown();
1975 PROFILER_MARKER_UNTYPED("Shutdown early", OTHER)do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("Shutdown early", ::geckoprofiler::category::OTHER); } } while
(false); } while (false)
;
1976
1977 WriteConsoleLog();
1978
1979 NS_ShutdownXPCOM(mServiceManager);
1980 mServiceManager = nullptr;
1981 }
1982}
1983
1984nsresult ScopedXPCOMStartup::Initialize(bool aInitJSContext) {
1985 NS_ASSERTION(gDirServiceProvider, "Should not get here!")do { if (!(gDirServiceProvider)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "Should not get here!", "gDirServiceProvider", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1985); MOZ_PretendNoReturn(); } } while (0)
;
1986
1987 nsresult rv;
1988
1989 rv = NS_InitXPCOM(&mServiceManager, gDirServiceProvider->GetAppDir(),
1990 gDirServiceProvider, aInitJSContext);
1991 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1992 NS_ERROR("Couldn't start xpcom!")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Couldn't start xpcom!"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1992); MOZ_PretendNoReturn(); } while (0)
;
1993 mServiceManager = nullptr;
1994 } else {
1995#ifdef DEBUG1
1996 nsCOMPtr<nsIComponentRegistrar> reg = do_QueryInterface(mServiceManager);
1997 NS_ASSERTION(reg, "Service Manager doesn't QI to Registrar.")do { if (!(reg)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Service Manager doesn't QI to Registrar."
, "reg", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1997); MOZ_PretendNoReturn(); } } while (0)
;
1998#endif
1999 }
2000
2001 return rv;
2002}
2003
2004/**
2005 * This is a little factory class that serves as a singleton-service-factory
2006 * for the nativeappsupport object.
2007 */
2008class nsSingletonFactory final : public nsIFactory {
2009 public:
2010 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:
2011 NS_DECL_NSIFACTORYvirtual nsresult CreateInstance(const nsIID & iid, void *
* result) override;
2012
2013 explicit nsSingletonFactory(nsISupports* aSingleton);
2014
2015 private:
2016 ~nsSingletonFactory() = default;
2017 nsCOMPtr<nsISupports> mSingleton;
2018};
2019
2020nsSingletonFactory::nsSingletonFactory(nsISupports* aSingleton)
2021 : mSingleton(aSingleton) {
2022 NS_ASSERTION(mSingleton, "Singleton was null!")do { if (!(mSingleton)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Singleton was null!"
, "mSingleton", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2022); MOZ_PretendNoReturn(); } } while (0)
;
2023}
2024
2025NS_IMPL_ISUPPORTS(nsSingletonFactory, nsIFactory)MozExternalRefCountType nsSingletonFactory::AddRef(void) { static_assert
(!std::is_destructible_v<nsSingletonFactory>, "Reference-counted class "
"nsSingletonFactory" " 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/toolkit/xre/nsAppRunner.cpp"
, 2025); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
2025; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsSingletonFactory" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsSingletonFactory" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"nsSingletonFactory\" != nullptr" " (" "Must specify a name"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2025); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsSingletonFactory\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2025; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsSingletonFactory" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("nsSingletonFactory"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
nsSingletonFactory::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/toolkit/xre/nsAppRunner.cpp"
, 2025); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 2025
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsSingletonFactory" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsSingletonFactory" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"nsSingletonFactory\" != nullptr" " (" "Must specify a name"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2025); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsSingletonFactory\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2025; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsSingletonFactory" " not thread-safe"); const
char* const nametmp = "nsSingletonFactory"; nsrefcnt count =
--mRefCnt; NS_LogRelease((this), (count), (nametmp)); if (count
== 0) { mRefCnt = 1; delete (this); return 0; } return count
; } nsresult nsSingletonFactory::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/toolkit/xre/nsAppRunner.cpp"
, 2025); 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<nsSingletonFactory, nsIFactory>, int32_t
( reinterpret_cast<char*>(static_cast<nsIFactory*>
((nsSingletonFactory*)0x1000)) - reinterpret_cast<char*>
((nsSingletonFactory*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsSingletonFactory, nsISupports>, int32_t(reinterpret_cast
<char*>(static_cast<nsISupports*>( static_cast<
nsIFactory*>((nsSingletonFactory*)0x1000))) - reinterpret_cast
<char*>((nsSingletonFactory*)0x1000))}, { nullptr, 0 } }
; static_assert(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
2026
2027NS_IMETHODIMPnsresult
2028nsSingletonFactory::CreateInstance(const nsIID& aIID, void** aResult) {
2029 return mSingleton->QueryInterface(aIID, aResult);
2030}
2031
2032/**
2033 * Set our windowcreator on the WindowWatcher service.
2034 */
2035nsresult ScopedXPCOMStartup::SetWindowCreator(nsINativeAppSupport* native) {
2036 nsresult rv;
2037
2038 NS_IF_ADDREF(gNativeAppSupport = native)ns_if_addref(gNativeAppSupport = native);
2039
2040 nsCOMPtr<nsIWindowCreator> creator(components::AppStartup::Service());
2041 if (!creator) return NS_ERROR_UNEXPECTED;
2042
2043 nsCOMPtr<nsIWindowWatcher> wwatch(
2044 do_GetService(NS_WINDOWWATCHER_CONTRACTID"@mozilla.org/embedcomp/window-watcher;1", &rv));
2045 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/toolkit/xre/nsAppRunner.cpp"
, 2045); return rv; } } while (false)
;
2046
2047 return wwatch->SetWindowCreator(creator);
2048}
2049
2050/* static */ already_AddRefed<nsINativeAppSupport> NS_GetNativeAppSupport() {
2051 if (!ScopedXPCOMStartup::gNativeAppSupport) {
2052 return nullptr;
2053 }
2054
2055 return do_AddRef(ScopedXPCOMStartup::gNativeAppSupport);
2056}
2057
2058#ifdef MOZ_HAS_REMOTE1
2059/* static */ already_AddRefed<nsIRemoteService> GetRemoteService() {
2060 AssertIsOnMainThread();
2061
2062 if (!gRemoteService) {
2063 gRemoteService = new nsRemoteService();
2064 }
2065 nsCOMPtr<nsIRemoteService> remoteService = gRemoteService.get();
2066 return remoteService.forget();
2067}
2068#endif
2069
2070nsINativeAppSupport* ScopedXPCOMStartup::gNativeAppSupport;
2071
2072static void DumpArbitraryHelp() {
2073 nsresult rv;
2074
2075 ScopedLogging log;
2076
2077 {
2078 ScopedXPCOMStartup xpcom;
2079 xpcom.Initialize();
2080
2081 nsCOMPtr<nsICommandLineRunner> cmdline(new nsCommandLine());
2082
2083 nsCString text;
2084 rv = cmdline->GetHelpText(text);
2085 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) printf("%s", text.get());
2086 }
2087}
2088
2089// English text needs to go into a dtd file.
2090// But when this is called we have no components etc. These strings must either
2091// be here, or in a native resource file.
2092static void DumpHelp() {
2093 printf(
2094 "Usage: %s [ options ... ] [URL]\n"
2095 " where options include:\n\n",
2096 gArgv[0]);
2097
2098#ifdef MOZ_X111
2099 printf(
2100 "X11 options\n"
2101 " --display=DISPLAY X display to use\n"
2102 " --sync Make X calls synchronous\n");
2103#endif
2104#ifdef XP_UNIX1
2105 printf(
2106 " --g-fatal-warnings Make all warnings fatal\n"
2107 "\n%s options\n",
2108 (const char*)gAppData->name);
2109#endif
2110
2111 printf(
2112 " -h or --help Print this message.\n"
2113 " -v or --version Print %s version.\n"
2114 " --full-version Print %s version, build and platform build ids.\n"
2115 " -P <profile> Start with <profile>.\n"
2116 " --profile <path> Start with profile at <path>.\n"
2117 " --migration Start with migration wizard.\n"
2118 " --ProfileManager Start with ProfileManager.\n"
2119 " --origin-to-force-quic-on <origin>\n"
2120 " Force to use QUIC for the specified origin.\n"
2121#ifdef MOZ_HAS_REMOTE1
2122 " --new-instance Open new instance, not a new window in running "
2123 "instance.\n"
2124#endif
2125 " --safe-mode Disables extensions and themes for this session.\n"
2126#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE1
2127 " --allow-downgrade Allows downgrading a profile.\n"
2128#endif
2129 " --MOZ_LOG=<modules> Treated as MOZ_LOG=<modules> environment "
2130 "variable,\n"
2131 " overrides it.\n"
2132 " --MOZ_LOG_FILE=<file> Treated as MOZ_LOG_FILE=<file> environment "
2133 "variable,\n"
2134 " overrides it. If MOZ_LOG_FILE is not specified as "
2135 "an\n"
2136 " argument or as an environment variable, logging "
2137 "will be\n"
2138 " written to stdout.\n",
2139 (const char*)gAppData->name, (const char*)gAppData->name);
2140
2141#if defined(XP_WIN)
2142 printf(" --console Start %s with a debugging console.\n",
2143 (const char*)gAppData->name);
2144#endif
2145
2146#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK1) || defined(XP_MACOSX)
2147 printf(" --headless Run without a GUI.\n");
2148#endif
2149
2150#if defined(MOZ_ENABLE_DBUS1)
2151 printf(
2152 " --dbus-service <launcher> Run as DBus service for "
2153 "org.freedesktop.Application and\n"
2154 " set a launcher (usually /usr/bin/appname "
2155 "script) for it.");
2156#endif
2157
2158 // this works, but only after the components have registered. so if you drop
2159 // in a new command line handler, --help won't not until the second run. out
2160 // of the bug, because we ship a component.reg file, it works correctly.
2161 DumpArbitraryHelp();
2162}
2163
2164static inline void DumpVersion() {
2165 if (gAppData->vendor && *gAppData->vendor) {
2166 printf("%s ", (const char*)gAppData->vendor);
2167 }
2168 printf("%s ", (const char*)gAppData->name);
2169
2170 // Use the displayed version
2171 // For example, for beta, we would display 42.0b2 instead of 42.0
2172 printf("%s", MOZ_STRINGIFY(MOZ_APP_VERSION_DISPLAY)"136.0a1");
2173
2174 if (gAppData->copyright && *gAppData->copyright) {
2175 printf(", %s", (const char*)gAppData->copyright);
2176 }
2177 printf("\n");
2178}
2179
2180static inline void DumpFullVersion() {
2181 if (gAppData->vendor && *gAppData->vendor) {
2182 printf("%s ", (const char*)gAppData->vendor);
2183 }
2184 printf("%s ", (const char*)gAppData->name);
2185
2186 // Use the displayed version
2187 // For example, for beta, we would display 42.0b2 instead of 42.0
2188 printf("%s ", MOZ_STRINGIFY(MOZ_APP_VERSION_DISPLAY)"136.0a1");
2189
2190 printf("%s ", (const char*)gAppData->buildID);
2191 printf("%s ", (const char*)PlatformBuildID());
2192 if (gAppData->copyright && *gAppData->copyright) {
2193 printf(", %s", (const char*)gAppData->copyright);
2194 }
2195 printf("\n");
2196}
2197
2198void XRE_InitOmnijar(nsIFile* greOmni, nsIFile* appOmni) {
2199 mozilla::Omnijar::Init(greOmni, appOmni);
2200}
2201
2202nsresult XRE_GetBinaryPath(nsIFile** aResult) {
2203 return mozilla::BinaryPath::GetFile(aResult);
2204}
2205
2206#ifdef XP_WIN
2207# include "nsWindowsRestart.cpp"
2208# include <shellapi.h>
2209
2210typedef BOOL(WINAPI* SetProcessDEPPolicyFunc)(DWORD dwFlags);
2211
2212static void RegisterApplicationRestartChanged(const char* aPref, void* aData) {
2213 DWORD cchCmdLine = 0;
2214 HRESULT rc = ::GetApplicationRestartSettings(::GetCurrentProcess(), nullptr,
2215 &cchCmdLine, nullptr);
2216 bool wasRegistered = false;
2217 if (rc == S_OK) {
2218 wasRegistered = true;
2219 }
2220
2221 if (Preferences::GetBool(PREF_WIN_REGISTER_APPLICATION_RESTART, false) &&
2222 !wasRegistered) {
2223 // Make the command line to use when restarting.
2224 // Excludes argv[0] because RegisterApplicationRestart adds the
2225 // executable name, replace that temporarily with -os-restarted
2226 char* exeName = gRestartArgv[0];
2227 gRestartArgv[0] = const_cast<char*>("-os-restarted");
2228 wchar_t** restartArgvConverted =
2229 AllocConvertUTF8toUTF16Strings(gRestartArgc, gRestartArgv);
2230 gRestartArgv[0] = exeName;
2231
2232 mozilla::UniquePtr<wchar_t[]> restartCommandLine;
2233 if (restartArgvConverted) {
2234 restartCommandLine =
2235 mozilla::MakeCommandLine(gRestartArgc, restartArgvConverted);
2236 FreeAllocStrings(gRestartArgc, restartArgvConverted);
2237 }
2238
2239 if (restartCommandLine) {
2240 // Flags RESTART_NO_PATCH and RESTART_NO_REBOOT are not set, so we
2241 // should be restarted if terminated by an update or restart.
2242 ::RegisterApplicationRestart(restartCommandLine.get(),
2243 RESTART_NO_CRASH | RESTART_NO_HANG);
2244 }
2245 } else if (wasRegistered) {
2246 ::UnregisterApplicationRestart();
2247 }
2248}
2249
2250static void OnAlteredPrefetchPrefChanged(const char* aPref, void* aData) {
2251 int32_t prefVal = Preferences::GetInt(PREF_WIN_ALTERED_DLL_PREFETCH, 0);
2252
2253 mozilla::DllPrefetchExperimentRegistryInfo prefetchRegInfo;
2254 mozilla::DebugOnly<mozilla::Result<Ok, nsresult>> reflectResult =
2255 prefetchRegInfo.ReflectPrefToRegistry(prefVal);
2256
2257 MOZ_ASSERT(reflectResult.value.isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.value.isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.value.isOk()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("reflectResult.value.isOk()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2257); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.value.isOk()"
")"); do { *((volatile int*)__null) = 2257; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2258}
2259
2260static void SetupAlteredPrefetchPref() {
2261 mozilla::DllPrefetchExperimentRegistryInfo prefetchRegInfo;
2262
2263 mozilla::DebugOnly<mozilla::Result<Ok, nsresult>> reflectResult =
2264 prefetchRegInfo.ReflectPrefToRegistry(
2265 Preferences::GetInt(PREF_WIN_ALTERED_DLL_PREFETCH, 0));
2266 MOZ_ASSERT(reflectResult.value.isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.value.isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.value.isOk()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("reflectResult.value.isOk()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2266); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.value.isOk()"
")"); do { *((volatile int*)__null) = 2266; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2267
2268 Preferences::RegisterCallback(&OnAlteredPrefetchPrefChanged,
2269 PREF_WIN_ALTERED_DLL_PREFETCH);
2270}
2271
2272static void ReflectSkeletonUIPrefToRegistry(const char* aPref, void* aData) {
2273 Unused << aPref;
2274 Unused << aData;
2275
2276 bool shouldBeEnabled =
2277 Preferences::GetBool(kPrefPreXulSkeletonUI, false) &&
2278 Preferences::GetBool(kPrefBrowserStartupBlankWindow, false) &&
2279 LookAndFeel::DrawInTitlebar();
2280 if (shouldBeEnabled && Preferences::HasUserValue(kPrefThemeId)) {
2281 nsCString themeId;
2282 Preferences::GetCString(kPrefThemeId, themeId);
2283 if (themeId.EqualsLiteral("default-theme@mozilla.org")) {
2284 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Default);
2285 } else if (themeId.EqualsLiteral("firefox-compact-dark@mozilla.org")) {
2286 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Dark);
2287 } else if (themeId.EqualsLiteral("firefox-compact-light@mozilla.org")) {
2288 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Light);
2289 } else {
2290 shouldBeEnabled = false;
2291 }
2292 } else if (shouldBeEnabled) {
2293 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Default);
2294 }
2295
2296 if (GetPreXULSkeletonUIEnabled() != shouldBeEnabled) {
2297 Unused << SetPreXULSkeletonUIEnabledIfAllowed(shouldBeEnabled);
2298 }
2299}
2300
2301static void SetupSkeletonUIPrefs() {
2302 ReflectSkeletonUIPrefToRegistry(nullptr, nullptr);
2303 Preferences::RegisterCallback(&ReflectSkeletonUIPrefToRegistry,
2304 kPrefPreXulSkeletonUI);
2305 Preferences::RegisterCallback(&ReflectSkeletonUIPrefToRegistry,
2306 kPrefBrowserStartupBlankWindow);
2307 Preferences::RegisterCallback(&ReflectSkeletonUIPrefToRegistry, kPrefThemeId);
2308 Preferences::RegisterCallback(
2309 &ReflectSkeletonUIPrefToRegistry,
2310 nsDependentCString(StaticPrefs::GetPrefName_browser_tabs_inTitlebar()));
2311}
2312
2313# if defined(MOZ_LAUNCHER_PROCESS)
2314
2315static void OnLauncherPrefChanged(const char* aPref, void* aData) {
2316 bool prefVal = Preferences::GetBool(PREF_WIN_LAUNCHER_PROCESS_ENABLED, true);
2317
2318 mozilla::LauncherRegistryInfo launcherRegInfo;
2319 mozilla::DebugOnly<mozilla::LauncherVoidResult> reflectResult =
2320 launcherRegInfo.ReflectPrefToRegistry(prefVal);
2321 MOZ_ASSERT(reflectResult.inspect().isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.inspect().isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.inspect().isOk
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("reflectResult.inspect().isOk()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2321); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.inspect().isOk()"
")"); do { *((volatile int*)__null) = 2321; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2322}
2323
2324static void OnLauncherTelemetryPrefChanged(const char* aPref, void* aData) {
2325 bool prefVal = Preferences::GetBool(kPrefHealthReportUploadEnabled, true);
2326
2327 mozilla::LauncherRegistryInfo launcherRegInfo;
2328 mozilla::DebugOnly<mozilla::LauncherVoidResult> reflectResult =
2329 launcherRegInfo.ReflectTelemetryPrefToRegistry(prefVal);
2330 MOZ_ASSERT(reflectResult.inspect().isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.inspect().isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.inspect().isOk
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("reflectResult.inspect().isOk()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2330); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.inspect().isOk()"
")"); do { *((volatile int*)__null) = 2330; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2331}
2332
2333static void SetupLauncherProcessPref() {
2334 if (gLauncherProcessState) {
2335 // We've already successfully run
2336 return;
2337 }
2338
2339 mozilla::LauncherRegistryInfo launcherRegInfo;
2340
2341 mozilla::LauncherResult<mozilla::LauncherRegistryInfo::EnabledState>
2342 enabledState = launcherRegInfo.IsEnabled();
2343
2344 if (enabledState.isOk()) {
2345 gLauncherProcessState = Some(enabledState.unwrap());
2346
2347 CrashReporter::RecordAnnotationU32(
2348 CrashReporter::Annotation::LauncherProcessState,
2349 static_cast<uint32_t>(enabledState.unwrap()));
2350
2351 // Reflect the launcher process registry state into user prefs
2352 Preferences::SetBool(
2353 PREF_WIN_LAUNCHER_PROCESS_ENABLED,
2354 enabledState.unwrap() !=
2355 mozilla::LauncherRegistryInfo::EnabledState::ForceDisabled);
2356 }
2357
2358 mozilla::DebugOnly<mozilla::LauncherVoidResult> reflectResult =
2359 launcherRegInfo.ReflectTelemetryPrefToRegistry(
2360 Preferences::GetBool(kPrefHealthReportUploadEnabled, true));
2361 MOZ_ASSERT(reflectResult.inspect().isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.inspect().isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.inspect().isOk
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("reflectResult.inspect().isOk()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.inspect().isOk()"
")"); do { *((volatile int*)__null) = 2361; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2362
2363 Preferences::RegisterCallback(&OnLauncherPrefChanged,
2364 PREF_WIN_LAUNCHER_PROCESS_ENABLED);
2365 Preferences::RegisterCallback(&OnLauncherTelemetryPrefChanged,
2366 kPrefHealthReportUploadEnabled);
2367}
2368
2369# endif // defined(MOZ_LAUNCHER_PROCESS)
2370
2371# if defined(MOZ_DEFAULT_BROWSER_AGENT)
2372
2373# define DEFAULT_BROWSER_AGENT_KEY_NAME \
2374 "SOFTWARE\\" MOZ_APP_VENDOR"Mozilla" "\\" MOZ_APP_NAME"firefox" "\\Default Browser Agent"
2375
2376static nsresult PrependRegistryValueName(nsAutoString& aValueName) {
2377 nsresult rv;
2378
2379 nsCOMPtr<nsIFile> binaryPath;
2380 rv = XRE_GetBinaryPath(getter_AddRefs(binaryPath));
2381 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/toolkit/xre/nsAppRunner.cpp"
, 2381); return rv; } } while (false)
;
2382
2383 nsCOMPtr<nsIFile> binaryDir;
2384 rv = binaryPath->GetParent(getter_AddRefs(binaryDir));
2385 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/toolkit/xre/nsAppRunner.cpp"
, 2385); return rv; } } while (false)
;
2386
2387 nsAutoString prefix;
2388 rv = binaryDir->GetPath(prefix);
2389 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/toolkit/xre/nsAppRunner.cpp"
, 2389); return rv; } } while (false)
;
2390
2391 prefix.AppendLiteral("|");
2392 aValueName.Insert(prefix, 0);
2393
2394 return NS_OK;
2395}
2396
2397static void OnDefaultAgentTelemetryPrefChanged(const char* aPref, void* aData) {
2398 nsresult rv;
2399 nsAutoString valueName;
2400 if (strcmp(aPref, kPrefHealthReportUploadEnabled) == 0) {
2401 valueName.AssignLiteral("DisableTelemetry");
2402 } else if (strcmp(aPref, kPrefDefaultAgentEnabled) == 0) {
2403 valueName.AssignLiteral("DisableDefaultBrowserAgent");
2404 } else {
2405 return;
2406 }
2407 rv = PrependRegistryValueName(valueName);
2408 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/toolkit/xre/nsAppRunner.cpp"
, 2408); return; } } while (false)
;
2409
2410 nsCOMPtr<nsIWindowsRegKey> regKey =
2411 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2412 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/toolkit/xre/nsAppRunner.cpp"
, 2412); return; } } while (false)
;
2413
2414 nsAutoString keyName;
2415 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2416 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2417 nsIWindowsRegKey::ACCESS_WRITE);
2418
2419 bool prefVal = Preferences::GetBool(aPref, true);
2420
2421 // We're recording whether the pref is *disabled*, so invert the value.
2422 rv = regKey->WriteIntValue(valueName, prefVal ? 0 : 1);
2423 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/toolkit/xre/nsAppRunner.cpp"
, 2423); return; } } while (false)
;
2424}
2425
2426static void OnSetDefaultBrowserUserChoicePrefChanged(const char* aPref,
2427 void* aData) {
2428 nsresult rv;
2429 if (strcmp(aPref, kPrefSetDefaultBrowserUserChoicePref) != 0) {
2430 return;
2431 }
2432 nsAutoString valueName;
2433 valueName.AssignLiteral("SetDefaultBrowserUserChoice");
2434 rv = PrependRegistryValueName(valueName);
2435 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/toolkit/xre/nsAppRunner.cpp"
, 2435); return; } } while (false)
;
2436
2437 nsCOMPtr<nsIWindowsRegKey> regKey =
2438 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2439 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/toolkit/xre/nsAppRunner.cpp"
, 2439); return; } } while (false)
;
2440
2441 nsAutoString keyName;
2442 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2443 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2444 nsIWindowsRegKey::ACCESS_WRITE);
2445
2446 bool prefVal = Preferences::GetBool(aPref, true);
2447
2448 rv = regKey->WriteIntValue(valueName, prefVal);
2449 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/toolkit/xre/nsAppRunner.cpp"
, 2449); return; } } while (false)
;
2450}
2451
2452static void OnDefaultAgentRemoteSettingsPrefChanged(const char* aPref,
2453 void* aData) {
2454 nsresult rv;
2455 nsAutoString valueName;
2456 if (strcmp(aPref, kPrefServicesSettingsServer) == 0) {
2457 valueName.AssignLiteral("ServicesSettingsServer");
2458 } else {
2459 return;
2460 }
2461 rv = PrependRegistryValueName(valueName);
2462 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/toolkit/xre/nsAppRunner.cpp"
, 2462); return; } } while (false)
;
2463
2464 nsCOMPtr<nsIWindowsRegKey> regKey =
2465 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2466 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/toolkit/xre/nsAppRunner.cpp"
, 2466); return; } } while (false)
;
2467
2468 nsAutoString keyName;
2469 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2470 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2471 nsIWindowsRegKey::ACCESS_WRITE);
2472
2473 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/toolkit/xre/nsAppRunner.cpp"
, 2473); return; } } while (false)
;
2474
2475 nsAutoString prefVal;
2476 rv = Preferences::GetString(aPref, prefVal);
2477 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2478 return;
2479 }
2480
2481 if (prefVal.IsEmpty()) {
2482 rv = regKey->RemoveValue(valueName);
2483 } else {
2484 rv = regKey->WriteStringValue(valueName, prefVal);
2485 }
2486 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/toolkit/xre/nsAppRunner.cpp"
, 2486); return; } } while (false)
;
2487}
2488
2489static void SetDefaultAgentLastRunTime() {
2490 nsresult rv;
2491 nsAutoString valueName;
2492 valueName.AppendLiteral("AppLastRunTime");
2493 rv = PrependRegistryValueName(valueName);
2494 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/toolkit/xre/nsAppRunner.cpp"
, 2494); return; } } while (false)
;
2495
2496 nsCOMPtr<nsIWindowsRegKey> regKey =
2497 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2498 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/toolkit/xre/nsAppRunner.cpp"
, 2498); return; } } while (false)
;
2499
2500 nsAutoString keyName;
2501 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2502 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2503 nsIWindowsRegKey::ACCESS_WRITE);
2504 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/toolkit/xre/nsAppRunner.cpp"
, 2504); return; } } while (false)
;
2505
2506 FILETIME fileTime;
2507 GetSystemTimeAsFileTime(&fileTime);
2508
2509 ULARGE_INTEGER integerTime;
2510 integerTime.u.LowPart = fileTime.dwLowDateTime;
2511 integerTime.u.HighPart = fileTime.dwHighDateTime;
2512
2513 rv = regKey->WriteInt64Value(valueName, integerTime.QuadPart);
2514 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/toolkit/xre/nsAppRunner.cpp"
, 2514); return; } } while (false)
;
2515}
2516
2517# endif // defined(MOZ_DEFAULT_BROWSER_AGENT)
2518
2519#endif // XP_WIN
2520
2521void UnlockProfile() {
2522 if (gProfileLock) {
2523 gProfileLock->Unlock();
2524 }
2525}
2526
2527nsresult LaunchChild(bool aBlankCommandLine, bool aTryExec) {
2528 // Restart this process by exec'ing it into the current process
2529 // if supported by the platform. Otherwise, use NSPR.
2530
2531 if (aBlankCommandLine) {
2532 gRestartArgc = 1;
2533 gRestartArgv[gRestartArgc] = nullptr;
2534 }
2535
2536 SaveToEnv("MOZ_LAUNCHED_CHILD=1");
2537#if defined(MOZ_LAUNCHER_PROCESS)
2538 SaveToEnv("MOZ_LAUNCHER_PROCESS=1");
2539#endif // defined(MOZ_LAUNCHER_PROCESS)
2540
2541#if !defined(MOZ_WIDGET_ANDROID) // Android has separate restart code.
2542# if defined(XP_MACOSX)
2543 InitializeMacApp();
2544 CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv, true);
2545 LaunchMacApp(gRestartArgc, gRestartArgv);
2546# else
2547 nsCOMPtr<nsIFile> lf;
2548 nsresult rv = XRE_GetBinaryPath(getter_AddRefs(lf));
2549 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2550
2551# if defined(XP_WIN)
2552 nsAutoString exePath;
2553 rv = lf->GetPath(exePath);
2554 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2555
2556 HANDLE hProcess;
2557 if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, nullptr,
2558 &hProcess))
2559 return NS_ERROR_FAILURE;
2560 // Keep the current process around until the restarted process has created
2561 // its message queue, to avoid the launched process's windows being forced
2562 // into the background.
2563 mozilla::WaitForInputIdle(hProcess);
2564 ::CloseHandle(hProcess);
2565
2566# else
2567 nsAutoCString exePath;
2568 rv = lf->GetNativePath(exePath);
2569 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2570
2571# if defined(XP_UNIX1)
2572 if (aTryExec) {
2573 execv(exePath.get(), gRestartArgv);
2574
2575 // If execv returns we know it's because it failed.
2576 return NS_ERROR_FAILURE;
2577 }
2578# endif
2579 if (PR_CreateProcessDetached(exePath.get(), gRestartArgv, nullptr, nullptr) ==
2580 PR_FAILURE) {
2581 return NS_ERROR_FAILURE;
2582 }
2583
2584 // Note that we don't know if the child process starts okay, if it
2585 // immediately returns non-zero then we may mask that by returning a zero
2586 // exit status.
2587
2588# endif // WP_WIN
2589# endif // WP_MACOSX
2590#endif // MOZ_WIDGET_ANDROID
2591
2592 return NS_ERROR_LAUNCHED_CHILD_PROCESS;
2593}
2594
2595static const char kProfileProperties[] =
2596 "chrome://mozapps/locale/profile/profileSelection.properties";
2597
2598namespace {
2599
2600/**
2601 * This class, instead of a raw nsresult, should be the return type of any
2602 * function called by SelectProfile that initializes XPCOM.
2603 */
2604class ReturnAbortOnError {
2605 public:
2606 MOZ_IMPLICIT ReturnAbortOnError(nsresult aRv) { mRv = ConvertRv(aRv); }
2607
2608 operator nsresult() { return mRv; }
2609
2610 private:
2611 inline nsresult ConvertRv(nsresult aRv) {
2612 if (NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1))) || aRv == NS_ERROR_LAUNCHED_CHILD_PROCESS) {
2613 return aRv;
2614 }
2615#ifdef MOZ_BACKGROUNDTASKS1
2616 // A background task that fails to lock its profile will return
2617 // NS_ERROR_UNEXPECTED and this will allow the task to exit with a
2618 // non-zero exit code.
2619 if (aRv == NS_ERROR_UNEXPECTED && BackgroundTasks::IsBackgroundTaskMode()) {
2620 return aRv;
2621 }
2622#endif
2623 return NS_ERROR_ABORT;
2624 }
2625
2626 nsresult mRv;
2627};
2628
2629} // namespace
2630
2631static nsresult ProfileMissingDialog(nsINativeAppSupport* aNative) {
2632#ifdef MOZ_WIDGET_ANDROID
2633 // We cannot really do anything this early during initialization, so we just
2634 // return as this is likely the effect of misconfiguration on the test side.
2635 // Non-test code paths cannot set the profile folder, which is always the
2636 // default one.
2637 Output(true, "Could not find profile folder.\n");
2638 return NS_ERROR_ABORT;
2639#else
2640# ifdef MOZ_BACKGROUNDTASKS1
2641 if (BackgroundTasks::IsBackgroundTaskMode()) {
2642 // We should never get to this point in background task mode.
2643 printf_stderr(
2644 "Could not determine any profile running in backgroundtask mode!\n");
2645 return NS_ERROR_ABORT;
2646 }
2647# endif // MOZ_BACKGROUNDTASKS
2648
2649 nsresult rv;
2650
2651 ScopedXPCOMStartup xpcom;
2652 rv = xpcom.Initialize();
2653 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/toolkit/xre/nsAppRunner.cpp"
, 2653); return rv; } } while (false)
;
2654
2655 rv = xpcom.SetWindowCreator(aNative);
2656 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/toolkit/xre/nsAppRunner.cpp"
, 2656); return NS_ERROR_FAILURE; } } while (false)
;
2657
2658# ifdef XP_MACOSX
2659 InitializeMacApp();
2660# endif
2661
2662 { // extra scoping is needed so we release these components before xpcom
2663 // shutdown
2664 nsCOMPtr<nsIStringBundleService> sbs =
2665 mozilla::components::StringBundle::Service();
2666 NS_ENSURE_TRUE(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2666); return NS_ERROR_FAILURE; } } while (false)
;
2667
2668 nsCOMPtr<nsIStringBundle> sb;
2669 sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
2670 NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2670); gLogConsoleErrors = true; return NS_ERROR_FAILURE; }
} while (0)
;
2671
2672 NS_ConvertUTF8toUTF16 appName(gAppData->name);
2673 AutoTArray<nsString, 2> params = {appName, appName};
2674
2675 // profileMissing
2676 nsAutoString missingMessage;
2677 rv = sb->FormatStringFromName("profileMissing", params, missingMessage);
2678 NS_ENSURE_SUCCESS(rv, NS_ERROR_ABORT)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_ABORT", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2678); return NS_ERROR_ABORT; } } while (false)
;
2679
2680 nsAutoString missingTitle;
2681 params.SetLength(1);
2682 rv = sb->FormatStringFromName("profileMissingTitle", params, missingTitle);
2683 NS_ENSURE_SUCCESS(rv, NS_ERROR_ABORT)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_ABORT", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2683); return NS_ERROR_ABORT; } } while (false)
;
2684
2685 nsCOMPtr<nsIPromptService> ps(do_GetService(NS_PROMPTSERVICE_CONTRACTID"@mozilla.org/prompter;1"));
2686 NS_ENSURE_TRUE(ps, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(ps)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "ps" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2686); return NS_ERROR_FAILURE; } } while (false)
;
2687
2688 ps->Alert(nullptr, missingTitle.get(), missingMessage.get());
2689
2690 return NS_ERROR_ABORT;
2691 }
2692#endif // MOZ_WIDGET_ANDROID
2693}
2694
2695static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
2696 nsIFile* aProfileLocalDir,
2697 nsIProfileUnlocker* aUnlocker,
2698 nsINativeAppSupport* aNative,
2699 nsIProfileLock** aResult) {
2700 nsresult rv;
2701
2702 // We aren't going to start this instance so we can unblock other instances
2703 // from starting up.
2704#if defined(MOZ_HAS_REMOTE1)
2705 gStartupLock = nullptr;
2706#endif
2707
2708 bool exists;
2709 aProfileDir->Exists(&exists);
2710 if (!exists) {
2711 return ProfileMissingDialog(aNative);
2712 }
2713
2714 ScopedXPCOMStartup xpcom;
2715 rv = xpcom.Initialize();
2716 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/toolkit/xre/nsAppRunner.cpp"
, 2716); return rv; } } while (false)
;
2717
2718#if defined(MOZ_TELEMETRY_REPORTING)
2719 // We cannot check if telemetry has been disabled by the user, yet.
2720 // So, rely on the build time settings, instead.
2721 mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
2722#endif
2723
2724 rv = xpcom.SetWindowCreator(aNative);
2725 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/toolkit/xre/nsAppRunner.cpp"
, 2725); return NS_ERROR_FAILURE; } } while (false)
;
2726
2727#ifdef XP_MACOSX
2728 InitializeMacApp();
2729#endif
2730
2731 { // extra scoping is needed so we release these components before xpcom
2732 // shutdown
2733 nsCOMPtr<nsIStringBundleService> sbs =
2734 mozilla::components::StringBundle::Service();
2735 NS_ENSURE_TRUE(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2735); return NS_ERROR_FAILURE; } } while (false)
;
2736
2737 nsCOMPtr<nsIStringBundle> sb;
2738 sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
2739 NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2739); gLogConsoleErrors = true; return NS_ERROR_FAILURE; }
} while (0)
;
2740
2741 NS_ConvertUTF8toUTF16 appName(gAppData->name);
2742 AutoTArray<nsString, 3> params = {appName, appName, appName};
2743
2744 nsAutoString killMessage;
2745#ifndef XP_MACOSX
2746 rv = sb->FormatStringFromName(
2747 aUnlocker ? "restartMessageUnlocker" : "restartMessageNoUnlocker2",
2748 params, killMessage);
2749#else
2750 rv = sb->FormatStringFromName(
2751 aUnlocker ? "restartMessageUnlockerMac" : "restartMessageNoUnlockerMac",
2752 params, killMessage);
2753#endif
2754 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/toolkit/xre/nsAppRunner.cpp"
, 2754); return NS_ERROR_FAILURE; } } while (false)
;
2755
2756 params.SetLength(1);
2757 nsAutoString killTitle;
2758 rv = sb->FormatStringFromName("restartTitle", params, killTitle);
2759 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/toolkit/xre/nsAppRunner.cpp"
, 2759); return NS_ERROR_FAILURE; } } while (false)
;
2760
2761#ifdef MOZ_BACKGROUNDTASKS1
2762 if (BackgroundTasks::IsBackgroundTaskMode()) {
2763 // This error is handled specially to exit with a non-zero exit code.
2764 printf_stderr("%s\n", NS_LossyConvertUTF16toASCII(killMessage).get());
2765 return NS_ERROR_UNEXPECTED;
2766 }
2767#endif
2768
2769 if (gfxPlatform::IsHeadless()) {
2770 // TODO: make a way to turn off all dialogs when headless.
2771 Output(true, "%s\n", NS_LossyConvertUTF16toASCII(killMessage).get());
2772 return NS_ERROR_FAILURE;
2773 }
2774
2775 nsCOMPtr<nsIPromptService> ps(do_GetService(NS_PROMPTSERVICE_CONTRACTID"@mozilla.org/prompter;1"));
2776 NS_ENSURE_TRUE(ps, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(ps)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "ps" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2776); return NS_ERROR_FAILURE; } } while (false)
;
2777
2778 if (aUnlocker) {
2779 int32_t button;
2780#ifdef MOZ_WIDGET_ANDROID
2781 // On Android we always kill the process if the lock is still being held
2782 button = 0;
2783#else
2784 const uint32_t flags = (nsIPromptService::BUTTON_TITLE_IS_STRING *
2785 nsIPromptService::BUTTON_POS_0) +
2786 (nsIPromptService::BUTTON_TITLE_CANCEL *
2787 nsIPromptService::BUTTON_POS_1);
2788
2789 bool checkState = false;
2790 rv = ps->ConfirmEx(nullptr, killTitle.get(), killMessage.get(), flags,
2791 killTitle.get(), nullptr, nullptr, nullptr,
2792 &checkState, &button);
2793 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2793); gLogConsoleErrors = true; return rv; } } while (0)
;
2794#endif
2795
2796 if (button == 0) {
2797 rv = aUnlocker->Unlock(nsIProfileUnlocker::FORCE_QUIT);
2798 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2799 return rv;
2800 }
2801
2802 SaveFileToEnv("XRE_PROFILE_PATH", aProfileDir);
2803 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", aProfileLocalDir);
2804
2805 return LaunchChild(false, true);
2806 }
2807 } else {
2808 rv = ps->Alert(nullptr, killTitle.get(), killMessage.get());
2809 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2809); gLogConsoleErrors = true; return rv; } } while (0)
;
2810 }
2811
2812 return NS_ERROR_ABORT;
2813 }
2814}
2815
2816static ReturnAbortOnError ShowProfileDialog(
2817 nsIToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative,
2818 const char* aDialogURL, const char* aTelemetryEnvVar) {
2819 nsresult rv;
2820
2821 nsCOMPtr<nsIFile> profD, profLD;
2822 bool offline = false;
2823 int32_t dialogReturn;
2824
2825 // We aren't going to start this instance so we can unblock other instances
2826 // from starting up.
2827#if defined(MOZ_HAS_REMOTE1)
2828 gStartupLock = nullptr;
2829#endif
2830
2831 {
2832 ScopedXPCOMStartup xpcom;
2833 rv = xpcom.Initialize();
2834 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/toolkit/xre/nsAppRunner.cpp"
, 2834); return rv; } } while (false)
;
2835
2836 rv = xpcom.SetWindowCreator(aNative);
2837 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/toolkit/xre/nsAppRunner.cpp"
, 2837); return NS_ERROR_FAILURE; } } while (false)
;
2838
2839#ifdef XP_MACOSX
2840 InitializeMacApp();
2841 CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv,
2842 true);
2843#endif
2844
2845 { // extra scoping is needed so we release these components before xpcom
2846 // shutdown
2847 nsCOMPtr<nsIWindowWatcher> windowWatcher(
2848 do_GetService(NS_WINDOWWATCHER_CONTRACTID"@mozilla.org/embedcomp/window-watcher;1"));
2849 nsCOMPtr<nsIDialogParamBlock> ioParamBlock(
2850 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID"@mozilla.org/embedcomp/dialogparam;1"));
2851 nsCOMPtr<nsIMutableArray> dlgArray(
2852 do_CreateInstance(NS_ARRAY_CONTRACTID"@mozilla.org/array;1"));
2853 NS_ENSURE_TRUE(windowWatcher && ioParamBlock && dlgArray,do { if ((__builtin_expect(!!(!(windowWatcher && ioParamBlock
&& dlgArray)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "windowWatcher && ioParamBlock && dlgArray"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2854); return NS_ERROR_FAILURE; } } while (false)
2854 NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(windowWatcher && ioParamBlock
&& dlgArray)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "windowWatcher && ioParamBlock && dlgArray"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2854); return NS_ERROR_FAILURE; } } while (false)
;
2855
2856 ioParamBlock->SetObjects(dlgArray);
2857
2858 nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service());
2859 NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(appStartup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "appStartup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2859); return NS_ERROR_FAILURE; } } while (false)
;
2860
2861 nsAutoCString features("centerscreen,chrome,modal,titlebar");
2862 // If we're launching a private browsing window make sure to set that
2863 // feature for the Profile Manager window as well, so it groups correctly
2864 // on the Windows taskbar.
2865 if (CheckArgExists("private-window") == ARG_FOUND) {
2866 features.AppendLiteral(",private");
2867 }
2868 nsCOMPtr<mozIDOMWindowProxy> newWindow;
2869 rv = windowWatcher->OpenWindow(nullptr, nsDependentCString(aDialogURL),
2870 "_blank"_ns, features, ioParamBlock,
2871 getter_AddRefs(newWindow));
2872
2873 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2873); gLogConsoleErrors = true; return rv; } } while (0)
;
2874
2875 rv = ioParamBlock->GetInt(0, &dialogReturn);
2876 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || dialogReturn == nsIToolkitProfileService::exit) {
2877 return NS_ERROR_ABORT;
2878 }
2879
2880 int32_t startOffline;
2881 rv = ioParamBlock->GetInt(1, &startOffline);
2882 offline = NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && startOffline == 1;
2883
2884 rv = dlgArray->QueryElementAt(0, NS_GET_IID(nsIFile)(nsIFile::COMTypeInfo<nsIFile, void>::kIID),
2885 getter_AddRefs(profD));
2886 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2886); gLogConsoleErrors = true; return rv; } } while (0)
;
2887
2888 rv = dlgArray->QueryElementAt(1, NS_GET_IID(nsIFile)(nsIFile::COMTypeInfo<nsIFile, void>::kIID),
2889 getter_AddRefs(profLD));
2890 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2890); gLogConsoleErrors = true; return rv; } } while (0)
;
2891
2892 if (dialogReturn == nsIToolkitProfileService::launchWithProfile) {
2893 int32_t newArguments;
2894 rv = ioParamBlock->GetInt(2, &newArguments);
2895
2896 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && newArguments > 0) {
2897 char** newArgv = (char**)realloc(
2898 gRestartArgv, sizeof(char*) * (gRestartArgc + newArguments + 1));
2899 NS_ENSURE_TRUE(newArgv, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(newArgv)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "newArgv" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2899); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
2900
2901 gRestartArgv = newArgv;
2902
2903 for (auto i = 0; i < newArguments; i++) {
2904 char16_t* arg;
2905 ioParamBlock->GetString(i, &arg);
2906 gRestartArgv[gRestartArgc++] =
2907 strdup(NS_ConvertUTF16toUTF8(nsDependentString(arg)).get());
2908 }
2909
2910 gRestartArgv[gRestartArgc] = nullptr;
2911 }
2912 }
2913 }
2914 }
2915
2916 if (offline) {
2917 SaveToEnv("XRE_START_OFFLINE=1");
2918 }
2919
2920 // User requested that we restart back into the profile manager.
2921 if (dialogReturn == nsIToolkitProfileService::restart) {
2922 SaveToEnv("XRE_RESTART_TO_PROFILE_MANAGER=1");
2923 } else {
2924 MOZ_ASSERT(dialogReturn == nsIToolkitProfileService::launchWithProfile)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(dialogReturn == nsIToolkitProfileService::launchWithProfile
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(dialogReturn == nsIToolkitProfileService::launchWithProfile
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"dialogReturn == nsIToolkitProfileService::launchWithProfile"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2924); AnnotateMozCrashReason("MOZ_ASSERT" "(" "dialogReturn == nsIToolkitProfileService::launchWithProfile"
")"); do { *((volatile int*)__null) = 2924; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2925 SaveFileToEnv("XRE_PROFILE_PATH", profD);
2926 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", profLD);
2927 }
2928 SaveToEnv(aTelemetryEnvVar);
2929
2930 if (gRestartedByOS) {
2931 // Re-add this argument when actually starting the application.
2932 char** newArgv =
2933 (char**)realloc(gRestartArgv, sizeof(char*) * (gRestartArgc + 2));
2934 NS_ENSURE_TRUE(newArgv, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(newArgv)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "newArgv" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2934); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
2935 gRestartArgv = newArgv;
2936 gRestartArgv[gRestartArgc++] = const_cast<char*>("-os-restarted");
2937 gRestartArgv[gRestartArgc] = nullptr;
2938 }
2939
2940 return LaunchChild(false, true);
2941}
2942
2943static ReturnAbortOnError ShowProfileManager(
2944 nsIToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative) {
2945 static const char kProfileManagerURL[] =
2946 "chrome://mozapps/content/profile/profileSelection.xhtml";
2947 static const char kTelemetryEnv[] = "XRE_RESTARTED_BY_PROFILE_MANAGER=1";
2948
2949 return ShowProfileDialog(aProfileSvc, aNative, kProfileManagerURL,
2950 kTelemetryEnv);
2951}
2952
2953static ReturnAbortOnError ShowProfileSelector(
2954 nsIToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative) {
2955 static const char kProfileSelectorURL[] = "about:profilemanager";
2956 static const char kTelemetryEnv[] = "XRE_RESTARTED_BY_PROFILE_SELECTOR=1";
2957
2958 return ShowProfileDialog(aProfileSvc, aNative, kProfileSelectorURL,
2959 kTelemetryEnv);
2960}
2961
2962static bool gDoMigration = false;
2963static bool gDoProfileReset = false;
2964MOZ_RUNINIT static nsCOMPtr<nsIToolkitProfile> gResetOldProfile;
2965
2966static nsresult LockProfile(nsINativeAppSupport* aNative, nsIFile* aRootDir,
2967 nsIFile* aLocalDir, nsIToolkitProfile* aProfile,
2968 nsIProfileLock** aResult) {
2969 // If you close Firefox and very quickly reopen it, the old Firefox may
2970 // still be closing down. Rather than immediately showing the
2971 // "Firefox is running but is not responding" message, we spend a few
2972 // seconds retrying first.
2973
2974 static const int kLockRetrySeconds = 5;
2975 static const int kLockRetrySleepMS = 100;
2976
2977 nsresult rv;
2978 nsCOMPtr<nsIProfileUnlocker> unlocker;
2979 const TimeStamp start = TimeStamp::Now();
2980 do {
2981 if (aProfile) {
2982 rv = aProfile->Lock(getter_AddRefs(unlocker), aResult);
2983 } else {
2984 rv = NS_LockProfilePath(aRootDir, aLocalDir, getter_AddRefs(unlocker),
2985 aResult);
2986 }
2987 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2988 StartupTimeline::Record(StartupTimeline::AFTER_PROFILE_LOCKED);
2989 return NS_OK;
2990 }
2991 PR_Sleep(kLockRetrySleepMS);
2992 } while (TimeStamp::Now() - start <
2993 TimeDuration::FromSeconds(kLockRetrySeconds));
2994
2995 return ProfileLockedDialog(aRootDir, aLocalDir, unlocker, aNative, aResult);
2996}
2997
2998// Pick a profile. We need to end up with a profile root dir, local dir and
2999// potentially an nsIToolkitProfile instance.
3000//
3001// 1) check for --profile <path>
3002// 2) check for -P <name>
3003// 3) check for --ProfileManager
3004// 4) use the default profile, if there is one
3005// 5) if there are *no* profiles, set up profile-migration
3006// 6) display the profile-manager UI
3007static nsresult SelectProfile(nsToolkitProfileService* aProfileSvc,
3008 nsINativeAppSupport* aNative, nsIFile** aRootDir,
3009 nsIFile** aLocalDir, nsIToolkitProfile** aProfile,
3010 bool* aWasDefaultSelection) {
3011 StartupTimeline::Record(StartupTimeline::SELECT_PROFILE);
3012
3013 nsresult rv;
3014
3015 if (EnvHasValue("MOZ_RESET_PROFILE_RESTART")) {
3016 gDoProfileReset = true;
3017 gDoMigration = true;
3018 }
3019
3020 // reset-profile and migration args need to be checked before any profiles are
3021 // chosen below.
3022 ArgResult ar = CheckArg("reset-profile");
3023 if (ar == ARG_FOUND) {
3024 gDoProfileReset = true;
3025 }
3026
3027 ar = CheckArg("migration");
3028 if (ar == ARG_FOUND) {
3029 gDoMigration = true;
3030 }
3031
3032#if defined(XP_WIN)
3033 // This arg is only used to indicate to telemetry that a profile refresh
3034 // (reset+migration) was requested from the uninstaller, pass this along
3035 // via an environment variable for simplicity.
3036 ar = CheckArg("uninstaller-profile-refresh");
3037 if (ar == ARG_FOUND) {
3038 SaveToEnv("MOZ_UNINSTALLER_PROFILE_REFRESH=1");
3039 }
3040#endif
3041
3042 if (EnvHasValue("XRE_RESTART_TO_PROFILE_MANAGER")) {
3043 return ShowProfileManager(aProfileSvc, aNative);
3044 }
3045
3046 // Ask the profile manager to select the profile directories to use.
3047 bool didCreate = false;
3048 rv = aProfileSvc->SelectStartupProfile(&gArgc, gArgv, gDoProfileReset,
3049 aRootDir, aLocalDir, aProfile,
3050 &didCreate, aWasDefaultSelection);
3051
3052 if (rv == NS_ERROR_SHOW_PROFILE_MANAGER) {
3053 return ShowProfileManager(aProfileSvc, aNative);
3054 }
3055
3056 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/toolkit/xre/nsAppRunner.cpp"
, 3056); return rv; } } while (false)
;
3057
3058 if (didCreate) {
3059 // For a fresh install, we would like to let users decide
3060 // to do profile migration on their own later after using.
3061 gDoProfileReset = false;
3062 gDoMigration = false;
3063 }
3064
3065 if (gDoProfileReset && !*aProfile) {
3066 NS_WARNING("Profile reset is only supported for named profiles.")NS_DebugBreak(NS_DEBUG_WARNING, "Profile reset is only supported for named profiles."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3066)
;
3067 return NS_ERROR_ABORT;
3068 }
3069
3070 // No profile could be found. This generally shouldn't happen, a new profile
3071 // should be created in all cases except for profile reset which is covered
3072 // above, but just in case...
3073 if (!*aRootDir) {
3074 NS_WARNING("Failed to select or create profile.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to select or create profile."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3074)
;
3075 return NS_ERROR_ABORT;
3076 }
3077
3078 return NS_OK;
3079}
3080
3081#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE1
3082struct FileWriteFunc final : public JSONWriteFunc {
3083 FILE* mFile;
3084 explicit FileWriteFunc(FILE* aFile) : mFile(aFile) {}
3085
3086 void Write(const Span<const char>& aStr) final {
3087 fprintf(mFile, "%.*s", int(aStr.size()), aStr.data());
3088 }
3089};
3090
3091static void SubmitDowngradeTelemetry(const nsCString& aLastVersion,
3092 bool aHasSync, int32_t aButton) {
3093 nsCOMPtr<nsIPrefService> prefSvc =
3094 do_GetService("@mozilla.org/preferences-service;1");
3095 NS_ENSURE_TRUE_VOID(prefSvc)do { if ((__builtin_expect(!!(!(prefSvc)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefSvc" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3095); return; } } while (false)
;
3096
3097 nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(prefSvc);
3098 NS_ENSURE_TRUE_VOID(prefBranch)do { if ((__builtin_expect(!!(!(prefBranch)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefBranch" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3098); return; } } while (false)
;
3099
3100 bool enabled;
3101 nsresult rv =
3102 prefBranch->GetBoolPref(kPrefHealthReportUploadEnabled, &enabled);
3103 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/toolkit/xre/nsAppRunner.cpp"
, 3103); return; } } while (false)
;
3104 if (!enabled) {
3105 return;
3106 }
3107
3108 nsCString server;
3109 rv = prefBranch->GetCharPref("toolkit.telemetry.server", server);
3110 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/toolkit/xre/nsAppRunner.cpp"
, 3110); return; } } while (false)
;
3111
3112 nsCString clientId;
3113 rv = prefBranch->GetCharPref("toolkit.telemetry.cachedClientID", clientId);
3114 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/toolkit/xre/nsAppRunner.cpp"
, 3114); return; } } while (false)
;
3115
3116 nsCString profileGroupId;
3117 rv = prefBranch->GetCharPref("toolkit.telemetry.cachedProfileGroupID",
3118 profileGroupId);
3119 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/toolkit/xre/nsAppRunner.cpp"
, 3119); return; } } while (false)
;
3120
3121 rv = prefSvc->GetDefaultBranch(nullptr, getter_AddRefs(prefBranch));
3122 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/toolkit/xre/nsAppRunner.cpp"
, 3122); return; } } while (false)
;
3123
3124 nsCString channel("default");
3125 rv = prefBranch->GetCharPref("app.update.channel", channel);
3126 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/toolkit/xre/nsAppRunner.cpp"
, 3126); return; } } while (false)
;
3127
3128 nsID uuid;
3129 rv = nsID::GenerateUUIDInPlace(uuid);
3130 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/toolkit/xre/nsAppRunner.cpp"
, 3130); return; } } while (false)
;
3131
3132 nsCString arch("null");
3133 nsCOMPtr<nsIPropertyBag2> sysInfo =
3134 do_GetService("@mozilla.org/system-info;1");
3135 NS_ENSURE_TRUE_VOID(sysInfo)do { if ((__builtin_expect(!!(!(sysInfo)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "sysInfo" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3135); return; } } while (false)
;
3136 sysInfo->GetPropertyAsACString(u"arch"_ns, arch);
3137
3138 time_t now;
3139 time(&now);
3140 char date[sizeof "YYYY-MM-DDThh:mm:ss.000Z"];
3141 strftime(date, sizeof date, "%FT%T.000Z", gmtime(&now));
3142
3143 NSID_TrimBracketsASCII pingId(uuid);
3144 constexpr auto pingType = "downgrade"_ns;
3145
3146 int32_t pos = aLastVersion.Find("_");
3147 if (pos == kNotFound) {
3148 return;
3149 }
3150
3151 const nsDependentCSubstring lastVersion = Substring(aLastVersion, 0, pos);
3152 const nsDependentCSubstring lastBuildId =
3153 Substring(aLastVersion, pos + 1, 14);
3154
3155 nsPrintfCString url("%s/submit/telemetry/%s/%s/%s/%s/%s/%s?v=%d",
3156 server.get(), PromiseFlatCStringTPromiseFlatString<char>(pingId).get(),
3157 pingType.get(), (const char*)gAppData->name,
3158 (const char*)gAppData->version, channel.get(),
3159 (const char*)gAppData->buildID,
3160 TELEMETRY_PING_FORMAT_VERSION4);
3161
3162 nsCOMPtr<nsIFile> pingFile;
3163 rv = NS_GetSpecialDirectory(XRE_USER_APP_DATA_DIR"UAppData", getter_AddRefs(pingFile));
3164 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/toolkit/xre/nsAppRunner.cpp"
, 3164); return; } } while (false)
;
3165 rv = pingFile->Append(u"Pending Pings"_ns);
3166 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/toolkit/xre/nsAppRunner.cpp"
, 3166); return; } } while (false)
;
3167 rv = pingFile->Create(nsIFile::DIRECTORY_TYPE, 0755);
3168 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_FILE_ALREADY_EXISTS) {
3169 return;
3170 }
3171 rv = pingFile->Append(NS_ConvertUTF8toUTF16(pingId));
3172 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/toolkit/xre/nsAppRunner.cpp"
, 3172); return; } } while (false)
;
3173
3174 nsCOMPtr<nsIFile> pingSender;
3175 rv = NS_GetSpecialDirectory(NS_GRE_BIN_DIR"GreBinD", getter_AddRefs(pingSender));
3176 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/toolkit/xre/nsAppRunner.cpp"
, 3176); return; } } while (false)
;
3177# ifdef XP_WIN
3178 pingSender->Append(u"pingsender.exe"_ns);
3179# else
3180 pingSender->Append(u"pingsender"_ns);
3181# endif
3182
3183 bool exists;
3184 rv = pingSender->Exists(&exists);
3185 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/toolkit/xre/nsAppRunner.cpp"
, 3185); return; } } while (false)
;
3186 if (!exists) {
3187 return;
3188 }
3189
3190 FILE* file;
3191 rv = pingFile->OpenANSIFileDesc("w", &file);
3192 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/toolkit/xre/nsAppRunner.cpp"
, 3192); return; } } while (false)
;
3193
3194 JSONWriter w(MakeUnique<FileWriteFunc>(file));
3195 w.Start();
3196 {
3197 w.StringProperty("type",
3198 Span<const char>(pingType.Data(), pingType.Length()));
3199 w.StringProperty("id", PromiseFlatCStringTPromiseFlatString<char>(pingId));
3200 w.StringProperty("creationDate", MakeStringSpan(date));
3201 w.IntProperty("version", TELEMETRY_PING_FORMAT_VERSION4);
3202 w.StringProperty("clientId", clientId);
3203 w.StringProperty("profileGroupId", profileGroupId);
3204 w.StartObjectProperty("application");
3205 {
3206 w.StringProperty("architecture", arch);
3207 w.StringProperty(
3208 "buildId",
3209 MakeStringSpan(static_cast<const char*>(gAppData->buildID)));
3210 w.StringProperty(
3211 "name", MakeStringSpan(static_cast<const char*>(gAppData->name)));
3212 w.StringProperty(
3213 "version",
3214 MakeStringSpan(static_cast<const char*>(gAppData->version)));
3215 w.StringProperty("displayVersion",
3216 MOZ_STRINGIFY(MOZ_APP_VERSION_DISPLAY)"136.0a1");
3217 w.StringProperty(
3218 "vendor", MakeStringSpan(static_cast<const char*>(gAppData->vendor)));
3219 w.StringProperty("platformVersion", gToolkitVersion);
3220# ifdef TARGET_XPCOM_ABI"x86_64-gcc3"
3221 w.StringProperty("xpcomAbi", TARGET_XPCOM_ABI"x86_64-gcc3");
3222# else
3223 w.StringProperty("xpcomAbi", "unknown");
3224# endif
3225 w.StringProperty("channel", channel);
3226 }
3227 w.EndObject();
3228 w.StartObjectProperty("payload");
3229 {
3230 w.StringProperty("lastVersion", PromiseFlatCStringTPromiseFlatString<char>(lastVersion));
3231 w.StringProperty("lastBuildId", PromiseFlatCStringTPromiseFlatString<char>(lastBuildId));
3232 w.BoolProperty("hasSync", aHasSync);
3233 w.IntProperty("button", aButton);
3234 }
3235 w.EndObject();
3236 }
3237 w.End();
3238
3239 fclose(file);
3240
3241 PathString filePath = pingFile->NativePath();
3242 const filesystem::Path::value_type* args[2];
3243# ifdef XP_WIN
3244 nsString urlw = NS_ConvertUTF8toUTF16(url);
3245 args[0] = urlw.get();
3246# else
3247 args[0] = url.get();
3248# endif
3249 args[1] = filePath.get();
3250
3251 nsCOMPtr<nsIProcess> process =
3252 do_CreateInstance("@mozilla.org/process/util;1");
3253 NS_ENSURE_TRUE_VOID(process)do { if ((__builtin_expect(!!(!(process)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "process" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3253); return; } } while (false)
;
3254 process->Init(pingSender);
3255 process->SetStartHidden(true);
3256 process->SetNoShell(true);
3257
3258# ifdef XP_WIN
3259 process->Runw(false, args, 2);
3260# else
3261 process->Run(false, args, 2);
3262# endif
3263}
3264
3265static const char kProfileDowngradeURL[] =
3266 "chrome://mozapps/content/profile/profileDowngrade.xhtml";
3267
3268static ReturnAbortOnError CheckDowngrade(nsIFile* aProfileDir,
3269 nsINativeAppSupport* aNative,
3270 nsIToolkitProfileService* aProfileSvc,
3271 const nsCString& aLastVersion) {
3272 int32_t result = 0;
3273 nsresult rv;
3274
3275 {
3276 if (gfxPlatform::IsHeadless()) {
3277 // TODO: make a way to turn off all dialogs when headless.
3278 Output(true,
3279 "This profile was last used with a newer version of this "
3280 "application. Please create a new profile.\n");
3281 return NS_ERROR_ABORT;
3282 }
3283
3284 ScopedXPCOMStartup xpcom;
3285 rv = xpcom.Initialize();
3286 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/toolkit/xre/nsAppRunner.cpp"
, 3286); return rv; } } while (false)
;
3287
3288 rv = xpcom.SetWindowCreator(aNative);
3289 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/toolkit/xre/nsAppRunner.cpp"
, 3289); return rv; } } while (false)
;
3290
3291# ifdef XP_MACOSX
3292 InitializeMacApp();
3293# endif
3294
3295 { // extra scoping is needed so we release these components before xpcom
3296 // shutdown
3297 bool hasSync = false;
3298 nsCOMPtr<nsIPrefService> prefSvc =
3299 do_GetService("@mozilla.org/preferences-service;1");
3300 NS_ENSURE_TRUE(prefSvc, rv)do { if ((__builtin_expect(!!(!(prefSvc)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefSvc" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3300); return rv; } } while (false)
;
3301
3302 nsCOMPtr<nsIFile> prefsFile;
3303 rv = aProfileDir->Clone(getter_AddRefs(prefsFile));
3304 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/toolkit/xre/nsAppRunner.cpp"
, 3304); return rv; } } while (false)
;
3305
3306 rv = prefsFile->Append(u"prefs.js"_ns);
3307 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/toolkit/xre/nsAppRunner.cpp"
, 3307); return rv; } } while (false)
;
3308
3309 rv = prefSvc->ReadUserPrefsFromFile(prefsFile);
3310 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3311 nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(prefSvc);
3312
3313 rv = prefBranch->PrefHasUserValue("services.sync.username", &hasSync);
3314 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/toolkit/xre/nsAppRunner.cpp"
, 3314); return rv; } } while (false)
;
3315 }
3316
3317 nsCOMPtr<nsIWindowWatcher> windowWatcher =
3318 do_GetService(NS_WINDOWWATCHER_CONTRACTID"@mozilla.org/embedcomp/window-watcher;1");
3319 NS_ENSURE_TRUE(windowWatcher, NS_ERROR_ABORT)do { if ((__builtin_expect(!!(!(windowWatcher)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "windowWatcher" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3319); return NS_ERROR_ABORT; } } while (false)
;
3320
3321 nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service());
3322 NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(appStartup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "appStartup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3322); return NS_ERROR_FAILURE; } } while (false)
;
3323
3324 nsCOMPtr<nsIDialogParamBlock> paramBlock =
3325 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID"@mozilla.org/embedcomp/dialogparam;1");
3326 NS_ENSURE_TRUE(paramBlock, NS_ERROR_ABORT)do { if ((__builtin_expect(!!(!(paramBlock)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "paramBlock" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3326); return NS_ERROR_ABORT; } } while (false)
;
3327
3328 uint8_t flags = 0;
3329 if (hasSync) {
3330 flags |= nsIToolkitProfileService::hasSync;
3331 }
3332
3333 paramBlock->SetInt(0, flags);
3334
3335 nsAutoCString features("centerscreen,chrome,modal,titlebar");
3336 // If we're launching a private browsing window make sure to set that
3337 // feature for the Profile Manager window as well, so it groups correctly
3338 // on the Windows taskbar.
3339 if (CheckArgExists("private-window") == ARG_FOUND) {
3340 features.AppendLiteral(",private");
3341 }
3342 nsCOMPtr<mozIDOMWindowProxy> newWindow;
3343 rv = windowWatcher->OpenWindow(
3344 nullptr, nsDependentCString(kProfileDowngradeURL), "_blank"_ns,
3345 features, paramBlock, getter_AddRefs(newWindow));
3346 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/toolkit/xre/nsAppRunner.cpp"
, 3346); return rv; } } while (false)
;
3347
3348 paramBlock->GetInt(1, &result);
3349
3350 SubmitDowngradeTelemetry(aLastVersion, hasSync, result);
3351 }
3352 }
3353
3354 if (result == nsIToolkitProfileService::createNewProfile) {
3355 // Create a new profile and start it.
3356 nsCString profileName;
3357 profileName.AssignLiteral("default");
3358# ifdef MOZ_DEDICATED_PROFILES1
3359 profileName.Append("-" MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default");
3360# endif
3361 nsCOMPtr<nsIToolkitProfile> newProfile;
3362 rv = aProfileSvc->CreateUniqueProfile(nullptr, profileName,
3363 getter_AddRefs(newProfile));
3364 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/toolkit/xre/nsAppRunner.cpp"
, 3364); return rv; } } while (false)
;
3365 rv = aProfileSvc->SetDefaultProfile(newProfile);
3366 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/toolkit/xre/nsAppRunner.cpp"
, 3366); return rv; } } while (false)
;
3367 rv = aProfileSvc->Flush();
3368 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/toolkit/xre/nsAppRunner.cpp"
, 3368); return rv; } } while (false)
;
3369
3370 nsCOMPtr<nsIFile> profD, profLD;
3371 rv = newProfile->GetRootDir(getter_AddRefs(profD));
3372 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/toolkit/xre/nsAppRunner.cpp"
, 3372); return rv; } } while (false)
;
3373 rv = newProfile->GetLocalDir(getter_AddRefs(profLD));
3374 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/toolkit/xre/nsAppRunner.cpp"
, 3374); return rv; } } while (false)
;
3375
3376 SaveFileToEnv("XRE_PROFILE_PATH", profD);
3377 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", profLD);
3378
3379 return LaunchChild(false, true);
3380 }
3381
3382 // Cancel
3383 return NS_ERROR_ABORT;
3384}
3385#endif
3386
3387/**
3388 * Extracts the various parts of a compatibility version string.
3389 *
3390 * Compatibility versions are of the form
3391 * "<appversion>_<appbuildid>/<platformbuildid>". The toolkit version comparator
3392 * can only handle 32-bit numbers and in the normal case build IDs are larger
3393 * than this. So if the build ID is numeric we split it into two version parts.
3394 */
3395static void ExtractCompatVersionInfo(const nsACString& aCompatVersion,
3396 nsACString& aAppVersion,
3397 nsACString& aAppBuildID) {
3398 int32_t underscorePos = aCompatVersion.FindChar('_');
3399 int32_t slashPos = aCompatVersion.FindChar('/');
3400
3401 if (underscorePos == kNotFound || slashPos == kNotFound ||
3402 slashPos < underscorePos) {
3403 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "compatibility.ini Version string does not match the expected format."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3404)
3404 "compatibility.ini Version string does not match the expected format.")NS_DebugBreak(NS_DEBUG_WARNING, "compatibility.ini Version string does not match the expected format."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3404)
;
3405
3406 // Fall back to just using the entire string as the version.
3407 aAppVersion = aCompatVersion;
3408 aAppBuildID.Truncate(0);
3409 return;
3410 }
3411
3412 aAppVersion = Substring(aCompatVersion, 0, underscorePos);
3413 aAppBuildID = Substring(aCompatVersion, underscorePos + 1,
3414 slashPos - (underscorePos + 1));
3415}
3416
3417/**
3418 * Compares the provided compatibility versions. Returns 0 if they match,
3419 * < 0 if the new version is considered an upgrade from the old version and
3420 * > 0 if the new version is considered a downgrade from the old version.
3421 */
3422int32_t CompareCompatVersions(const nsACString& aOldCompatVersion,
3423 const nsACString& aNewCompatVersion) {
3424 // Hardcode the case where the last run was in safe mode (Bug 1556612). We
3425 // cannot tell if this is a downgrade or not so just assume it isn't and let
3426 // the user proceed.
3427 if (aOldCompatVersion.EqualsLiteral("Safe Mode")) {
3428 return -1;
3429 }
3430
3431 // Extract the major version part from the version string and only use that
3432 // for version comparison.
3433 int32_t index = aOldCompatVersion.FindChar('.');
3434 const nsACString& oldMajorVersion = Substring(
3435 aOldCompatVersion, 0, index < 0 ? aOldCompatVersion.Length() : index);
3436 index = aNewCompatVersion.FindChar('.');
3437 const nsACString& newMajorVersion = Substring(
3438 aNewCompatVersion, 0, index < 0 ? aNewCompatVersion.Length() : index);
3439
3440 return CompareVersions(PromiseFlatCStringTPromiseFlatString<char>(oldMajorVersion).get(),
3441 PromiseFlatCStringTPromiseFlatString<char>(newMajorVersion).get());
3442}
3443
3444/**
3445 * Checks the compatibility.ini file to see if we have updated our application
3446 * or otherwise invalidated our caches. If the application has been updated,
3447 * we return false; otherwise, we return true.
3448 *
3449 * We also write the status of the caches (valid/invalid) into the return param
3450 * aCachesOK. The aCachesOK is always invalid if the application has been
3451 * updated.
3452 *
3453 * Finally, aIsDowngrade is set to true if the current application is older
3454 * than that previously used by the profile.
3455 */
3456static bool CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion,
3457 const nsCString& aOSABI, nsIFile* aXULRunnerDir,
3458 nsIFile* aAppDir, nsIFile* aFlagFile,
3459 bool* aCachesOK, bool* aIsDowngrade,
3460 nsCString& aLastVersion) {
3461 *aCachesOK = false;
3462 *aIsDowngrade = false;
3463 gLastAppVersion.SetIsVoid(true);
3464 gLastAppBuildID.SetIsVoid(true);
3465
3466 nsCOMPtr<nsIFile> file;
3467 aProfileDir->Clone(getter_AddRefs(file));
3468 if (!file) return false;
3469 file->AppendNative(FILE_COMPATIBILITY_INFO"compatibility.ini"_ns);
3470
3471 nsINIParsernsINIParser_internal parser;
3472 nsresult rv = parser.Init(file);
3473 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3474
3475 rv = parser.GetString("Compatibility", "LastVersion", aLastVersion);
3476 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3477 return false;
3478 }
3479
3480 if (!aLastVersion.Equals(aVersion)) {
3481 // The version is not the same. Whether it's a downgrade depends on an
3482 // actual comparison:
3483 *aIsDowngrade = 0 < CompareCompatVersions(aLastVersion, aVersion);
3484 ExtractCompatVersionInfo(aLastVersion, gLastAppVersion, gLastAppBuildID);
3485 return false;
3486 }
3487
3488 // If we get here, the version matched, but there may still be other
3489 // differences between us and the build that the profile last ran under.
3490
3491 gLastAppVersion.Assign(gAppData->version);
3492 gLastAppBuildID.Assign(gAppData->buildID);
3493
3494 nsAutoCString buf;
3495 rv = parser.GetString("Compatibility", "LastOSABI", buf);
3496 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !aOSABI.Equals(buf)) return false;
3497
3498 rv = parser.GetString("Compatibility", "LastPlatformDir", buf);
3499 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3500
3501 nsCOMPtr<nsIFile> lf;
3502 rv = NS_NewLocalFileWithPersistentDescriptor(buf, getter_AddRefs(lf));
3503 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3504
3505 bool eq;
3506 rv = lf->Equals(aXULRunnerDir, &eq);
3507 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !eq) return false;
3508
3509 if (aAppDir) {
3510 rv = parser.GetString("Compatibility", "LastAppDir", buf);
3511 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3512
3513 rv = NS_NewLocalFileWithPersistentDescriptor(buf, getter_AddRefs(lf));
3514 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3515
3516 rv = lf->Equals(aAppDir, &eq);
3517 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !eq) return false;
3518 }
3519
3520 // If we see this flag, caches are invalid.
3521 rv = parser.GetString("Compatibility", "InvalidateCaches", buf);
3522 *aCachesOK = (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !buf.EqualsLiteral("1"));
3523
3524 bool purgeCaches = false;
3525 if (aFlagFile && NS_SUCCEEDED(aFlagFile->Exists(&purgeCaches))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aFlagFile->Exists
(&purgeCaches))), 1)))
&&
3526 purgeCaches) {
3527 *aCachesOK = false;
3528 }
3529
3530 return true;
3531}
3532
3533void BuildCompatVersion(const char* aAppVersion, const char* aAppBuildID,
3534 const char* aToolkitBuildID, nsACString& aBuf) {
3535 aBuf.Assign(aAppVersion);
3536 aBuf.Append('_');
3537 aBuf.Append(aAppBuildID);
3538 aBuf.Append('/');
3539 aBuf.Append(aToolkitBuildID);
3540}
3541
3542static void BuildVersion(nsCString& aBuf) {
3543 BuildCompatVersion(gAppData->version, gAppData->buildID, gToolkitBuildID,
3544 aBuf);
3545}
3546
3547static void WriteVersion(nsIFile* aProfileDir, const nsCString& aVersion,
3548 const nsCString& aOSABI, nsIFile* aXULRunnerDir,
3549 nsIFile* aAppDir, bool invalidateCache) {
3550 nsCOMPtr<nsIFile> file;
3551 aProfileDir->Clone(getter_AddRefs(file));
3552 if (!file) return;
3553 file->AppendNative(FILE_COMPATIBILITY_INFO"compatibility.ini"_ns);
3554
3555 nsAutoCString platformDir;
3556 Unused << aXULRunnerDir->GetPersistentDescriptor(platformDir);
3557
3558 nsAutoCString appDir;
3559 if (aAppDir) Unused << aAppDir->GetPersistentDescriptor(appDir);
3560
3561 PRFileDesc* fd;
3562 nsresult rv = file->OpenNSPRFileDesc(PR_WRONLY0x02 | PR_CREATE_FILE0x08 | PR_TRUNCATE0x20,
3563 0600, &fd);
3564 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3565 NS_ERROR("could not create output stream")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "could not create output stream"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3565); MOZ_PretendNoReturn(); } while (0)
;
3566 return;
3567 }
3568
3569 static const char kHeader[] = "[Compatibility]" NS_LINEBREAK"\012" "LastVersion=";
3570
3571 PR_Write(fd, kHeader, sizeof(kHeader) - 1);
3572 PR_Write(fd, aVersion.get(), aVersion.Length());
3573
3574 static const char kOSABIHeader[] = NS_LINEBREAK"\012" "LastOSABI=";
3575 PR_Write(fd, kOSABIHeader, sizeof(kOSABIHeader) - 1);
3576 PR_Write(fd, aOSABI.get(), aOSABI.Length());
3577
3578 static const char kPlatformDirHeader[] = NS_LINEBREAK"\012" "LastPlatformDir=";
3579
3580 PR_Write(fd, kPlatformDirHeader, sizeof(kPlatformDirHeader) - 1);
3581 PR_Write(fd, platformDir.get(), platformDir.Length());
3582
3583 static const char kAppDirHeader[] = NS_LINEBREAK"\012" "LastAppDir=";
3584 if (aAppDir) {
3585 PR_Write(fd, kAppDirHeader, sizeof(kAppDirHeader) - 1);
3586 PR_Write(fd, appDir.get(), appDir.Length());
3587 }
3588
3589 static const char kInvalidationHeader[] = NS_LINEBREAK"\012" "InvalidateCaches=1";
3590 if (invalidateCache)
3591 PR_Write(fd, kInvalidationHeader, sizeof(kInvalidationHeader) - 1);
3592
3593 static const char kNL[] = NS_LINEBREAK"\012";
3594 PR_Write(fd, kNL, sizeof(kNL) - 1);
3595
3596 PR_Close(fd);
3597}
3598
3599/**
3600 * Returns true if the startup cache file was successfully removed.
3601 * Returns false if file->Clone fails at any point (OOM) or if unable
3602 * to remove the startup cache file. Note in particular the return value
3603 * is unaffected by a failure to remove extensions.ini
3604 */
3605static bool RemoveComponentRegistries(nsIFile* aProfileDir,
3606 nsIFile* aLocalProfileDir,
3607 bool aRemoveEMFiles) {
3608 nsCOMPtr<nsIFile> file;
3609 aProfileDir->Clone(getter_AddRefs(file));
3610 if (!file) return false;
3611
3612 if (aRemoveEMFiles) {
3613 file->SetNativeLeafName("extensions.ini"_ns);
3614 file->Remove(false);
3615 }
3616
3617 aLocalProfileDir->Clone(getter_AddRefs(file));
3618 if (!file) return false;
3619
3620 file->AppendNative("startupCache"_ns);
3621 nsresult rv = file->Remove(true);
3622 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) || rv == NS_ERROR_FILE_NOT_FOUND;
3623}
3624
3625// When we first initialize the crash reporter we don't have a profile,
3626// so we set the minidump path to $TEMP. Once we have a profile,
3627// we set it to $PROFILE/minidumps, creating the directory
3628// if needed.
3629static void MakeOrSetMinidumpPath(nsIFile* profD) {
3630 nsCOMPtr<nsIFile> dumpD;
3631 profD->Clone(getter_AddRefs(dumpD));
3632
3633 if (dumpD) {
3634 bool fileExists;
3635 // XXX: do some more error checking here
3636 dumpD->Append(u"minidumps"_ns);
3637 dumpD->Exists(&fileExists);
3638 if (!fileExists) {
3639 nsresult rv = dumpD->Create(nsIFile::DIRECTORY_TYPE, 0700);
3640 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/toolkit/xre/nsAppRunner.cpp"
, 3640); return; } } while (false)
;
3641 }
3642
3643 nsAutoString pathStr;
3644 if (NS_SUCCEEDED(dumpD->GetPath(pathStr))((bool)(__builtin_expect(!!(!NS_FAILED_impl(dumpD->GetPath
(pathStr))), 1)))
)
3645 CrashReporter::SetMinidumpPath(pathStr);
3646 }
3647}
3648
3649const XREAppData* gAppData = nullptr;
3650
3651/**
3652 * NSPR will search for the "nspr_use_zone_allocator" symbol throughout
3653 * the process and use it to determine whether the application defines its own
3654 * memory allocator or not.
3655 *
3656 * Since most applications (e.g. Firefox and Thunderbird) don't use any special
3657 * allocators and therefore don't define this symbol, NSPR must search the
3658 * entire process, which reduces startup performance.
3659 *
3660 * By defining the symbol here, we can avoid the wasted lookup and hopefully
3661 * improve startup performance.
3662 */
3663NS_VISIBILITY_DEFAULT__attribute__((visibility("default"))) PRBool nspr_use_zone_allocator = PR_FALSE0;
3664
3665#ifdef CAIRO_HAS_DWRITE_FONT
3666
3667# include <dwrite.h>
3668# include "nsWindowsHelpers.h"
3669
3670# ifdef DEBUG_DWRITE_STARTUP
3671
3672# define LOGREGISTRY(msg) LogRegistryEvent(msg)
3673
3674// for use when monitoring process
3675static void LogRegistryEvent(const wchar_t* msg) {
3676 HKEY dummyKey;
3677 HRESULT hr;
3678 wchar_t buf[512];
3679
3680 wsprintf(buf, L" log %s", msg);
3681 hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buf, 0, KEY_READ, &dummyKey);
3682 if (SUCCEEDED(hr)) {
3683 RegCloseKey(dummyKey);
3684 }
3685}
3686# else
3687
3688# define LOGREGISTRY(msg)
3689
3690# endif
3691
3692static DWORD WINAPI InitDwriteBG(LPVOID lpdwThreadParam) {
3693 SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
3694 LOGREGISTRY(L"loading dwrite.dll");
3695 HMODULE dwdll = LoadLibrarySystem32(L"dwrite.dll");
3696 if (dwdll) {
3697 decltype(DWriteCreateFactory)* createDWriteFactory =
3698 (decltype(DWriteCreateFactory)*)GetProcAddress(dwdll,
3699 "DWriteCreateFactory");
3700 if (createDWriteFactory) {
3701 LOGREGISTRY(L"creating dwrite factory");
3702 IDWriteFactory* factory;
3703 HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED,
3704 __uuidof(IDWriteFactory),
3705 reinterpret_cast<IUnknown**>(&factory));
3706 if (SUCCEEDED(hr)) {
3707 LOGREGISTRY(L"dwrite factory done");
3708 factory->Release();
3709 LOGREGISTRY(L"freed factory");
3710 } else {
3711 LOGREGISTRY(L"failed to create factory");
3712 }
3713 }
3714 }
3715 SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
3716 return 0;
3717}
3718#endif
3719
3720#include "GeckoProfiler.h"
3721#include "ProfilerControl.h"
3722
3723// Encapsulates startup and shutdown state for XRE_main
3724class XREMain {
3725 public:
3726 XREMain() = default;
3727
3728 ~XREMain() {
3729 mScopedXPCOM = nullptr;
3730 mAppData = nullptr;
3731 }
3732
3733 int XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig);
3734 int XRE_mainInit(bool* aExitFlag);
3735 int XRE_mainStartup(bool* aExitFlag);
3736 nsresult XRE_mainRun();
3737
3738 bool CheckLastStartupWasCrash();
3739
3740 nsCOMPtr<nsINativeAppSupport> mNativeApp;
3741 RefPtr<nsToolkitProfileService> mProfileSvc;
3742 nsCOMPtr<nsIFile> mProfD;
3743 nsCOMPtr<nsIFile> mProfLD;
3744 nsCOMPtr<nsIProfileLock> mProfileLock;
3745
3746 UniquePtr<ScopedXPCOMStartup> mScopedXPCOM;
3747 UniquePtr<XREAppData> mAppData;
3748
3749 nsXREDirProvider mDirProvider;
3750
3751#ifdef MOZ_WIDGET_GTK1
3752 nsAutoCString mXDGActivationToken;
3753 nsAutoCString mDesktopStartupID;
3754#endif
3755
3756 bool mStartOffline = false;
3757 nsAutoCString mOriginToForceQUIC;
3758#if defined(MOZ_HAS_REMOTE1)
3759 bool mDisableRemoteClient = false;
3760#endif
3761};
3762
3763#if defined(XP_UNIX1) && !defined(ANDROID)
3764static SmprintfPointer FormatUid(uid_t aId) {
3765 if (const auto pw = getpwuid(aId)) {
3766 return mozilla::Smprintf("%s", pw->pw_name);
3767 }
3768 return mozilla::Smprintf("uid %d", static_cast<int>(aId));
3769}
3770
3771// Bug 1323302: refuse to run under sudo or similar.
3772static bool CheckForUserMismatch() {
3773 static char const* const kVars[] = {
3774 "HOME",
3775# ifdef MOZ_WIDGET_GTK1
3776 "XDG_RUNTIME_DIR",
3777# endif
3778# ifdef MOZ_X111
3779 "XAUTHORITY",
3780# endif
3781 };
3782
3783 const uid_t euid = geteuid();
3784 if (euid != 0) {
3785 // On Linux it's possible to have superuser capabilities with a
3786 // nonzero uid, but anyone who knows enough to make that happen
3787 // probably knows enough to debug the resulting problems.
3788 // Otherwise, a non-root user can't cause the problems we're
3789 // concerned about.
3790 return false;
3791 }
3792
3793 for (const auto var : kVars) {
3794 if (const auto path = PR_GetEnv(var)) {
3795 struct stat st;
3796 if (stat(path, &st) == 0) {
3797 if (st.st_uid != euid) {
3798 const auto owner = FormatUid(st.st_uid);
3799 Output(true,
3800 "Running " MOZ_APP_DISPLAYNAME"Nightly"
3801 " as root in a regular"
3802 " user's session is not supported. ($%s is %s which is"
3803 " owned by %s.)\n",
3804 var, path, owner.get());
3805 return true;
3806 }
3807 }
3808 }
3809 }
3810 return false;
3811}
3812#else // !XP_UNIX || ANDROID
3813static bool CheckForUserMismatch() { return false; }
3814#endif
3815
3816void mozilla::startup::IncreaseDescriptorLimits() {
3817#ifdef XP_UNIX1
3818 // Increase the fd limit to accomodate IPC resources like shared memory.
3819# ifdef XP_DARWIN
3820 // We use Mach IPC for shared memory, so a lower limit suffices.
3821 // See also the Darwin case in config/external/nspr/pr/moz.build
3822 static constexpr rlim_t kFDs = 4096;
3823# else // Unix but not Darwin
3824 // This can be increased if needed, but also be aware that Linux
3825 // distributions may impose hard limits less than this.
3826 static constexpr rlim_t kFDs = 65536;
3827# endif // Darwin or not
3828 struct rlimit rlim;
3829
3830 if (getrlimit(RLIMIT_NOFILERLIMIT_NOFILE, &rlim) != 0) {
3831 Output(false, "getrlimit: %s\n", strerror(errno(*__errno_location ())));
3832 return;
3833 }
3834 // Don't decrease the limit if it's already high enough, but don't
3835 // try to go over the hard limit. (RLIM_INFINITY isn't required to
3836 // be the numerically largest rlim_t, so don't assume that.)
3837 if (rlim.rlim_cur != RLIM_INFINITY((__rlim_t) -1) && rlim.rlim_cur < kFDs &&
3838 rlim.rlim_cur < rlim.rlim_max) {
3839 if (rlim.rlim_max != RLIM_INFINITY((__rlim_t) -1) && rlim.rlim_max < kFDs) {
3840 rlim.rlim_cur = rlim.rlim_max;
3841 } else {
3842 rlim.rlim_cur = kFDs;
3843 }
3844 if (setrlimit(RLIMIT_NOFILERLIMIT_NOFILE, &rlim) != 0) {
3845 Output(false, "setrlimit: %s\n", strerror(errno(*__errno_location ())));
3846 }
3847 }
3848#endif
3849}
3850
3851#ifdef XP_WIN
3852// Looks for the current CPU microcode version, returns 0 if it cannot find it
3853static uint32_t FindCPUMicrocodeVersion(HKEY key) {
3854 // Windows uses different registry values to surface the current microcode
3855 // value, and sometimes different update levels of the same version use
3856 // different values (e.g. Windows 11 24H2 uses "Current Record Version",
3857 // older Windows 11 and Windows 8/10 use "Update Revision", Windows 7 uses
3858 // "Update Signature" or sometimes "CurrentPatchLevel" for AMD CPUs.
3859 // Microcode version is represented by a 32-bit value but sometimes a 64-bit
3860 // value is surfaced instead with only half of it populated (e.g.
3861 // "Update Revision" on Windows 8, 10 and 11 pre-24H2). Since in these cases
3862 // the other half is zero, we pick the first non-zero 32-bit value we find
3863 // starting with the most "modern" registry value.
3864 LPCWSTR choices[] = {L"Current Record Version", L"Update Revision",
3865 L"Update Signature", L"CurrentPatchLevel"};
3866 for (const auto& oneChoice : choices) {
3867 DWORD keyValue[2] = {};
3868 DWORD len = sizeof(keyValue);
3869 DWORD vtype;
3870
3871 if (RegQueryValueExW(key, oneChoice, nullptr, &vtype,
3872 reinterpret_cast<LPBYTE>(keyValue),
3873 &len) == ERROR_SUCCESS) {
3874 if ((vtype == REG_BINARY) || (vtype == REG_DWORD)) {
3875 for (size_t i = 0; i < (len / sizeof(DWORD)); i++) {
3876 uint32_t value = keyValue[i];
3877
3878 if (value != 0) {
3879 return value;
3880 }
3881 }
3882 }
3883 }
3884 }
3885
3886 return 0;
3887}
3888#endif
3889
3890static void MaybeAddCPUMicrocodeCrashAnnotation() {
3891#ifdef XP_WIN
3892 // Add CPU microcode version to the crash report as "CPUMicrocodeVersion".
3893 // It feels like this code may belong in nsSystemInfo instead.
3894 HKEY key;
3895 static const WCHAR keyName[] =
3896 L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
3897
3898 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &key) ==
3899 ERROR_SUCCESS) {
3900 uint32_t cpuMicrocodeVersion = FindCPUMicrocodeVersion(key);
3901
3902 if (cpuMicrocodeVersion != 0) {
3903 CrashReporter::RecordAnnotationNSCString(
3904 CrashReporter::Annotation::CPUMicrocodeVersion,
3905 nsPrintfCString("0x%" PRIx32"x", cpuMicrocodeVersion));
3906 }
3907 }
3908#endif
3909}
3910
3911#if defined(MOZ_BACKGROUNDTASKS1)
3912static void SetupConsoleForBackgroundTask(
3913 const nsCString& aBackgroundTaskName) {
3914 // We do not suppress output on Windows because:
3915 // 1. Background task subprocesses launched via LaunchApp() does not attach to
3916 // the console.
3917 // 2. Suppressing output intermittently causes failures on when running
3918 // multiple tasks (see bug 1831631)
3919# ifndef XP_WIN
3920 if (BackgroundTasks::IsNoOutputTaskName(aBackgroundTaskName) &&
3921 !CheckArg("attach-console") &&
3922 !EnvHasValue("MOZ_BACKGROUNDTASKS_IGNORE_NO_OUTPUT")) {
3923 // Suppress output, somewhat crudely. We need to suppress stderr as well
3924 // as stdout because assertions, of which there are many, write to stderr.
3925 Unused << freopen("/dev/null", "w", stdoutstdout);
3926 Unused << freopen("/dev/null", "w", stderrstderr);
3927 return;
3928 }
3929# endif
3930 printf_stderr("*** You are running in background task mode. ***\n");
3931}
3932#endif
3933
3934/*
3935 * XRE_mainInit - Initial setup and command line parameter processing.
3936 * Main() will exit early if either return value != 0 or if aExitFlag is
3937 * true.
3938 */
3939int XREMain::XRE_mainInit(bool* aExitFlag) {
3940 if (!aExitFlag) return 1;
1
Assuming 'aExitFlag' is non-null
2
Taking false branch
3941 *aExitFlag = false;
3942
3943 atexit(UnexpectedExit);
3944 auto expectedShutdown = mozilla::MakeScopeExit([&] { MozExpectedExit(); });
3945
3946 StartupTimeline::Record(StartupTimeline::MAIN);
3947
3948 if (CheckForUserMismatch()) {
3
Taking false branch
3949 return 1;
3950 }
3951
3952#ifdef XP_MACOSX
3953 mozilla::MacAutoreleasePool pool;
3954
3955 DisableAppNap();
3956#endif
3957
3958#ifdef MOZ_BACKGROUNDTASKS1
3959 Maybe<nsCString> backgroundTask = Nothing();
3960 const char* backgroundTaskName = nullptr;
3961 if (ARG_FOUND ==
4
Assuming the condition is false
5
Taking false branch
3962 CheckArg("backgroundtask", &backgroundTaskName, CheckArgFlag::None)) {
3963 backgroundTask = Some(backgroundTaskName);
3964
3965 SetupConsoleForBackgroundTask(backgroundTask.ref());
3966 }
3967
3968 BackgroundTasks::Init(backgroundTask);
3969#endif
3970
3971#ifndef ANDROID
3972 if (PR_GetEnv("MOZ_RUN_GTEST")
6
Assuming the condition is false
8
Taking false branch
3973# ifdef FUZZING
3974 || PR_GetEnv("FUZZER")
3975# endif
3976# ifdef MOZ_BACKGROUNDTASKS1
3977 || BackgroundTasks::IsBackgroundTaskMode()
7
Assuming the condition is false
3978# endif
3979 ) {
3980 // Enable headless mode and assert that it worked, since gfxPlatform
3981 // uses a static bool set after the first call to `IsHeadless`.
3982 // Note: Android gtests seem to require an Activity and fail to start
3983 // with headless mode enabled.
3984 PR_SetEnv("MOZ_HEADLESS=1");
3985 MOZ_ASSERT(gfxPlatform::IsHeadless())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gfxPlatform::IsHeadless())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(gfxPlatform::IsHeadless())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("gfxPlatform::IsHeadless()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3985); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gfxPlatform::IsHeadless()"
")"); do { *((volatile int*)__null) = 3985; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3986 }
3987#endif // ANDROID
3988
3989 if (PR_GetEnv("MOZ_CHAOSMODE")) {
9
Assuming the condition is false
10
Taking false branch
3990 ChaosFeature feature = ChaosFeature::Any;
3991 long featureInt = strtol(PR_GetEnv("MOZ_CHAOSMODE"), nullptr, 16);
3992 if (featureInt) {
3993 // NOTE: MOZ_CHAOSMODE=0 or a non-hex value maps to Any feature.
3994 feature = static_cast<ChaosFeature>(featureInt);
3995 }
3996 ChaosMode::SetChaosFeature(feature);
3997 }
3998
3999 if (CheckArgExists("fxr")) {
11
Assuming the condition is false
12
Taking false branch
4000 gFxREmbedded = true;
4001 }
4002
4003 if (ChaosMode::isActive(ChaosFeature::Any)) {
13
Assuming the condition is false
4004 printf_stderr(
4005 "*** You are running in chaos test mode. See ChaosMode.h. ***\n");
4006 }
4007
4008 if (CheckArg("headless") || CheckArgExists("screenshot")) {
14
Assuming the condition is true
4009 PR_SetEnv("MOZ_HEADLESS=1");
4010 }
4011
4012 if (gfxPlatform::IsHeadless()) {
15
Assuming the condition is false
16
Taking false branch
4013#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK1) || defined(XP_MACOSX)
4014 printf_stderr("*** You are running in headless mode.\n");
4015#else
4016 Output(
4017 true,
4018 "Error: headless mode is not currently supported on this platform.\n");
4019 return 1;
4020#endif
4021
4022#ifdef XP_MACOSX
4023 // To avoid taking focus when running in headless mode immediately
4024 // transition Firefox to a background application.
4025 ProcessSerialNumber psn = {0, kCurrentProcess};
4026 OSStatus transformStatus =
4027 TransformProcessType(&psn, kProcessTransformToBackgroundApplication);
4028 if (transformStatus != noErr) {
4029 NS_ERROR("Failed to make process a background application.")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Failed to make process a background application."
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4029); MOZ_PretendNoReturn(); } while (0)
;
4030 return 1;
4031 }
4032#endif
4033 }
4034
4035 gKioskMode = CheckArg("kiosk", nullptr, CheckArgFlag::None);
4036 const char* kioskMonitorNumber = nullptr;
4037 if (CheckArg("kiosk-monitor", &kioskMonitorNumber, CheckArgFlag::None)) {
17
Assuming the condition is false
18
Taking false branch
4038 gKioskMode = true;
4039 gKioskMonitor = atoi(kioskMonitorNumber);
4040 }
4041
4042#if defined(NIGHTLY_BUILD1)
4043 if (XRE_IsParentProcess()) {
19
Taking false branch
4044 gAllowContentAnalysisArgPresent =
4045 CheckArg("allow-content-analysis", nullptr, CheckArgFlag::None) ==
4046 ARG_FOUND;
4047 }
4048#endif
4049
4050 nsresult rv;
4051 ArgResult ar;
4052
4053#ifdef DEBUG1
4054 if (PR_GetEnv("XRE_MAIN_BREAK")) NS_BREAK()do { NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4054); MOZ_PretendNoReturn(); } while (0)
;
20
Assuming the condition is false
21
Taking false branch
4055#endif
4056
4057 mozilla::startup::IncreaseDescriptorLimits();
4058
4059 SetupErrorHandling(gArgv[0]);
4060
4061#ifdef CAIRO_HAS_DWRITE_FONT
4062 {
4063 // Bug 602792 - when DWriteCreateFactory is called the dwrite client dll
4064 // starts the FntCache service if it isn't already running (it's set
4065 // to manual startup by default in Windows 7 RTM). Subsequent DirectWrite
4066 // calls cause the IDWriteFactory object to communicate with the FntCache
4067 // service with a timeout; if there's no response after the timeout, the
4068 // DirectWrite client library will assume the service isn't around and do
4069 // manual font file I/O on _all_ system fonts. To avoid this, load the
4070 // dwrite library and create a factory as early as possible so that the
4071 // FntCache service is ready by the time it's needed.
4072
4073 CreateThread(nullptr, 0, &InitDwriteBG, nullptr, 0, nullptr);
4074 }
4075#endif
4076
4077#ifdef XP_UNIX1
4078 const char* home = PR_GetEnv("HOME");
4079 if (!home || !*home) {
22
Assuming 'home' is non-null
23
Assuming the condition is false
24
Taking false branch
4080 struct passwd* pw = getpwuid(geteuid());
4081 if (!pw || !pw->pw_dir) {
4082 Output(true, "Could not determine HOME directory");
4083 return 1;
4084 }
4085 SaveWordToEnv("HOME", nsDependentCString(pw->pw_dir));
4086 }
4087#endif
4088
4089#ifdef MOZ_ACCESSIBILITY_ATK1
4090 // Suppress atk-bridge init at startup, until mozilla accessibility is
4091 // initialized. This works after gnome 2.24.2.
4092 SaveToEnv("NO_AT_BRIDGE=1");
25
Calling 'SaveToEnv'
4093#endif
4094
4095 // Check for application.ini overrides
4096 const char* override = nullptr;
4097 ar = CheckArg("override", &override);
4098 if (ar == ARG_BAD) {
4099 Output(true, "Incorrect number of arguments passed to --override");
4100 return 1;
4101 }
4102 if (ar == ARG_FOUND) {
4103 nsCOMPtr<nsIFile> overrideLF;
4104 rv = XRE_GetFileFromPath(override, getter_AddRefs(overrideLF));
4105 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4106 Output(true, "Error: unrecognized override.ini path.\n");
4107 return 1;
4108 }
4109
4110 rv = XRE_ParseAppData(overrideLF, *mAppData);
4111 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4112 Output(true, "Couldn't read override.ini");
4113 return 1;
4114 }
4115 }
4116
4117 // Check sanity and correctness of app data.
4118
4119 if (!mAppData->name) {
4120 Output(true, "Error: App:Name not specified in application.ini\n");
4121 return 1;
4122 }
4123 if (!mAppData->buildID) {
4124 Output(true, "Error: App:BuildID not specified in application.ini\n");
4125 return 1;
4126 }
4127
4128 // XXX Originally ScopedLogging was here? Now it's in XRE_main above
4129 // XRE_mainInit.
4130
4131 if (!mAppData->minVersion) {
4132 Output(true, "Error: Gecko:MinVersion not specified in application.ini\n");
4133 return 1;
4134 }
4135
4136 if (!mAppData->maxVersion) {
4137 // If no maxVersion is specified, we assume the app is only compatible
4138 // with the initial preview release. Do not increment this number ever!
4139 mAppData->maxVersion = "1.*";
4140 }
4141
4142 if (mozilla::Version(mAppData->minVersion) > gToolkitVersion ||
4143 mozilla::Version(mAppData->maxVersion) < gToolkitVersion) {
4144 Output(true,
4145 "Error: Platform version '%s' is not compatible with\n"
4146 "minVersion >= %s\nmaxVersion <= %s\n"
4147 "Maybe try to reinstall " MOZ_APP_DISPLAYNAME"Nightly" "?\n",
4148 (const char*)gToolkitVersion, (const char*)mAppData->minVersion,
4149 (const char*)mAppData->maxVersion);
4150 return 1;
4151 }
4152
4153 rv = mDirProvider.Initialize(mAppData->directory, mAppData->xreDirectory);
4154 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return 1;
4155
4156 if (EnvHasValue("MOZ_CRASHREPORTER")) {
4157 mAppData->flags |= NS_XRE_ENABLE_CRASH_REPORTER(1 << 3);
4158 }
4159
4160 nsCOMPtr<nsIFile> xreBinDirectory;
4161 xreBinDirectory = mDirProvider.GetGREBinDir();
4162
4163 if ((mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER(1 << 3)) &&
4164 NS_SUCCEEDED(CrashReporter::SetExceptionHandler(xreBinDirectory))((bool)(__builtin_expect(!!(!NS_FAILED_impl(CrashReporter::SetExceptionHandler
(xreBinDirectory))), 1)))
) {
4165 nsCOMPtr<nsIFile> file;
4166 rv = nsXREDirProvider::GetUserAppDataDirectory(getter_AddRefs(file));
4167 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4168 CrashReporter::SetUserAppDataDirectory(file);
4169 }
4170 if (mAppData->crashReporterURL) {
4171 CrashReporter::SetServerURL(
4172 nsDependentCString(mAppData->crashReporterURL));
4173 }
4174
4175 // We overwrite this once we finish starting up.
4176 CrashReporter::RecordAnnotationBool(CrashReporter::Annotation::StartupCrash,
4177 true);
4178
4179 // pass some basic info from the app data
4180 if (mAppData->vendor) {
4181 CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::Vendor,
4182 mAppData->vendor);
4183 }
4184 if (mAppData->name) {
4185 CrashReporter::RecordAnnotationCString(
4186 CrashReporter::Annotation::ProductName, mAppData->name);
4187 }
4188 if (mAppData->ID) {
4189 CrashReporter::RecordAnnotationCString(
4190 CrashReporter::Annotation::ProductID, mAppData->ID);
4191 }
4192 if (mAppData->version) {
4193 CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::Version,
4194 mAppData->version);
4195 }
4196 if (mAppData->buildID) {
4197 CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::BuildID,
4198 mAppData->buildID);
4199 }
4200
4201 nsDependentCString releaseChannel(MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default");
4202 CrashReporter::RecordAnnotationNSCString(
4203 CrashReporter::Annotation::ReleaseChannel, releaseChannel);
4204
4205#ifdef XP_WIN
4206 nsAutoString appInitDLLs;
4207 if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) {
4208 CrashReporter::RecordAnnotationNSString(
4209 CrashReporter::Annotation::AppInitDLLs, appInitDLLs);
4210 }
4211
4212 nsString packageFamilyName = widget::WinUtils::GetPackageFamilyName();
4213 if (StringBeginsWith(packageFamilyName, u"Mozilla."_ns) ||
4214 StringBeginsWith(packageFamilyName, u"MozillaCorporation."_ns)) {
4215 CrashReporter::RecordAnnotationNSCString(
4216 CrashReporter::Annotation::WindowsPackageFamilyName,
4217 NS_ConvertUTF16toUTF8(packageFamilyName));
4218 }
4219#endif
4220
4221 bool isBackgroundTaskMode = false;
4222#ifdef MOZ_BACKGROUNDTASKS1
4223 Maybe<nsCString> backgroundTasks = BackgroundTasks::GetBackgroundTasks();
4224 if (backgroundTasks.isSome()) {
4225 isBackgroundTaskMode = true;
4226 CrashReporter::RecordAnnotationNSCString(
4227 CrashReporter::Annotation::BackgroundTaskName, backgroundTasks.ref());
4228 }
4229#endif
4230 CrashReporter::RecordAnnotationBool(
4231 CrashReporter::Annotation::BackgroundTaskMode, isBackgroundTaskMode);
4232
4233 CrashReporter::RecordAnnotationBool(CrashReporter::Annotation::HeadlessMode,
4234 gfxPlatform::IsHeadless());
4235
4236 CrashReporter::SetRestartArgs(gArgc, gArgv);
4237
4238 // annotate other data (user id etc)
4239 nsCOMPtr<nsIFile> userAppDataDir;
4240 if (NS_SUCCEEDED(mDirProvider.GetUserAppDataDirectory(((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetUserAppDataDirectory
( getter_AddRefs(userAppDataDir)))), 1)))
4241 getter_AddRefs(userAppDataDir)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetUserAppDataDirectory
( getter_AddRefs(userAppDataDir)))), 1)))
) {
4242 CrashReporter::SetupExtraData(userAppDataDir,
4243 nsDependentCString(mAppData->buildID));
4244
4245 // see if we have a crashreporter-override.ini in the application
4246 // directory
4247 nsCOMPtr<nsIFile> overrideini;
4248 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetAppDir
()->Clone(getter_AddRefs(overrideini)))), 1)))
4249 mDirProvider.GetAppDir()->Clone(getter_AddRefs(overrideini)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetAppDir
()->Clone(getter_AddRefs(overrideini)))), 1)))
&&
4250 NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(overrideini->AppendNative
("crashreporter-override.ini"_ns))), 1)))
4251 overrideini->AppendNative("crashreporter-override.ini"_ns))((bool)(__builtin_expect(!!(!NS_FAILED_impl(overrideini->AppendNative
("crashreporter-override.ini"_ns))), 1)))
) {
4252#ifdef XP_WIN
4253 nsAutoString overridePathW;
4254 overrideini->GetPath(overridePathW);
4255 NS_ConvertUTF16toUTF8 overridePath(overridePathW);
4256#else
4257 nsAutoCString overridePath;
4258 overrideini->GetNativePath(overridePath);
4259#endif
4260
4261 SaveWordToEnv("MOZ_CRASHREPORTER_STRINGS_OVERRIDE", overridePath);
4262 }
4263 }
4264 } else {
4265 // We might have registered a runtime exception module very early in process
4266 // startup to catch early crashes. This is before we have access to ini file
4267 // data, so unregister here if it turns out the crash reporter is disabled.
4268 CrashReporter::UnregisterRuntimeExceptionModule();
4269 }
4270
4271#if defined(MOZ_SANDBOX1) && defined(XP_WIN)
4272 if (mAppData->sandboxBrokerServices) {
4273 nsAutoString binDirPath;
4274 MOZ_ALWAYS_SUCCEEDS(xreBinDirectory->GetPath(binDirPath))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(xreBinDirectory->GetPath(binDirPath))), 1)))), 1))) { } else
{ do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(xreBinDirectory->GetPath(binDirPath))"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4274); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(xreBinDirectory->GetPath(binDirPath))"
")"); do { *((volatile int*)__null) = 4274; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
4275 SandboxBroker::Initialize(mAppData->sandboxBrokerServices, binDirPath);
4276 } else {
4277# if defined(MOZ_SANDBOX1)
4278 // If we're sandboxing content and we fail to initialize, then crashing here
4279 // seems like the sensible option.
4280 if (BrowserTabsRemoteAutostart()) {
4281 MOZ_CRASH("Failed to initialize broker services, can't continue.")do { do { } while (false); MOZ_ReportCrash("" "Failed to initialize broker services, can't continue."
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4281); AnnotateMozCrashReason("MOZ_CRASH(" "Failed to initialize broker services, can't continue."
")"); do { *((volatile int*)__null) = 4281; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4282 }
4283# endif
4284 // Otherwise just warn for the moment, as most things will work.
4285 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Failed to initialize broker services, sandboxed processes will "
"fail to start.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4287)
4286 "Failed to initialize broker services, sandboxed processes will "NS_DebugBreak(NS_DEBUG_WARNING, "Failed to initialize broker services, sandboxed processes will "
"fail to start.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4287)
4287 "fail to start.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to initialize broker services, sandboxed processes will "
"fail to start.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4287)
;
4288 }
4289#endif
4290
4291#ifdef XP_MACOSX
4292 // Set up ability to respond to system (Apple) events. This must occur before
4293 // ProcessUpdates to ensure that links clicked in external applications aren't
4294 // lost when updates are pending.
4295 SetupMacApplicationDelegate(&gRestartedByOS);
4296
4297 if (EnvHasValue("MOZ_LAUNCHED_CHILD")) {
4298 // This is needed, on relaunch, to force the OS to use the "Cocoa Dock
4299 // API". Otherwise the call to ReceiveNextEvent() below will make it
4300 // use the "Carbon Dock API". For more info see bmo bug 377166.
4301 EnsureUseCocoaDockAPI();
4302
4303 // When the app relaunches, the original process exits. This causes
4304 // the dock tile to stop bouncing, lose the "running" triangle, and
4305 // if the tile does not permanently reside in the Dock, even disappear.
4306 // This can be confusing to the user, who is expecting the app to launch.
4307 // Calling ReceiveNextEvent without requesting any event is enough to
4308 // cause a dock tile for the child process to appear.
4309 const EventTypeSpec kFakeEventList[] = {{INT_MAX2147483647, INT_MAX2147483647}};
4310 EventRef event;
4311 ::ReceiveNextEvent(GetEventTypeCount(kFakeEventList), kFakeEventList,
4312 kEventDurationNoWait, false, &event);
4313 }
4314
4315 if (CheckArg("foreground")) {
4316 // The original process communicates that it was in the foreground by
4317 // adding this argument. This new process, which is taking over for
4318 // the old one, should make itself the active application.
4319 ProcessSerialNumber psn;
4320 if (::GetCurrentProcess(&psn) == noErr) {
4321 ::SetFrontProcess(&psn);
4322 }
4323 }
4324#endif
4325
4326 SaveToEnv("MOZ_LAUNCHED_CHILD=");
4327
4328 // On Windows, the -os-restarted command line switch lets us know when we are
4329 // restarted via RegisterApplicationRestart. May be used for other OSes later.
4330 if (CheckArg("os-restarted", nullptr, CheckArgFlag::RemoveArg) == ARG_FOUND) {
4331 gRestartedByOS = true;
4332 }
4333
4334 gRestartArgc = gArgc;
4335 gRestartArgv =
4336 (char**)malloc(sizeof(char*) * (gArgc + 1 + (override ? 2 : 0)));
4337 if (!gRestartArgv) {
4338 return 1;
4339 }
4340
4341 int i;
4342 for (i = 0; i < gArgc; ++i) {
4343 gRestartArgv[i] = gArgv[i];
4344 }
4345
4346 // Add the -override argument back (it is removed automatically be CheckArg)
4347 // if there is one
4348 if (override) {
4349 gRestartArgv[gRestartArgc++] = const_cast<char*>("-override");
4350 gRestartArgv[gRestartArgc++] = const_cast<char*>(override);
4351 }
4352
4353 gRestartArgv[gRestartArgc] = nullptr;
4354
4355 Maybe<bool> safeModeRequested = IsSafeModeRequested(gArgc, gArgv);
4356 if (!safeModeRequested) {
4357 return 1;
4358 }
4359#ifdef MOZ_BACKGROUNDTASKS1
4360 if (BackgroundTasks::IsBackgroundTaskMode()) {
4361 safeModeRequested = Some(false);
4362
4363 // Remove the --backgroundtask arg now that it has been saved in
4364 // gRestartArgv.
4365 const char* tmpBackgroundTaskName = nullptr;
4366 Unused << CheckArg("backgroundtask", &tmpBackgroundTaskName,
4367 CheckArgFlag::RemoveArg);
4368 }
4369#endif
4370
4371 gSafeMode = safeModeRequested.value();
4372
4373 MaybeAddCPUMicrocodeCrashAnnotation();
4374 CrashReporter::RegisterAnnotationBool(CrashReporter::Annotation::SafeMode,
4375 &gSafeMode);
4376
4377 // Strip the now unsupported no-remote command line argument.
4378 CheckArg("no-remote");
4379
4380#if defined(MOZ_HAS_REMOTE1)
4381 // Handle the --new-instance command line arguments.
4382 ar = CheckArg("new-instance");
4383 if (ar == ARG_FOUND || EnvHasValue("MOZ_NEW_INSTANCE")) {
4384 mDisableRemoteClient = true;
4385 }
4386#else
4387 // These arguments do nothing in platforms with no remoting support but we
4388 // should remove them from the command line anyway.
4389 CheckArg("new-instance");
4390#endif
4391
4392 ar = CheckArg("offline");
4393 if (ar || EnvHasValue("XRE_START_OFFLINE")) {
4394 mStartOffline = true;
4395 }
4396
4397 const char* origin = nullptr;
4398 if (!PR_GetEnv("MOZ_FORCE_QUIC_ON") &&
4399 ARG_FOUND == CheckArg("origin-to-force-quic-on", &origin,
4400 CheckArgFlag::RemoveArg)) {
4401 mOriginToForceQUIC.Assign(origin);
4402 }
4403
4404 // On Windows, to get working console arrangements so help/version/etc
4405 // print something, we need to initialize the native app support.
4406 rv = NS_CreateNativeAppSupport(getter_AddRefs(mNativeApp));
4407 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return 1;
4408
4409 // Handle --help, --full-version and --version command line arguments.
4410 // They should return quickly, so we deal with them here.
4411 if (CheckArg("h") || CheckArg("help") || CheckArg("?")) {
4412 DumpHelp();
4413 *aExitFlag = true;
4414 return 0;
4415 }
4416
4417 if (CheckArg("v") || CheckArg("version")) {
4418 DumpVersion();
4419 *aExitFlag = true;
4420 return 0;
4421 }
4422
4423 if (CheckArg("full-version")) {
4424 DumpFullVersion();
4425 *aExitFlag = true;
4426 return 0;
4427 }
4428
4429#ifdef MOZ_ENABLE_DBUS1
4430 const char* dbusServiceLauncher = nullptr;
4431 ar = CheckArg("dbus-service", &dbusServiceLauncher, CheckArgFlag::None);
4432 if (ar == ARG_BAD) {
4433 Output(true, "Missing launcher param for --dbus-service\n");
4434 return 1;
4435 }
4436 if (ar == ARG_FOUND) {
4437 UniquePtr<DBusService> dbusService =
4438 MakeUnique<DBusService>(dbusServiceLauncher);
4439 if (dbusService->Init()) {
4440 dbusService->Run();
4441 }
4442 *aExitFlag = true;
4443 return 0;
4444 }
4445#endif
4446
4447 rv = XRE_InitCommandLine(gArgc, gArgv);
4448 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4448); return 1; } } while (false)
;
4449
4450 return 0;
4451}
4452
4453#if defined(XP_LINUX1) && !defined(ANDROID)
4454
4455static void AnnotateLSBRelease(void*) {
4456 nsCString dist, desc, release, codename;
4457 if (widget::lsb::GetLSBRelease(dist, desc, release, codename)) {
4458 CrashReporter::AppendAppNotesToCrashReport(desc);
4459 }
4460}
4461
4462#endif // defined(XP_LINUX) && !defined(ANDROID)
4463
4464#ifdef XP_WIN
4465static void ReadAheadSystemDll(const wchar_t* dllName) {
4466 wchar_t dllPath[MAX_PATH];
4467 if (ConstructSystem32Path(dllName, dllPath, MAX_PATH)) {
4468 ReadAheadLib(dllPath);
4469 }
4470}
4471
4472static void ReadAheadPackagedDll(const wchar_t* dllName,
4473 const wchar_t* aGREDir) {
4474 wchar_t dllPath[MAX_PATH];
4475 swprintf(dllPath, MAX_PATH, L"%s\\%s", aGREDir, dllName);
4476 ReadAheadLib(dllPath);
4477}
4478
4479static void ReadAheadDlls(const wchar_t* greDir) {
4480 // In Bug 1628903, we investigated which DLLs we should prefetch in
4481 // order to reduce disk I/O and improve startup on Windows machines.
4482 // Our ultimate goal is to measure the impact of these improvements on
4483 // retention (see Bug 1640087). Before we place this within a pref,
4484 // we should ensure this feature only ships to the nightly channel
4485 // and monitor results from that subset.
4486 if (greDir) {
4487 // Prefetch the DLLs shipped with firefox
4488 ReadAheadPackagedDll(L"libegl.dll", greDir);
4489 ReadAheadPackagedDll(L"libGLESv2.dll", greDir);
4490 ReadAheadPackagedDll(L"nssckbi.dll", greDir);
4491 ReadAheadPackagedDll(L"freebl3.dll", greDir);
4492 ReadAheadPackagedDll(L"softokn3.dll", greDir);
4493
4494 // Prefetch the system DLLs
4495 ReadAheadSystemDll(L"DWrite.dll");
4496 ReadAheadSystemDll(L"D3DCompiler_47.dll");
4497 } else {
4498 // Load DataExchange.dll and twinapi.appcore.dll for
4499 // nsWindow::EnableDragDrop
4500 ReadAheadSystemDll(L"DataExchange.dll");
4501 ReadAheadSystemDll(L"twinapi.appcore.dll");
4502
4503 // Load twinapi.dll for WindowsUIUtils::UpdateTabletModeState
4504 ReadAheadSystemDll(L"twinapi.dll");
4505
4506 // Load explorerframe.dll for WinTaskbar::Initialize
4507 ReadAheadSystemDll(L"ExplorerFrame.dll");
4508
4509 // Load WinTypes.dll for nsOSHelperAppService::GetApplicationDescription
4510 ReadAheadSystemDll(L"WinTypes.dll");
4511 }
4512}
4513#endif
4514
4515#if defined(MOZ_UPDATER1) && !defined(MOZ_WIDGET_ANDROID)
4516enum struct ShouldNotProcessUpdatesReason {
4517 DevToolsLaunching,
4518 NotAnUpdatingTask,
4519 OtherInstanceRunning,
4520 FirstStartup,
4521 MultiSessionInstallLockout
4522};
4523
4524const char* ShouldNotProcessUpdatesReasonAsString(
4525 ShouldNotProcessUpdatesReason aReason) {
4526 switch (aReason) {
4527 case ShouldNotProcessUpdatesReason::DevToolsLaunching:
4528 return "DevToolsLaunching";
4529 case ShouldNotProcessUpdatesReason::NotAnUpdatingTask:
4530 return "NotAnUpdatingTask";
4531 case ShouldNotProcessUpdatesReason::OtherInstanceRunning:
4532 return "OtherInstanceRunning";
4533 case ShouldNotProcessUpdatesReason::FirstStartup:
4534 return "FirstStartup";
4535 case ShouldNotProcessUpdatesReason::MultiSessionInstallLockout:
4536 return "MultiSessionInstallLockout";
4537 default:
4538 MOZ_CRASH("impossible value for ShouldNotProcessUpdatesReason")do { do { } while (false); MOZ_ReportCrash("" "impossible value for ShouldNotProcessUpdatesReason"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4538); AnnotateMozCrashReason("MOZ_CRASH(" "impossible value for ShouldNotProcessUpdatesReason"
")"); do { *((volatile int*)__null) = 4538; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4539 }
4540}
4541
4542Maybe<ShouldNotProcessUpdatesReason> ShouldNotProcessUpdates(
4543 nsXREDirProvider& aDirProvider, nsIFile* aUpdateRoot) {
4544 // Don't process updates when launched from the installer.
4545 // It's possible for a stale update to be present in the case of a paveover;
4546 // ignore it and leave the update service to discard it.
4547 if (ARG_FOUND == CheckArgExists("first-startup")) {
4548 NS_WARNING("ShouldNotProcessUpdates(): FirstStartup")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): FirstStartup"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4548)
;
4549 return Some(ShouldNotProcessUpdatesReason::FirstStartup);
4550 }
4551
4552 // Do not process updates if we're launching devtools, as evidenced by
4553 // "--chrome ..." with the browser toolbox chrome document URL.
4554
4555 // Keep this synchronized with the value of the same name in
4556 // devtools/client/framework/browser-toolbox/Launcher.sys.mjs. Or, for bonus
4557 // points, lift this value to nsIXulRuntime or similar, so that it can be
4558 // accessed in both locations. (The prefs service isn't available at this
4559 // point so the simplest manner of sharing the value is not available to us.)
4560 const char* BROWSER_TOOLBOX_WINDOW_URL =
4561 "chrome://devtools/content/framework/browser-toolbox/window.html";
4562
4563 const char* chromeParam = nullptr;
4564 if (ARG_FOUND == CheckArg("chrome", &chromeParam, CheckArgFlag::None)) {
4565 if (!chromeParam || !strcmp(BROWSER_TOOLBOX_WINDOW_URL, chromeParam)) {
4566 NS_WARNING("ShouldNotProcessUpdates(): DevToolsLaunching")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): DevToolsLaunching"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4566)
;
4567 return Some(ShouldNotProcessUpdatesReason::DevToolsLaunching);
4568 }
4569 }
4570
4571 bool otherInstance = false;
4572 // At this point we have a dir provider but no XPCOM directory service. We
4573 // launch the update sync manager using that information so that it doesn't
4574 // need to ask for (and fail to find) the directory service.
4575 nsCOMPtr<nsIFile> anAppFile;
4576 bool persistent;
4577 nsresult rv = aDirProvider.GetFile(XRE_EXECUTABLE_FILE"XREExeF", &persistent,
4578 getter_AddRefs(anAppFile));
4579 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && anAppFile) {
4580 auto updateSyncManager = new nsUpdateSyncManager(anAppFile);
4581 rv = updateSyncManager->IsOtherInstanceRunning(&otherInstance);
4582 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4583 // Unless we know that there is another instance, we default to assuming
4584 // there is not one.
4585 otherInstance = false;
4586 }
4587 }
4588
4589 if (otherInstance) {
4590 bool msilActive = false;
4591 rv = IsMultiSessionInstallLockoutActive(aUpdateRoot, msilActive);
4592 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && msilActive) {
4593 NS_WARNING("ShouldNotProcessUpdates(): MultiSessionInstallLockout")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): MultiSessionInstallLockout"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4593)
;
4594 return Some(ShouldNotProcessUpdatesReason::MultiSessionInstallLockout);
4595 }
4596 }
4597
4598# ifdef MOZ_BACKGROUNDTASKS1
4599 // Do not process updates if we're running a background task mode and another
4600 // instance is already running. This avoids periodic maintenance updating
4601 // underneath a browsing session.
4602 Maybe<nsCString> backgroundTasks = BackgroundTasks::GetBackgroundTasks();
4603 if (backgroundTasks.isSome()) {
4604 // Only process updates for specific tasks: at this time, the
4605 // `backgroundupdate` task and the test-only `shouldprocessupdates` task.
4606 //
4607 // Background tasks can be sparked by Firefox instances that are shutting
4608 // down, which can cause races between the task startup trying to update and
4609 // Firefox trying to invoke the updater. This happened when converting
4610 // `pingsender` to a background task, since it is launched to send pings at
4611 // shutdown: Bug 1736373.
4612 //
4613 // We'd prefer to have this be a property of the task definition sibling to
4614 // `backgroundTaskTimeoutSec`, but when we reach this code we're well before
4615 // we can load the task JSM.
4616 if (!BackgroundTasks::IsUpdatingTaskName(backgroundTasks.ref())) {
4617 NS_WARNING("ShouldNotProcessUpdates(): NotAnUpdatingTask")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): NotAnUpdatingTask"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4617)
;
4618 return Some(ShouldNotProcessUpdatesReason::NotAnUpdatingTask);
4619 }
4620
4621 if (otherInstance) {
4622 NS_WARNING("ShouldNotProcessUpdates(): OtherInstanceRunning")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): OtherInstanceRunning"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4622)
;
4623 return Some(ShouldNotProcessUpdatesReason::OtherInstanceRunning);
4624 }
4625 }
4626# endif
4627
4628 return Nothing();
4629}
4630#endif
4631
4632namespace mozilla::startup {
4633Result<nsCOMPtr<nsIFile>, nsresult> GetIncompleteStartupFile(nsIFile* aProfLD) {
4634 nsCOMPtr<nsIFile> crashFile;
4635 MOZ_TRY(aProfLD->Clone(getter_AddRefs(crashFile)))do { auto mozTryTempResult_ = ::mozilla::ToResult(aProfLD->
Clone(getter_AddRefs(crashFile))); if ((__builtin_expect(!!(mozTryTempResult_
.isErr()), 0))) { return mozTryTempResult_.propagateErr(); } }
while (0)
;
4636 MOZ_TRY(crashFile->Append(FILE_STARTUP_INCOMPLETE))do { auto mozTryTempResult_ = ::mozilla::ToResult(crashFile->
Append(u".startup-incomplete"_ns)); if ((__builtin_expect(!!(
mozTryTempResult_.isErr()), 0))) { return mozTryTempResult_.propagateErr
(); } } while (0)
;
4637 return std::move(crashFile);
4638}
4639} // namespace mozilla::startup
4640
4641// Check whether the last startup attempt resulted in a crash or hang.
4642// This is distinct from the definition of a startup crash from
4643// nsAppStartup::TrackStartupCrashBegin.
4644bool XREMain::CheckLastStartupWasCrash() {
4645 Result<nsCOMPtr<nsIFile>, nsresult> crashFile =
4646 GetIncompleteStartupFile(mProfLD);
4647 if (crashFile.isErr()) {
4648 return true;
4649 }
4650
4651 // Attempt to create the incomplete startup canary file. If the file already
4652 // exists, this fails, and we know the last startup was a crash. If it
4653 // doesn't already exist, it is created, and will be removed at the end of
4654 // the startup crash detection window.
4655 AutoFDClose fd;
4656 Unused << crashFile.inspect()->OpenNSPRFileDesc(
4657 PR_WRONLY0x02 | PR_CREATE_FILE0x08 | PR_EXCL0x80, 0666, getter_Transfers(fd));
4658 return !fd;
4659}
4660
4661/*
4662 * XRE_mainStartup - Initializes the profile and various other services.
4663 * Main() will exit early if either return value != 0 or if aExitFlag is
4664 * true.
4665 */
4666int XREMain::XRE_mainStartup(bool* aExitFlag) {
4667 nsresult rv;
4668
4669 if (!aExitFlag) return 1;
4670 *aExitFlag = false;
4671
4672#ifdef XP_MACOSX
4673 mozilla::MacAutoreleasePool pool;
4674#endif
4675
4676 // Enable Telemetry IO Reporting on DEBUG, nightly and local builds,
4677 // but disable it on FUZZING builds and for ANDROID.
4678#ifndef FUZZING
4679# ifndef ANDROID
4680# ifdef DEBUG1
4681 mozilla::Telemetry::InitIOReporting(gAppData->xreDirectory);
4682# else
4683 {
4684 const char* releaseChannel = MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default";
4685 if (strcmp(releaseChannel, "nightly") == 0 ||
4686 strcmp(releaseChannel, "default") == 0) {
4687 mozilla::Telemetry::InitIOReporting(gAppData->xreDirectory);
4688 }
4689 }
4690# endif /* DEBUG */
4691# endif /* ANDROID */
4692#endif /* FUZZING */
4693
4694#if defined(XP_WIN)
4695 // Enable the HeapEnableTerminationOnCorruption exploit mitigation. We ignore
4696 // the return code because it always returns success, although it has no
4697 // effect on Windows older than XP SP3.
4698 HeapSetInformation(NULL__null, HeapEnableTerminationOnCorruption, NULL__null, 0);
4699#endif /* XP_WIN */
4700
4701#ifdef MOZ_WIDGET_GTK1
4702 // Stash startup token in owned memory because gtk_init will clear
4703 // DESKTOP_STARTUP_ID it.
4704 if (const char* v = PR_GetEnv("DESKTOP_STARTUP_ID")) {
4705 mDesktopStartupID.Assign(v);
4706 }
4707 if (const char* v = PR_GetEnv("XDG_ACTIVATION_TOKEN")) {
4708 mXDGActivationToken.Assign(v);
4709 }
4710#endif
4711
4712#if defined(XP_WIN)
4713 {
4714 // Save the shortcut path before lpTitle is replaced by an AUMID,
4715 // such as by WinTaskbar
4716 STARTUPINFOW si;
4717 GetStartupInfoW(&si);
4718 if (si.dwFlags & STARTF_TITLEISAPPID) {
4719 NS_WARNING("AUMID was already set, shortcut may have been lost.")NS_DebugBreak(NS_DEBUG_WARNING, "AUMID was already set, shortcut may have been lost."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4719)
;
4720 } else if ((si.dwFlags & STARTF_TITLEISLINKNAME) && si.lpTitle) {
4721 gProcessStartupShortcut.Assign(si.lpTitle);
4722 }
4723 }
4724#endif /* XP_WIN */
4725
4726#if defined(MOZ_WIDGET_GTK1)
4727 // setup for private colormap. Ideally we'd like to do this
4728 // in nsAppShell::Create, but we need to get in before gtk
4729 // has been initialized to make sure everything is running
4730 // consistently.
4731
4732 // Set program name to the one defined in application.ini.
4733 g_set_prgname(gAppData->remotingName);
4734
4735 // Initialize GTK here for splash.
4736
4737# if defined(MOZ_WIDGET_GTK1) && defined(MOZ_X111)
4738 // Disable XInput2 multidevice support due to focus bugginess.
4739 // See bugs 1182700, 1170342.
4740 // gdk_disable_multidevice() affects Gdk X11 backend only,
4741 // the multidevice support is always enabled on Wayland backend.
4742 const char* useXI2 = PR_GetEnv("MOZ_USE_XINPUT2");
4743 if (!useXI2 || (*useXI2 == '0')) gdk_disable_multidevice();
4744# endif
4745
4746 // Open the display ourselves instead of using gtk_init, so that we can
4747 // close it without fear that one day gtk might clean up the display it
4748 // opens.
4749 if (!gtk_parse_args(&gArgc, &gArgv)) return 1;
4750#endif /* MOZ_WIDGET_GTK */
4751
4752#ifdef FUZZING
4753 if (PR_GetEnv("FUZZER")) {
4754 *aExitFlag = true;
4755 return mozilla::fuzzerRunner->Run(&gArgc, &gArgv);
4756 }
4757#endif
4758
4759 if (PR_GetEnv("MOZ_RUN_GTEST")) {
4760 int result;
4761#ifdef XP_WIN
4762 UseParentConsole();
4763#endif
4764 // RunGTest will only be set if we're in xul-unit
4765 if (mozilla::RunGTest) {
4766 gIsGtest = true;
4767 result = mozilla::RunGTest(&gArgc, gArgv);
4768 gIsGtest = false;
4769 } else {
4770 result = 1;
4771 printf("TEST-UNEXPECTED-FAIL | gtest | Not compiled with enable-tests\n");
4772 }
4773 *aExitFlag = true;
4774 return result;
4775 }
4776
4777 bool isBackgroundTaskMode = false;
4778#ifdef MOZ_BACKGROUNDTASKS1
4779 isBackgroundTaskMode = BackgroundTasks::IsBackgroundTaskMode();
4780#endif
4781
4782#ifdef MOZ_HAS_REMOTE1
4783 if (gfxPlatform::IsHeadless()) {
4784 mDisableRemoteClient = true;
4785 }
4786#endif
4787
4788#ifdef MOZ_X111
4789 // Init X11 in thread-safe mode. Must be called prior to the first call to
4790 // XOpenDisplay (called inside gdk_display_open). This is a requirement for
4791 // off main tread compositing.
4792 if (!isBackgroundTaskMode && !gfxPlatform::IsHeadless()) {
4793 XInitThreads();
4794 }
4795#endif
4796#if defined(MOZ_WIDGET_GTK1)
4797 if (!isBackgroundTaskMode && !gfxPlatform::IsHeadless()) {
4798 const char* display_name = nullptr;
4799 bool saveDisplayArg = false;
4800
4801 // display_name is owned by gdk.
4802 display_name = gdk_get_display_arg_name();
4803 bool waylandEnabled = IsWaylandEnabled();
4804# ifdef MOZ_WAYLAND1
4805 if (!display_name) {
4806 auto* proxyEnv = getenv("MOZ_DISABLE_WAYLAND_PROXY");
4807 bool disableWaylandProxy = proxyEnv && *proxyEnv;
4808 if (!disableWaylandProxy && XRE_IsParentProcess() && waylandEnabled) {
4809 auto* proxyLog = getenv("WAYLAND_PROXY_LOG");
4810 WaylandProxy::SetVerbose(proxyLog && *proxyLog);
4811 WaylandProxy::SetCompositorCrashHandler(WlCompositorCrashHandler);
4812 WaylandProxy::AddState(WAYLAND_PROXY_ENABLED(1 << 0));
4813 gWaylandProxy = WaylandProxy::Create();
4814 if (gWaylandProxy) {
4815 if (!gWaylandProxy->RunThread()) {
4816 Output(true, "Failed to run Wayland proxy\n");
4817 }
4818 }
4819 } else {
4820 WaylandProxy::AddState(WAYLAND_PROXY_DISABLED(1 << 1));
4821 }
4822 }
4823# endif
4824
4825 // if --display argument is given make sure it's
4826 // also passed to ContentChild::Init() by MOZ_GDK_DISPLAY.
4827 if (display_name) {
4828 SaveWordToEnv("MOZ_GDK_DISPLAY", nsDependentCString(display_name));
4829 saveDisplayArg = true;
4830 }
4831
4832 // On Wayland disabled builds read X11 DISPLAY env exclusively
4833 // and don't care about different displays.
4834 if (!waylandEnabled && !display_name) {
4835 display_name = PR_GetEnv("DISPLAY");
4836 if (!display_name) {
4837 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
4838 "Error: no DISPLAY environment variable specified\n");
4839 return 1;
4840 }
4841 }
4842
4843 if (display_name) {
4844 GdkDisplay* disp = gdk_display_open(display_name);
4845 if (!disp) {
4846 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Error: cannot open display: %s\n", display_name);
4847 return 1;
4848 }
4849 if (saveDisplayArg) {
4850 if (GdkIsX11Display(disp)) {
4851 SaveWordToEnv("DISPLAY", nsDependentCString(display_name));
4852 } else if (GdkIsWaylandDisplay(disp)) {
4853 SaveWordToEnv("WAYLAND_DISPLAY", nsDependentCString(display_name));
4854 }
4855 }
4856 } else {
4857 gdk_display_manager_open_display(gdk_display_manager_get(), nullptr);
4858 }
4859# if defined(MOZ_WAYLAND1)
4860 // We want to use proxy for main connection only so
4861 // restore original Wayland display for next potential Wayland connections
4862 // from gfx probe code and so on.
4863 if (gWaylandProxy) {
4864 gWaylandProxy->RestoreWaylandDisplay();
4865 }
4866 if (waylandEnabled && PR_GetEnv("WAYLAND_DISPLAY") && GdkIsX11Display()) {
4867 // Gtk somehow switched to X11 display but we want Wayland.
4868 // It may happen if compositor response is missig or it's slow
4869 // or WAYLAND_DISPLAY is wrong. In such case throw warning but
4870 // run with X11.
4871 Output(true,
4872 "Error: Failed to open Wayland display, fallback to X11. "
4873 "WAYLAND_DISPLAY='%s' DISPLAY='%s'\n",
4874 PR_GetEnv("WAYLAND_DISPLAY"), PR_GetEnv("DISPLAY"));
4875
4876 // We need to unset WAYLAND_DISPLAY. Gfx probe code doesn't have fallback
4877 // to X11 and we'll end with Browser running SW rendering only then.
4878 g_unsetenv("WAYLAND_DISPLAY");
4879 gWaylandProxy = nullptr;
4880 }
4881# endif
4882 if (!gdk_display_get_default()) {
4883 Output(true,
4884 "Error: we don't have any display, WAYLAND_DISPLAY='%s' "
4885 "DISPLAY='%s'\n",
4886 PR_GetEnv("WAYLAND_DISPLAY"), PR_GetEnv("DISPLAY"));
4887 return 1;
4888 }
4889 // Check that Wayland only and X11 only builds
4890 // use appropriate displays.
4891# if defined(MOZ_WAYLAND1) && !defined(MOZ_X111)
4892 if (!GdkIsWaylandDisplay()) {
4893 Output(true, "Wayland only build is missig Wayland display!\n");
4894 return 1;
4895 }
4896# endif
4897# if !defined(MOZ_WAYLAND1) && defined(MOZ_X111)
4898 if (!GdkIsX11Display()) {
4899 Output(true, "X11 only build is missig X11 display!\n");
4900 return 1;
4901 }
4902# endif
4903 }
4904#endif
4905#if defined(MOZ_HAS_REMOTE1)
4906 // handle --remote now that xpcom is fired up
4907 gRemoteService = new nsRemoteService();
4908 if (gRemoteService) {
4909 gRemoteService->SetProgram(gAppData->remotingName);
4910 gStartupLock = gRemoteService->LockStartup();
4911 if (!gStartupLock) {
4912 NS_WARNING("Failed to lock for startup, continuing anyway.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to lock for startup, continuing anyway."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4912)
;
4913 }
4914 }
4915#endif
4916#if defined(MOZ_WIDGET_GTK1)
4917 g_set_application_name(mAppData->name);
4918
4919#endif /* defined(MOZ_WIDGET_GTK) */
4920#ifdef MOZ_X111
4921 // Do this after initializing GDK, or GDK will install its own handler.
4922 XRE_InstallX11ErrorHandler();
4923#endif
4924
4925 bool canRun = false;
4926 rv = mNativeApp->Start(&canRun);
4927 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !canRun) {
4928 return 1;
4929 }
4930
4931#ifdef MOZ_WIDGET_GTK1
4932 // startup token might be cleared now, we recover it in case we need a
4933 // restart.
4934 if (!mDesktopStartupID.IsEmpty()) {
4935 // Leak it with extreme prejudice!
4936 PR_SetEnv(ToNewCString("DESKTOP_STARTUP_ID="_ns + mDesktopStartupID));
4937 }
4938
4939 if (!mXDGActivationToken.IsEmpty()) {
4940 // Leak it with extreme prejudice!
4941 PR_SetEnv(ToNewCString("XDG_ACTIVATION_TOKEN="_ns + mXDGActivationToken));
4942 }
4943#endif
4944
4945 // Support exiting early for testing startup sequence. Bug 1360493
4946 if (CheckArg("test-launch-without-hang")) {
4947 *aExitFlag = true;
4948 return 0;
4949 }
4950
4951 mProfileSvc = NS_GetToolkitProfileService();
4952 if (!mProfileSvc) {
4953 // We failed to choose or create profile - notify user and quit
4954 ProfileMissingDialog(mNativeApp);
4955 return 1;
4956 }
4957
4958 bool wasDefaultSelection;
4959 nsCOMPtr<nsIToolkitProfile> profile;
4960 rv = SelectProfile(mProfileSvc, mNativeApp, getter_AddRefs(mProfD),
4961 getter_AddRefs(mProfLD), getter_AddRefs(profile),
4962 &wasDefaultSelection);
4963 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
4964 *aExitFlag = true;
4965 return 0;
4966 }
4967
4968 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4969 // We failed to choose or create profile - notify user and quit
4970 ProfileMissingDialog(mNativeApp);
4971 return 1;
4972 }
4973
4974#if defined(MOZ_HAS_REMOTE1)
4975 if (gRemoteService) {
4976 // Use the full profile path to identify the profile.
4977 nsCString profilePath;
4978
4979# ifdef XP_WIN
4980 nsString path;
4981 rv = mProfD->GetPath(path);
4982 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4983 CopyUTF16toUTF8(path, profilePath);
4984 }
4985# else
4986 rv = mProfD->GetNativePath(profilePath);
4987# endif
4988
4989 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4990 gRemoteService->SetProfile(profilePath);
4991
4992 if (!mDisableRemoteClient) {
4993 // Try to remote the entire command line. If this fails, start up
4994 // normally.
4995# ifdef MOZ_WIDGET_GTK1
4996 auto& startupToken =
4997 GdkIsWaylandDisplay() ? mXDGActivationToken : mDesktopStartupID;
4998# ifdef MOZ_X111
4999 if (GdkIsX11Display() && startupToken.IsEmpty()) {
5000 startupToken = SynthesizeStartupToken();
5001 }
5002# endif /* MOZ_X11 */
5003 gRemoteService->SetStartupToken(startupToken);
5004# endif
5005 rv = gRemoteService->StartClient();
5006
5007 if (rv == NS_ERROR_NOT_AVAILABLE && profile) {
5008 // Older versions would use the profile name in preference to the
5009 // path.
5010 nsCString profileName;
5011 profile->GetName(profileName);
5012 gRemoteService->SetProfile(profileName);
5013
5014 rv = gRemoteService->StartClient();
5015
5016 // Reset back to the path.
5017 gRemoteService->SetProfile(profilePath);
5018 }
5019
5020 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5021 *aExitFlag = true;
5022 gStartupLock = nullptr;
5023 return 0;
5024 }
5025
5026 if (rv == NS_ERROR_INVALID_ARG) {
5027 gStartupLock = nullptr;
5028 return 1;
5029 }
5030 }
5031 }
5032 }
5033#endif /* MOZ_HAS_REMOTE */
5034
5035#if defined(MOZ_UPDATER1) && !defined(MOZ_WIDGET_ANDROID)
5036# ifdef XP_WIN
5037 {
5038 // When automatically restarting for a staged background update
5039 // we want the child process to wait here so that the updater
5040 // does not register two instances running and use that as a
5041 // reason to not process updates. This function requires having
5042 // -restart-pid <param> in the command line to function properly.
5043 // Ensure we keep -restart-pid if we are running tests
5044 if (ARG_FOUND == CheckArgExists("restart-pid") &&
5045 !CheckArg("test-only-automatic-restart-no-wait")) {
5046 // We're not testing and can safely remove it now and read the pid.
5047 const char* restartPidString = nullptr;
5048 CheckArg("restart-pid", &restartPidString, CheckArgFlag::RemoveArg);
5049 // pid should be first parameter following -restart-pid.
5050 uint32_t pid = nsDependentCString(restartPidString).ToInteger(&rv, 10U);
5051 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && pid > 0) {
5052 printf_stderr(
5053 "*** MaybeWaitForProcessExit: launched pidDWORD = %u ***\n", pid);
5054 RefPtr<nsUpdateProcessor> updater = new nsUpdateProcessor();
5055 if (NS_FAILED(((bool)(__builtin_expect(!!(NS_FAILED_impl(updater->WaitForProcessExit
(pid, MAYBE_WAIT_TIMEOUT_MS))), 0)))
5056 updater->WaitForProcessExit(pid, MAYBE_WAIT_TIMEOUT_MS))((bool)(__builtin_expect(!!(NS_FAILED_impl(updater->WaitForProcessExit
(pid, MAYBE_WAIT_TIMEOUT_MS))), 0)))
) {
5057 NS_WARNING("Failed to MaybeWaitForProcessExit.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to MaybeWaitForProcessExit."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5057)
;
5058 }
5059 } else {
5060 NS_WARNING("Failed to parse pid from -restart-pid.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to parse pid from -restart-pid."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5060)
;
5061 }
5062 }
5063 }
5064# endif
5065 // Check for and process any available updates
5066 nsCOMPtr<nsIFile> updRoot;
5067 bool persistent;
5068 rv = mDirProvider.GetFile(XRE_UPDATE_ROOT_DIR"UpdRootD", &persistent,
5069 getter_AddRefs(updRoot));
5070 // XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed
5071 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5072 updRoot = mDirProvider.GetAppDir();
5073 }
5074
5075 Maybe<ShouldNotProcessUpdatesReason> shouldNotProcessUpdatesReason =
5076 ShouldNotProcessUpdates(mDirProvider, updRoot);
5077 if (shouldNotProcessUpdatesReason.isNothing()) {
5078 nsCOMPtr<nsIFile> exeFile, exeDir;
5079 rv = mDirProvider.GetFile(XRE_EXECUTABLE_FILE"XREExeF", &persistent,
5080 getter_AddRefs(exeFile));
5081 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5081); return 1; } } while (false)
;
5082 rv = exeFile->GetParent(getter_AddRefs(exeDir));
5083 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5083); return 1; } } while (false)
;
5084 ProcessUpdates(mDirProvider.GetGREDir(), exeDir, updRoot, gRestartArgc,
5085 gRestartArgv, mAppData->version);
5086 } else {
5087 if (CheckArg("test-should-not-process-updates") ||
5088 EnvHasValue("MOZ_TEST_SHOULD_NOT_PROCESS_UPDATES")) {
5089 // Support for testing *not* processing an update. The launched process
5090 // can witness this environment variable and conclude that its runtime
5091 // environment resulted in not processing updates.
5092
5093 SaveToEnv(nsPrintfCString("MOZ_TEST_SHOULD_NOT_PROCESS_UPDATES="
5094 "ShouldNotProcessUpdates(): %s",
5095 ShouldNotProcessUpdatesReasonAsString(
5096 shouldNotProcessUpdatesReason.value()))
5097 .get());
5098 }
5099 }
5100 if (CheckArg("test-process-updates") ||
5101 EnvHasValue("MOZ_TEST_PROCESS_UPDATES")) {
5102 SaveToEnv("MOZ_TEST_PROCESS_UPDATES=");
5103
5104 // If the caller has asked us to log our arguments, do so. This is used
5105 // to make sure that the maintenance service successfully launches the
5106 // callback application.
5107 const char* logFile = nullptr;
5108 if (ARG_FOUND == CheckArg("dump-args", &logFile)) {
5109 FILE* logFP = fopen(logFile, "wb");
5110 if (logFP) {
5111 for (int i = 1; i < gRestartArgc; ++i) {
5112 fprintf(logFP, "%s\n", gRestartArgv[i]);
5113 }
5114 fclose(logFP);
5115 }
5116 }
5117
5118 // Tests may want to know when we are done. We are about to exit, so we are
5119 // done here. Write out a file to indicate this to the caller.
5120 WriteUpdateCompleteTestFile(updRoot);
5121
5122 *aExitFlag = true;
5123 return 0;
5124 }
5125#endif
5126
5127 // We now know there is no existing instance using the selected profile.
5128
5129 // We only ever show the profile selector if a specific profile wasn't chosen
5130 // via command line arguments or environment variables.
5131 if (wasDefaultSelection) {
5132 if (!mProfileSvc->GetStartWithLastProfile()) {
5133 // First check the old style profile manager
5134 rv = ShowProfileManager(mProfileSvc, mNativeApp);
5135 } else if (profile && profile->GetShowProfileSelector()) {
5136 // Now check the new profile group selector
5137 rv = ShowProfileSelector(mProfileSvc, mNativeApp);
5138 } else {
5139 rv = NS_OK;
5140 }
5141
5142 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5143 *aExitFlag = true;
5144 return 0;
5145 }
5146
5147 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5148 return 1;
5149 }
5150 }
5151
5152 // We always want to lock the profile even if we're actually going to reset
5153 // it later.
5154 rv = LockProfile(mNativeApp, mProfD, mProfLD, profile,
5155 getter_AddRefs(mProfileLock));
5156 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5157 *aExitFlag = true;
5158 return 0;
5159 }
5160 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5161 return 1;
5162 }
5163
5164 if (gDoProfileReset) {
5165 if (!EnvHasValue("MOZ_RESET_PROFILE_RESTART")) {
5166 if (ARG_FOUND == CheckArgExists("first-startup")) {
5167 // If the profile reset was initiated by the stub installer, we want to
5168 // set MOZ_RESET_PROFILE_SESSION so we can check for it later when the
5169 // Firefox Profile Migrator runs. At that point we set overrides to
5170 // ensure users see the right homepage.
5171 SaveToEnv("MOZ_RESET_PROFILE_SESSION=0");
5172 } else if (gDoMigration) {
5173 // Otherwise this is a profile reset and migration triggered via the
5174 // command line during development and we want to restore the session
5175 // and perform the approriate homepage overrides.
5176 SaveToEnv("MOZ_RESET_PROFILE_SESSION=1");
5177 }
5178 } else {
5179 // If the profile reset was initiated by the user, such as through
5180 // about:support, we want to restore their session.
5181 SaveToEnv("MOZ_RESET_PROFILE_SESSION=1");
5182 SaveToEnv("MOZ_RESET_PROFILE_RESTART=");
5183 }
5184 // Unlock the source profile.
5185 mProfileLock->Unlock();
5186
5187 // If we're resetting a profile, create a new one and use it to startup.
5188 gResetOldProfile = profile;
5189 rv = mProfileSvc->CreateResetProfile(getter_AddRefs(profile));
5190 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5191 rv = profile->GetRootDir(getter_AddRefs(mProfD));
5192 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5192); return 1; } } while (false)
;
5193 SaveFileToEnv("XRE_PROFILE_PATH", mProfD);
5194
5195 rv = profile->GetLocalDir(getter_AddRefs(mProfLD));
5196 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5196); return 1; } } while (false)
;
5197 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", mProfLD);
5198
5199 // Lock the new profile
5200 rv = LockProfile(mNativeApp, mProfD, mProfLD, profile,
5201 getter_AddRefs(mProfileLock));
5202 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5203 *aExitFlag = true;
5204 return 0;
5205 }
5206 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5207 return 1;
5208 }
5209 } else {
5210 NS_WARNING("Profile reset failed.")NS_DebugBreak(NS_DEBUG_WARNING, "Profile reset failed.", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5210)
;
5211 return 1;
5212 }
5213 }
5214
5215 gProfileLock = mProfileLock;
5216
5217 nsAutoCString version;
5218 BuildVersion(version);
5219
5220#ifdef TARGET_OS_ABI"Linux_x86_64-gcc3"
5221 constexpr auto osABI = nsLiteralCString{TARGET_OS_ABI"Linux_x86_64-gcc3"};
5222#else
5223 // No TARGET_XPCOM_ABI, but at least the OS is known
5224 constexpr auto osABI = nsLiteralCString{OS_TARGET"Linux" "_UNKNOWN"};
5225#endif
5226
5227 // Check for version compatibility with the last version of the app this
5228 // profile was started with. The format of the version stamp is defined
5229 // by the BuildVersion function.
5230 // Also check to see if something has happened to invalidate our
5231 // fastload caches, like an app upgrade.
5232
5233 // If we see .purgecaches, that means someone did a make.
5234 // Re-register components to catch potential changes.
5235 nsCOMPtr<nsIFile> flagFile;
5236 if (mAppData->directory) {
5237 Unused << mAppData->directory->Clone(getter_AddRefs(flagFile));
5238 }
5239 if (flagFile) {
5240 flagFile->AppendNative(FILE_INVALIDATE_CACHES".purgecaches"_ns);
5241 }
5242
5243 bool cachesOK;
5244 bool isDowngrade;
5245 nsCString lastVersion;
5246 bool versionOK = CheckCompatibility(
5247 mProfD, version, osABI, mDirProvider.GetGREDir(), mAppData->directory,
5248 flagFile, &cachesOK, &isDowngrade, lastVersion);
5249
5250 MOZ_RELEASE_ASSERT(!cachesOK || lastVersion.Equals(version),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!cachesOK || lastVersion.Equals(version))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!cachesOK || lastVersion.Equals(version)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!cachesOK || lastVersion.Equals(version)"
" (" "Caches cannot be good if the version has changed." ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5251); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!cachesOK || lastVersion.Equals(version)"
") (" "Caches cannot be good if the version has changed." ")"
); do { *((volatile int*)__null) = 5251; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5251 "Caches cannot be good if the version has changed.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!cachesOK || lastVersion.Equals(version))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!cachesOK || lastVersion.Equals(version)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!cachesOK || lastVersion.Equals(version)"
" (" "Caches cannot be good if the version has changed." ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5251); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!cachesOK || lastVersion.Equals(version)"
") (" "Caches cannot be good if the version has changed." ")"
); do { *((volatile int*)__null) = 5251; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5252
5253#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE1
5254 // The argument check must come first so the argument is always removed from
5255 // the command line regardless of whether this is a downgrade or not.
5256 if (!CheckArg("allow-downgrade") && isDowngrade &&
5257 !EnvHasValue("MOZ_ALLOW_DOWNGRADE")) {
5258# ifdef XP_MACOSX
5259 InitializeMacApp();
5260# endif
5261 rv = CheckDowngrade(mProfD, mNativeApp, mProfileSvc, lastVersion);
5262 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5263 *aExitFlag = true;
5264 return 0;
5265 }
5266 }
5267#endif
5268
5269 rv = mDirProvider.SetProfile(mProfD, mProfLD);
5270 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5270); return 1; } } while (false)
;
5271
5272 //////////////////////// NOW WE HAVE A PROFILE ////////////////////////
5273
5274 mozilla::Telemetry::SetProfileDir(mProfD);
5275
5276 if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER(1 << 3)) {
5277 MakeOrSetMinidumpPath(mProfD);
5278 }
5279
5280 CrashReporter::SetProfileDirectory(mProfD);
5281
5282#ifdef MOZ_ASAN_REPORTER
5283 // In ASan reporter builds, we need to set ASan's log_path as early as
5284 // possible, so it dumps its errors into files there instead of using
5285 // the default stderr location. Since this is crucial for ASan reporter
5286 // to work at all (and we don't want people to use a non-functional
5287 // ASan reporter build), all failures while setting log_path are fatal.
5288 setASanReporterPath(mProfD);
5289
5290 // Export to env for child processes
5291 SaveFileToEnv("ASAN_REPORTER_PATH", mProfD);
5292#endif
5293
5294 bool lastStartupWasCrash = CheckLastStartupWasCrash();
5295
5296 CrashReporter::RecordAnnotationBool(
5297 CrashReporter::Annotation::LastStartupWasCrash, lastStartupWasCrash);
5298
5299 if (CheckArg("purgecaches") || PR_GetEnv("MOZ_PURGE_CACHES") ||
5300 lastStartupWasCrash || gSafeMode) {
5301 cachesOK = false;
5302 }
5303
5304 CrashReporter::RecordAnnotationBool(
5305 CrashReporter::Annotation::StartupCacheValid, cachesOK && versionOK);
5306
5307#if defined(MOZ_UPDATER1) && !defined(MOZ_WIDGET_ANDROID)
5308 if (shouldNotProcessUpdatesReason) {
5309 nsDependentCString skipStartupReason(ShouldNotProcessUpdatesReasonAsString(
5310 shouldNotProcessUpdatesReason.value()));
5311 mozilla::glean::update::skip_startup_update_reason.Get(skipStartupReason)
5312 .Add(1);
5313 } else {
5314 mozilla::glean::update::skip_startup_update_reason.Get("none"_ns).Add(1);
5315 }
5316#endif
5317
5318 // Every time a profile is loaded by a build with a different version,
5319 // it updates the compatibility.ini file saying what version last wrote
5320 // the fastload caches. On subsequent launches if the version matches,
5321 // there is no need for re-registration. If the user loads the same
5322 // profile in different builds the component registry must be
5323 // re-generated to prevent mysterious component loading failures.
5324 //
5325 bool startupCacheValid = true;
5326
5327 if (!cachesOK || !versionOK) {
5328 QuotaManager::InvalidateQuotaCache();
5329
5330 startupCacheValid = RemoveComponentRegistries(mProfD, mProfLD, false);
5331
5332 // Rewrite compatibility.ini to match the current build. The next run
5333 // should attempt to invalidate the caches if either this run is safe mode
5334 // or the attempt to invalidate the caches this time failed.
5335 WriteVersion(mProfD, version, osABI, mDirProvider.GetGREDir(),
5336 mAppData->directory, gSafeMode || !startupCacheValid);
5337 }
5338
5339 if (!startupCacheValid) StartupCache::IgnoreDiskCache();
5340
5341 if (flagFile) {
5342 flagFile->Remove(true);
5343 }
5344
5345 // Flush any pending page load events.
5346 mozilla::glean_pings::Pageload.Submit("startup"_ns);
5347
5348 if (!isBackgroundTaskMode) {
5349#ifdef USE_GLX_TEST1
5350 GfxInfo::FireGLXTestProcess();
5351#endif
5352#ifdef MOZ_WAYLAND1
5353 // Make sure we have wayland connection for main thread.
5354 // It's used as template to create display connections
5355 // for different threads.
5356 if (IsWaylandEnabled()) {
5357 MOZ_UNUSED(WaylandDisplayGet())do { if (WaylandDisplayGet()) { (void)0; } } while (0);
5358 }
5359#endif
5360#ifdef MOZ_WIDGET_GTK1
5361 nsAppShell::InstallTermSignalHandler();
5362#endif
5363 }
5364
5365 return 0;
5366}
5367
5368#if defined(MOZ_SANDBOX1)
5369void AddSandboxAnnotations() {
5370 CrashReporter::RecordAnnotationU32(
5371 CrashReporter::Annotation::ContentSandboxLevel,
5372 GetEffectiveContentSandboxLevel());
5373 CrashReporter::RecordAnnotationU32(CrashReporter::Annotation::GpuSandboxLevel,
5374 GetEffectiveGpuSandboxLevel());
5375
5376 // Include whether or not this instance is capable of content sandboxing
5377 bool sSandboxCapable = false;
5378
5379# if defined(XP_WIN)
5380 // All supported Windows versions support some level of content sandboxing
5381 sSandboxCapable = true;
5382# elif defined(XP_MACOSX)
5383 // All supported OS X versions are capable
5384 sSandboxCapable = true;
5385# elif defined(XP_LINUX1)
5386 sSandboxCapable = SandboxInfo::Get().CanSandboxContent();
5387# elif defined(__OpenBSD__)
5388 sSandboxCapable = true;
5389 StartOpenBSDSandbox(GeckoProcessType_Default);
5390# endif
5391
5392 CrashReporter::RecordAnnotationBool(
5393 CrashReporter::Annotation::ContentSandboxCapable, sSandboxCapable);
5394}
5395#endif /* MOZ_SANDBOX */
5396
5397/*
5398 * XRE_mainRun - Command line startup, profile migration, and
5399 * the calling of appStartup->Run().
5400 */
5401nsresult XREMain::XRE_mainRun() {
5402 nsresult rv = NS_OK;
5403 NS_ASSERTION(mScopedXPCOM, "Scoped xpcom not initialized.")do { if (!(mScopedXPCOM)) { NS_DebugBreak(NS_DEBUG_ASSERTION,
"Scoped xpcom not initialized.", "mScopedXPCOM", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5403); MOZ_PretendNoReturn(); } } while (0)
;
5404
5405#if defined(XP_WIN)
5406 RefPtr<mozilla::DllServices> dllServices(mozilla::DllServices::Get());
5407 dllServices->StartUntrustedModulesProcessor(false);
5408 auto dllServicesDisable =
5409 MakeScopeExit([&dllServices]() { dllServices->DisableFull(); });
5410
5411 mozilla::mscom::InitProfilerMarkers();
5412#endif // defined(XP_WIN)
5413
5414 // We need the appStartup pointer to span multiple scopes, so we declare
5415 // it here.
5416 nsCOMPtr<nsIAppStartup> appStartup;
5417 // Ditto with the command line.
5418 nsCOMPtr<nsICommandLineRunner> cmdLine;
5419
5420 {
5421#ifdef XP_MACOSX
5422 // In this scope, create an autorelease pool that will leave scope with
5423 // it just before entering our event loop.
5424 mozilla::MacAutoreleasePool pool;
5425#endif
5426
5427 rv = mScopedXPCOM->SetWindowCreator(mNativeApp);
5428 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/toolkit/xre/nsAppRunner.cpp"
, 5428); return NS_ERROR_FAILURE; } } while (false)
;
5429
5430 // tell the crash reporter to also send the release channel
5431 nsCOMPtr<nsIPrefService> prefs =
5432 do_GetService("@mozilla.org/preferences-service;1", &rv);
5433 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5434 nsCOMPtr<nsIPrefBranch> defaultPrefBranch;
5435 rv = prefs->GetDefaultBranch(nullptr, getter_AddRefs(defaultPrefBranch));
5436
5437 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5438 nsAutoCString sval;
5439 rv = defaultPrefBranch->GetCharPref("app.update.channel", sval);
5440 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5441 CrashReporter::RecordAnnotationNSCString(
5442 CrashReporter::Annotation::ReleaseChannel, sval);
5443 }
5444 }
5445 }
5446 // Needs to be set after xpcom initialization.
5447 bool includeContextHeap = Preferences::GetBool(
5448 "toolkit.crashreporter.include_context_heap", false);
5449 CrashReporter::SetIncludeContextHeap(includeContextHeap);
5450
5451#if defined(XP_LINUX1) && !defined(ANDROID)
5452 PR_CreateThread(PR_USER_THREAD, AnnotateLSBRelease, 0, PR_PRIORITY_LOW,
5453 PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
5454#endif
5455
5456 if (mStartOffline) {
5457 nsCOMPtr<nsIIOService> io(
5458 do_GetService("@mozilla.org/network/io-service;1"));
5459 NS_ENSURE_TRUE(io, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(io)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "io" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5459); return NS_ERROR_FAILURE; } } while (false)
;
5460 io->SetManageOfflineStatus(false);
5461 io->SetOffline(true);
5462 }
5463
5464 if (!mOriginToForceQUIC.IsEmpty()) {
5465 PR_SetEnv(ToNewCString("MOZ_FORCE_QUIC_ON="_ns + mOriginToForceQUIC));
5466 }
5467
5468#ifdef XP_WIN
5469 mozilla::DllPrefetchExperimentRegistryInfo prefetchRegInfo;
5470 mozilla::AlteredDllPrefetchMode dllPrefetchMode =
5471 prefetchRegInfo.GetAlteredDllPrefetchMode();
5472
5473 if (!PR_GetEnv("XRE_NO_DLL_READAHEAD") &&
5474 dllPrefetchMode != mozilla::AlteredDllPrefetchMode::NoPrefetch) {
5475 nsCOMPtr<nsIFile> greDir = mDirProvider.GetGREDir();
5476 nsAutoString path;
5477 rv = greDir->GetPath(path);
5478 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5479 // We use the presence of a path argument inside the thread to determine
5480 // which list of Dlls to use. The old list does not need access to the
5481 // GRE dir, so the path argument is voided.
5482 if (dllPrefetchMode !=
5483 mozilla::AlteredDllPrefetchMode::OptimizedPrefetch) {
5484 path.SetIsVoid(true);
5485 }
5486
5487 NS_DispatchBackgroundTask(
5488 NS_NewRunnableFunction("ReadAheadDlls", [path = std::move(path)] {
5489 ReadAheadDlls(path.IsVoid() ? nullptr : path.get());
5490 }));
5491 }
5492 }
5493#endif
5494
5495 if (gDoMigration) {
5496 nsCOMPtr<nsIFile> file;
5497 mDirProvider.GetAppDir()->Clone(getter_AddRefs(file));
5498 file->AppendNative("override.ini"_ns);
5499 nsINIParsernsINIParser_internal parser;
5500 nsresult rv = parser.Init(file);
5501 // if override.ini doesn't exist, also check for distribution.ini
5502 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5503 bool persistent;
5504 mDirProvider.GetFile(XRE_APP_DISTRIBUTION_DIR"XREAppDist", &persistent,
5505 getter_AddRefs(file));
5506 file->AppendNative("distribution.ini"_ns);
5507 rv = parser.Init(file);
5508 }
5509 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5510 nsAutoCString buf;
5511 rv = parser.GetString("XRE", "EnableProfileMigrator", buf);
5512 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5513 if (buf[0] == '0' || buf[0] == 'f' || buf[0] == 'F') {
5514 gDoMigration = false;
5515 }
5516 }
5517 }
5518 }
5519
5520 // We'd like to initialize the JSContext *after* reading the user prefs.
5521 // Unfortunately that's not possible if we have to do profile migration
5522 // because that requires us to execute JS before reading user prefs.
5523 // Restarting the browser after profile migration would fix this. See
5524 // bug 1592523.
5525 bool initializedJSContext = false;
5526
5527 {
5528 // Profile Migration
5529 if (mAppData->flags & NS_XRE_ENABLE_PROFILE_MIGRATOR(1 << 1) && gDoMigration) {
5530 gDoMigration = false;
5531
5532 xpc::InitializeJSContext();
5533 initializedJSContext = true;
5534
5535 nsCOMPtr<nsIProfileMigrator> pm(
5536 do_CreateInstance(NS_PROFILEMIGRATOR_CONTRACTID"@mozilla.org/toolkit/profile-migrator;1"));
5537 if (pm) {
5538 nsAutoCString aKey;
5539 nsAutoCString aName;
5540 if (gDoProfileReset) {
5541 // Automatically migrate from the current application if we just
5542 // reset the profile.
5543 aKey = MOZ_APP_NAME"firefox";
5544 gResetOldProfile->GetName(aName);
5545 }
5546#ifdef XP_MACOSX
5547 // Necessary for migration wizard to be accessible.
5548 InitializeMacApp();
5549#endif
5550 pm->Migrate(&mDirProvider, aKey, aName);
5551 }
5552 }
5553
5554 if (gDoProfileReset) {
5555 if (!initializedJSContext) {
5556 xpc::InitializeJSContext();
5557 initializedJSContext = true;
5558 }
5559
5560 nsresult backupCreated =
5561 ProfileResetCleanup(mProfileSvc, gResetOldProfile);
5562 if (NS_FAILED(backupCreated)((bool)(__builtin_expect(!!(NS_FAILED_impl(backupCreated)), 0
)))
) {
5563 NS_WARNING("Could not cleanup the profile that was reset")NS_DebugBreak(NS_DEBUG_WARNING, "Could not cleanup the profile that was reset"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5563)
;
5564 }
5565 }
5566 }
5567
5568 // Initialize user preferences before notifying startup observers so they're
5569 // ready in time for early consumers, such as the component loader.
5570 mDirProvider.InitializeUserPrefs();
5571
5572 // Now that all (user) prefs have been loaded we can initialize the main
5573 // thread's JSContext.
5574 if (!initializedJSContext) {
5575 xpc::InitializeJSContext();
5576 }
5577
5578 // Finally, now that JS has been initialized, we can finish pref loading.
5579 // This needs to happen after JS and XPConnect initialization because
5580 // AutoConfig files require JS execution. Note that this means AutoConfig
5581 // files can't override JS engine start-up prefs.
5582 mDirProvider.FinishInitializingUserPrefs();
5583
5584 // Do a canary load of a JS based module here. This will help us detect
5585 // missing resources during startup and make us react appropriate, that
5586 // is inform the user before exiting with a crash.
5587 {
5588 mozilla::dom::AutoJSAPI jsapi;
5589 MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()))do { if ((__builtin_expect(!!(jsapi.Init(xpc::PrivilegedJunkScope
())), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "jsapi.Init(xpc::PrivilegedJunkScope())", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5589); AnnotateMozCrashReason("MOZ_CRASH(" "jsapi.Init(xpc::PrivilegedJunkScope())"
")"); do { *((volatile int*)__null) = 5589; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5590 JS::Rooted<JSObject*> mod(jsapi.cx());
5591 // AppConstants.sys.mjs is small, widely used and most likely will
5592 // never go away.
5593 rv = mozJSModuleLoader::Get()->ImportESModule(
5594 jsapi.cx(), "resource://gre/modules/AppConstants.sys.mjs"_ns, &mod);
5595 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5596 return NS_ERROR_OMNIJAR_OR_DIR_MISSING;
5597 }
5598 }
5599
5600#if defined(MOZ_SANDBOX1) && defined(XP_WIN)
5601 // Now that we have preferences and the directory provider, we can
5602 // finish initializing SandboxBroker. This must happen before the GFX
5603 // platform is initialized (which will launch the GPU process), which
5604 // occurs when the "app-startup" category is started up below
5605 //
5606 // After this completes, we are ready to launch sandboxed processes
5607 mozilla::SandboxBroker::GeckoDependentInitialize();
5608#endif
5609
5610 nsCOMPtr<nsIFile> workingDir;
5611 rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR"CurWorkD",
5612 getter_AddRefs(workingDir));
5613 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5614 // No working dir? This can happen if it gets deleted before we start.
5615 workingDir = nullptr;
5616 }
5617
5618 cmdLine = new nsCommandLine();
5619
5620 rv = cmdLine->Init(gArgc, gArgv, workingDir,
5621 nsICommandLine::STATE_INITIAL_LAUNCH);
5622 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/toolkit/xre/nsAppRunner.cpp"
, 5622); return NS_ERROR_FAILURE; } } while (false)
;
5623
5624 // "app-startup" is the name of both the category and the event
5625 NS_CreateServicesFromCategory("app-startup", cmdLine, "app-startup",
5626 nullptr);
5627
5628 appStartup = components::AppStartup::Service();
5629 NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(appStartup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "appStartup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5629); return NS_ERROR_FAILURE; } } while (false)
;
5630
5631 mDirProvider.DoStartup();
5632
5633#ifdef XP_WIN
5634 // It needs to be called on the main thread because it has to use
5635 // nsObserverService.
5636 EnsureWin32kInitialized();
5637#endif
5638
5639 // As FilePreferences need the profile directory, we must initialize right
5640 // here.
5641 mozilla::FilePreferences::InitDirectoriesAllowlist();
5642 mozilla::FilePreferences::InitPrefs();
5643
5644 nsCString userAgentLocale;
5645 LocaleService::GetInstance()->GetAppLocaleAsBCP47(userAgentLocale);
5646 CrashReporter::RecordAnnotationNSCString(
5647 CrashReporter::Annotation::useragent_locale, userAgentLocale);
5648
5649 if (!AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
5650 /* Special-case services that need early access to the command
5651 line. */
5652 nsCOMPtr<nsIObserverService> obsService =
5653 mozilla::services::GetObserverService();
5654 if (obsService) {
5655 obsService->NotifyObservers(cmdLine, "command-line-startup", nullptr);
5656 }
5657 }
5658
5659#ifdef XP_WIN
5660 // Hack to sync up the various environment storages. XUL_APP_FILE is special
5661 // in that it comes from a different CRT (firefox.exe's static-linked copy).
5662 // Ugly details in http://bugzil.la/1175039#c27
5663 char appFile[MAX_PATH];
5664 if (GetEnvironmentVariableA("XUL_APP_FILE", appFile, sizeof(appFile))) {
5665 SmprintfPointer saved = mozilla::Smprintf("XUL_APP_FILE=%s", appFile);
5666 // We intentionally leak the string here since it is required by
5667 // PR_SetEnv.
5668 PR_SetEnv(saved.release());
5669 }
5670#endif
5671
5672 mozilla::AppShutdown::SaveEnvVarsForPotentialRestart();
5673
5674 // clear out any environment variables which may have been set
5675 // during the relaunch process now that we know we won't be relaunching.
5676 SaveToEnv("XRE_PROFILE_PATH=");
5677 SaveToEnv("XRE_PROFILE_LOCAL_PATH=");
5678 SaveToEnv("XRE_START_OFFLINE=");
5679 SaveToEnv("XUL_APP_FILE=");
5680 SaveToEnv("XRE_BINARY_PATH=");
5681 SaveToEnv("XRE_RESTARTED_BY_PROFILE_MANAGER=");
5682
5683 if (!AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
5684#ifdef XP_MACOSX
5685 if (!BackgroundTasks::IsBackgroundTaskMode()) {
5686 rv = appStartup->CreateHiddenWindow();
5687 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/toolkit/xre/nsAppRunner.cpp"
, 5687); return NS_ERROR_FAILURE; } } while (false)
;
5688 }
5689#endif
5690
5691#ifdef XP_WIN
5692 Preferences::RegisterCallbackAndCall(
5693 RegisterApplicationRestartChanged,
5694 PREF_WIN_REGISTER_APPLICATION_RESTART);
5695 SetupAlteredPrefetchPref();
5696 SetupSkeletonUIPrefs();
5697# if defined(MOZ_LAUNCHER_PROCESS)
5698 SetupLauncherProcessPref();
5699# endif // defined(MOZ_LAUNCHER_PROCESS)
5700# if defined(MOZ_DEFAULT_BROWSER_AGENT)
5701# if defined(MOZ_BACKGROUNDTASKS1)
5702 // The backgroundtask profile is not a browsing profile, let alone the new
5703 // default profile, so don't mirror its properties into the registry.
5704 if (!BackgroundTasks::IsBackgroundTaskMode())
5705# endif // defined(MOZ_BACKGROUNDTASKS)
5706 {
5707 Preferences::RegisterCallbackAndCall(
5708 &OnDefaultAgentTelemetryPrefChanged,
5709 kPrefHealthReportUploadEnabled);
5710 Preferences::RegisterCallbackAndCall(
5711 &OnDefaultAgentTelemetryPrefChanged, kPrefDefaultAgentEnabled);
5712
5713 Preferences::RegisterCallbackAndCall(
5714 &OnDefaultAgentRemoteSettingsPrefChanged,
5715 kPrefServicesSettingsServer);
5716
5717 Preferences::RegisterCallbackAndCall(
5718 &OnSetDefaultBrowserUserChoicePrefChanged,
5719 kPrefSetDefaultBrowserUserChoicePref);
5720
5721 SetDefaultAgentLastRunTime();
5722 }
5723# endif // defined(MOZ_DEFAULT_BROWSER_AGENT)
5724#endif
5725
5726#if defined(MOZ_WIDGET_GTK1)
5727 // Clear the environment variables so they won't be inherited by child
5728 // processes and confuse things.
5729 for (const auto& name : kStartupTokenNames) {
5730 g_unsetenv(name.get());
5731 }
5732#endif
5733
5734#ifdef XP_MACOSX
5735 InitializeMacApp();
5736
5737 // we re-initialize the command-line service and do appleevents munging
5738 // after we are sure that we're not restarting
5739 cmdLine = new nsCommandLine();
5740
5741 char** tempArgv = static_cast<char**>(malloc(gArgc * sizeof(char*)));
5742 for (int i = 0; i < gArgc; i++) {
5743 tempArgv[i] = strdup(gArgv[i]);
5744 }
5745 CommandLineServiceMac::SetupMacCommandLine(gArgc, tempArgv, false);
5746 rv = cmdLine->Init(gArgc, tempArgv, workingDir,
5747 nsICommandLine::STATE_INITIAL_LAUNCH);
5748 free(tempArgv);
5749 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/toolkit/xre/nsAppRunner.cpp"
, 5749); return NS_ERROR_FAILURE; } } while (false)
;
5750
5751# ifdef MOZILLA_OFFICIAL
5752 // Check if we're running from a DMG or an app translocated location and
5753 // allow the user to install to the Applications directory.
5754 if (MacRunFromDmgUtils::MaybeInstallAndRelaunch()) {
5755 bool userAllowedQuit = true;
5756 appStartup->Quit(nsIAppStartup::eForceQuit, 0, &userAllowedQuit);
5757 }
5758# endif
5759#endif
5760
5761 nsCOMPtr<nsIObserverService> obsService =
5762 mozilla::services::GetObserverService();
5763 if (obsService)
5764 obsService->NotifyObservers(nullptr, "final-ui-startup", nullptr);
5765
5766 (void)appStartup->DoneStartingUp();
5767
5768 CrashReporter::RecordAnnotationBool(
5769 CrashReporter::Annotation::StartupCrash, false);
5770
5771 AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed);
5772 }
5773
5774 if (!AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
5775 rv = cmdLine->Run();
5776 NS_ENSURE_SUCCESS_LOG(rv, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5776); gLogConsoleErrors = true; return NS_ERROR_FAILURE; }
} while (0)
;
5777 }
5778
5779 if (!AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
5780#if defined(MOZ_HAS_REMOTE1)
5781 // if we have X remote support, start listening for requests on the
5782 // proxy window.
5783 if (gRemoteService) {
5784 gRemoteService->StartupServer();
5785 gStartupLock = nullptr;
5786 }
5787#endif
5788
5789 mNativeApp->Enable();
5790 }
5791
5792 // Send Telemetry about Gecko version and buildid
5793 mozilla::glean::gecko::version.Set(nsDependentCString(gAppData->version));
5794 mozilla::glean::gecko::build_id.Set(nsDependentCString(gAppData->buildID));
5795
5796#if defined(MOZ_SANDBOX1) && defined(XP_LINUX1)
5797 // If we're on Linux, we now have information about the OS capabilities
5798 // available to us.
5799 SandboxInfo sandboxInfo = SandboxInfo::Get();
5800 Telemetry::Accumulate(Telemetry::SANDBOX_HAS_USER_NAMESPACES,
5801 sandboxInfo.Test(SandboxInfo::kHasUserNamespaces));
5802
5803 CrashReporter::RecordAnnotationU32(
5804 CrashReporter::Annotation::ContentSandboxCapabilities,
5805 sandboxInfo.AsInteger());
5806#endif /* MOZ_SANDBOX && XP_LINUX */
5807
5808#if defined(XP_WIN)
5809 LauncherResult<bool> isAdminWithoutUac = IsAdminWithoutUac();
5810 if (isAdminWithoutUac.isOk()) {
5811 glean::os_environment::is_admin_without_uac.Set(
5812 isAdminWithoutUac.unwrap());
5813 }
5814#endif /* XP_WIN */
5815
5816#if defined(MOZ_SANDBOX1)
5817 AddSandboxAnnotations();
5818#endif /* MOZ_SANDBOX */
5819
5820 mProfileSvc->CompleteStartup();
5821 }
5822
5823#ifdef MOZ_BACKGROUNDTASKS1
5824 if (BackgroundTasks::IsBackgroundTaskMode()) {
5825 // In background task mode, we don't fire various delayed initialization
5826 // notifications, which in the regular browser is how startup crash tracking
5827 // is marked as finished. Here, getting this far means we don't have a
5828 // startup crash.
5829 rv = appStartup->TrackStartupCrashEnd();
5830 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/toolkit/xre/nsAppRunner.cpp"
, 5830); return rv; } } while (false)
;
5831
5832 // We never open a window, but don't want to exit immediately.
5833 rv = appStartup->EnterLastWindowClosingSurvivalArea();
5834 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/toolkit/xre/nsAppRunner.cpp"
, 5834); return rv; } } while (false)
;
5835
5836 // Avoid some small differences in initialization order across platforms.
5837 nsCOMPtr<nsIPowerManagerService> powerManagerService =
5838 do_GetService(POWERMANAGERSERVICE_CONTRACTID"@mozilla.org/power/powermanagerservice;1");
5839 nsCOMPtr<nsIStringBundleService> stringBundleService =
5840 do_GetService(NS_STRINGBUNDLE_CONTRACTID"@mozilla.org/intl/stringbundle;1");
5841
5842 rv = BackgroundTasks::RunBackgroundTask(cmdLine);
5843 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/toolkit/xre/nsAppRunner.cpp"
, 5843); return rv; } } while (false)
;
5844 }
5845#endif
5846
5847 {
5848 rv = appStartup->Run();
5849 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5850 NS_ERROR("failed to run appstartup")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "failed to run appstartup"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5850); MOZ_PretendNoReturn(); } while (0)
;
5851 gLogConsoleErrors = true;
5852 }
5853 }
5854
5855 return rv;
5856}
5857
5858#if defined(MOZ_WIDGET_ANDROID)
5859static already_AddRefed<nsIFile> GreOmniPath(int argc, char** argv) {
5860 nsresult rv;
5861
5862 const char* path = nullptr;
5863 ArgResult ar = CheckArg(argc, argv, "greomni", &path, CheckArgFlag::None);
5864 if (ar == ARG_BAD) {
5865 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
5866 "Error: argument --greomni requires a path argument\n");
5867 return nullptr;
5868 }
5869
5870 if (!path) return nullptr;
5871
5872 nsCOMPtr<nsIFile> greOmni;
5873 rv = XRE_GetFileFromPath(path, getter_AddRefs(greOmni));
5874 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5875 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Error: argument --greomni requires a valid path\n");
5876 return nullptr;
5877 }
5878
5879 return greOmni.forget();
5880}
5881#endif
5882
5883/*
5884 * XRE_main - A class based main entry point used by most platforms.
5885 * Note that on OSX, aAppData->xreDirectory will point to
5886 * .app/Contents/Resources.
5887 */
5888int XREMain::XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig) {
5889 gArgc = argc;
5890 gArgv = argv;
5891
5892 ScopedLogging log;
5893
5894 mozilla::LogModule::Init(gArgc, gArgv);
5895
5896#ifndef XP_LINUX1
5897 NS_SetCurrentThreadName("MainThread");
5898#endif
5899
5900 AUTO_BASE_PROFILER_LABEL("XREMain::XRE_main (around Gecko Profiler)", OTHER)::mozilla::baseprofiler::AutoProfilerLabel raiiObject5900( "XREMain::XRE_main (around Gecko Profiler)"
, nullptr, ::mozilla::baseprofiler::ProfilingCategoryPair::OTHER
)
;
5901 AUTO_PROFILER_INITmozilla::AutoProfilerInit raiiObject5901;
5902 AUTO_PROFILER_LABEL("XREMain::XRE_main", OTHER)mozilla::AutoProfilerLabel raiiObject5902( "XREMain::XRE_main"
, nullptr, JS::ProfilingCategoryPair::OTHER)
;
5903
5904#ifdef XP_MACOSX
5905 // We call this early because it will kick off a background-thread task
5906 // to register the fonts, and we'd like it to have a chance to complete
5907 // before gfxPlatform initialization actually requires it.
5908 gfxPlatformMac::RegisterSupplementalFonts();
5909#endif
5910
5911#ifdef MOZ_WIDGET_ANDROID
5912 // We call the early because we run system font API on a background-thread
5913 // to initialize internal font API data in Android. (Bug 1895926)
5914 gfxAndroidPlatform::InitializeFontAPI();
5915#endif
5916
5917#ifdef MOZ_CODE_COVERAGE
5918 CodeCoverageHandler::Init();
5919#endif
5920
5921 nsresult rv = NS_OK;
5922
5923 if (aConfig.appData) {
5924 mAppData = MakeUnique<XREAppData>(*aConfig.appData);
5925 } else {
5926 MOZ_RELEASE_ASSERT(aConfig.appDataPath)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aConfig.appDataPath)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aConfig.appDataPath))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("aConfig.appDataPath"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5926); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aConfig.appDataPath"
")"); do { *((volatile int*)__null) = 5926; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5927 nsCOMPtr<nsIFile> appini;
5928 rv = XRE_GetFileFromPath(aConfig.appDataPath, getter_AddRefs(appini));
5929 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5930 Output(true, "Error: unrecognized path: %s\n", aConfig.appDataPath);
5931 return 1;
5932 }
5933
5934 mAppData = MakeUnique<XREAppData>();
5935 rv = XRE_ParseAppData(appini, *mAppData);
5936 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5937 Output(true, "Couldn't read application.ini");
5938 return 1;
5939 }
5940
5941 appini->GetParent(getter_AddRefs(mAppData->directory));
5942 }
5943
5944 const char* appRemotingName = getenv("MOZ_APP_REMOTINGNAME");
5945 if (appRemotingName) {
5946 mAppData->remotingName = appRemotingName;
5947 } else if (!mAppData->remotingName) {
5948 mAppData->remotingName = mAppData->name;
5949 }
5950 // used throughout this file
5951 gAppData = mAppData.get();
5952
5953 nsCOMPtr<nsIFile> binFile;
5954 rv = XRE_GetBinaryPath(getter_AddRefs(binFile));
5955 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5955); return 1; } } while (false)
;
5956
5957 rv = binFile->GetPath(gAbsoluteArgv0Path);
5958 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5958); return 1; } } while (false)
;
5959
5960 if (!mAppData->xreDirectory) {
5961 nsCOMPtr<nsIFile> greDir;
5962
5963#if defined(MOZ_WIDGET_ANDROID)
5964 greDir = GreOmniPath(argc, argv);
5965 if (!greDir) {
5966 return 2;
5967 }
5968#else
5969 rv = binFile->GetParent(getter_AddRefs(greDir));
5970 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return 2;
5971#endif
5972
5973#ifdef XP_MACOSX
5974 nsCOMPtr<nsIFile> parent;
5975 greDir->GetParent(getter_AddRefs(parent));
5976 greDir = parent.forget();
5977 greDir->AppendNative("Resources"_ns);
5978#endif
5979
5980 mAppData->xreDirectory = greDir;
5981 }
5982
5983#if defined(MOZ_WIDGET_ANDROID)
5984 nsCOMPtr<nsIFile> dataDir;
5985 rv = binFile->GetParent(getter_AddRefs(dataDir));
5986 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return 2;
5987
5988 mAppData->directory = dataDir;
5989#else
5990 if (aConfig.appData && aConfig.appDataPath) {
5991 mAppData->xreDirectory->Clone(getter_AddRefs(mAppData->directory));
5992 mAppData->directory->AppendNative(nsDependentCString(aConfig.appDataPath));
5993 }
5994#endif
5995
5996 if (!mAppData->directory) {
5997 mAppData->directory = mAppData->xreDirectory;
5998 }
5999
6000#if defined(XP_WIN)
6001# if defined(MOZ_SANDBOX1)
6002 mAppData->sandboxBrokerServices = aConfig.sandboxBrokerServices;
6003# endif // defined(MOZ_SANDBOX)
6004
6005 {
6006 DebugOnly<bool> result = WindowsBCryptInitialization();
6007 MOZ_ASSERT(result)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(result)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(result))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("result", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "result" ")"
); do { *((volatile int*)__null) = 6007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6008 }
6009
6010# if defined(_M_IX86) || defined(_M_X64)
6011 {
6012 DebugOnly<bool> result = WindowsMsctfInitialization();
6013 MOZ_ASSERT(result)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(result)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(result))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("result", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6013); AnnotateMozCrashReason("MOZ_ASSERT" "(" "result" ")"
); do { *((volatile int*)__null) = 6013; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6014 }
6015# endif // _M_IX86 || _M_X64
6016
6017 // Bug 1924623: Detouring VariantClear resulted in a huge crash spike for
6018 // Thunderbird, so let's only do that for Firefox.
6019# ifdef MOZ_BUILD_APP_IS_BROWSER1
6020 {
6021 DebugOnly<bool> result = WindowsOleAut32Initialization();
6022 MOZ_ASSERT(result)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(result)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(result))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("result", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "result" ")"
); do { *((volatile int*)__null) = 6022; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6023 }
6024# endif // MOZ_BUILD_APP_IS_BROWSER
6025
6026#endif // defined(XP_WIN)
6027
6028 // Once we unset the exception handler, we lose the ability to properly
6029 // detect hangs -- they show up as crashes. We do this as late as possible.
6030 // In particular, after ProcessRuntime is destroyed on Windows.
6031 auto unsetExceptionHandler = MakeScopeExit([&] {
6032 if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER(1 << 3))
6033 return CrashReporter::UnsetExceptionHandler();
6034 return NS_OK;
6035 });
6036
6037 mozilla::AutoIOInterposer ioInterposerGuard;
6038 ioInterposerGuard.Init();
6039
6040#if defined(XP_WIN)
6041 // We should have already done this when we created the skeleton UI. However,
6042 // there is code in here which needs xul in order to work, like EnsureMTA. It
6043 // should be setup that running it again is safe.
6044 mozilla::mscom::ProcessRuntime msCOMRuntime;
6045#endif
6046
6047 // init
6048 bool exit = false;
6049 int result = XRE_mainInit(&exit);
6050 if (result != 0 || exit) return result;
6051
6052 // If we exit gracefully, remove the startup crash canary file.
6053 auto cleanup = MakeScopeExit([&]() -> nsresult {
6054 if (mProfLD) {
6055 nsCOMPtr<nsIFile> crashFile;
6056 MOZ_TRY_VAR(crashFile, GetIncompleteStartupFile(mProfLD))do { auto mozTryVarTempResult_ = (GetIncompleteStartupFile(mProfLD
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (crashFile
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6057 crashFile->Remove(false);
6058 }
6059 return NS_OK;
6060 });
6061
6062 // startup
6063 result = XRE_mainStartup(&exit);
6064 if (result != 0 || exit) return result;
6065
6066 // Start the real application. We use |aInitJSContext = false| because
6067 // XRE_mainRun wants to initialize the JSContext after reading user prefs.
6068
6069 mScopedXPCOM = MakeUnique<ScopedXPCOMStartup>();
6070
6071 rv = mScopedXPCOM->Initialize(/* aInitJSContext = */ false);
6072 if (rv == NS_ERROR_OMNIJAR_CORRUPT) {
6073 if (XRE_IsParentProcess()
6074#ifdef MOZ_BACKGROUNDTASKS1
6075 && !mozilla::BackgroundTasks::IsBackgroundTaskMode()
6076#endif
6077 ) {
6078 Output(
6079 true,
6080 "The installation seems to be corrupt.\nPlease check your hardware "
6081 "and disk setup\nand/or re-install.\n");
6082 }
6083 MOZ_CRASH("NS_ERROR_OMNIJAR_CORRUPT")do { do { } while (false); MOZ_ReportCrash("" "NS_ERROR_OMNIJAR_CORRUPT"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6083); AnnotateMozCrashReason("MOZ_CRASH(" "NS_ERROR_OMNIJAR_CORRUPT"
")"); do { *((volatile int*)__null) = 6083; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6084 }
6085 NS_ENSURE_SUCCESS(rv, 1)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", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6085); return 1; } } while (false)
;
6086
6087 // run!
6088 rv = XRE_mainRun();
6089 if (rv == NS_ERROR_OMNIJAR_OR_DIR_MISSING) {
6090 if (XRE_IsParentProcess()
6091#ifdef MOZ_BACKGROUNDTASKS1
6092 && !mozilla::BackgroundTasks::IsBackgroundTaskMode()
6093#endif
6094 ) {
6095 Output(true,
6096 "The installation seems to be incomplete.\nPlease check your "
6097 "hardware and disk setup\nand/or re-install.\n");
6098 }
6099 if (mozilla::IsPackagedBuild()) {
6100 // IsPackagedBuild just looks for omni.ja on disk. If we were able to
6101 // find and open it before but not to load the expected JS module from
6102 // it now, signal corruption.
6103 MOZ_CRASH("NS_ERROR_OMNIJAR_CORRUPT")do { do { } while (false); MOZ_ReportCrash("" "NS_ERROR_OMNIJAR_CORRUPT"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6103); AnnotateMozCrashReason("MOZ_CRASH(" "NS_ERROR_OMNIJAR_CORRUPT"
")"); do { *((volatile int*)__null) = 6103; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6104 }
6105 MOZ_CRASH("NS_ERROR_OMNIJAR_OR_DIR_MISSING")do { do { } while (false); MOZ_ReportCrash("" "NS_ERROR_OMNIJAR_OR_DIR_MISSING"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6105); AnnotateMozCrashReason("MOZ_CRASH(" "NS_ERROR_OMNIJAR_OR_DIR_MISSING"
")"); do { *((volatile int*)__null) = 6105; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6106 }
6107
6108#ifdef MOZ_X111
6109 XRE_CleanupX11ErrorHandler();
6110#endif
6111
6112 gAbsoluteArgv0Path.Truncate();
6113
6114#if defined(MOZ_HAS_REMOTE1)
6115 // Shut down the remote service. We must do this before calling LaunchChild
6116 // if we're restarting because otherwise the new instance will attempt to
6117 // remote to this instance.
6118 if (gRemoteService) {
6119 gRemoteService->ShutdownServer();
6120 gStartupLock = nullptr;
6121 gRemoteService = nullptr;
6122 }
6123#endif
6124
6125 mScopedXPCOM = nullptr;
6126
6127 // unlock the profile after ScopedXPCOMStartup object (xpcom)
6128 // has gone out of scope. see bug #386739 for more details
6129 mProfileLock->Unlock();
6130 gProfileLock = nullptr;
6131
6132 gLastAppVersion.Truncate();
6133 gLastAppBuildID.Truncate();
6134
6135#ifdef MOZ_WIDGET_GTK1
6136 // gdk_display_close also calls gdk_display_manager_set_default_display
6137 // appropriately when necessary.
6138 if (!gfxPlatform::IsHeadless()) {
6139# ifdef MOZ_WAYLAND1
6140 WaylandDisplayRelease();
6141 gWaylandProxy = nullptr;
6142# endif
6143 }
6144#endif
6145
6146 mozilla::AppShutdown::MaybeDoRestart();
6147
6148 XRE_DeinitCommandLine();
6149
6150 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6151 return 1;
6152 }
6153 return mozilla::AppShutdown::GetExitCode();
6154}
6155
6156void XRE_StopLateWriteChecks(void) { mozilla::StopLateWriteChecks(); }
6157
6158int XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig) {
6159 XREMain main;
6160
6161 int result = main.XRE_main(argc, argv, aConfig);
6162 mozilla::RecordShutdownEndTimeStamp();
6163#ifdef MOZ_BACKGROUNDTASKS1
6164 // This is well after the profile has been unlocked, so it's okay if this does
6165 // delete this background task's temporary profile.
6166 mozilla::BackgroundTasks::Shutdown();
6167#endif
6168 return result;
6169}
6170
6171nsresult XRE_InitCommandLine(int aArgc, char* aArgv[]) {
6172 nsresult rv = NS_OK;
6173
6174#if defined(XP_WIN)
6175 CommandLine::Init(aArgc, aArgv);
6176#else
6177
6178 // these leak on error, but that's OK: we'll just exit()
6179 char** canonArgs = new char*[aArgc];
6180
6181 // get the canonical version of the binary's path
6182 nsCOMPtr<nsIFile> binFile;
6183 rv = XRE_GetBinaryPath(getter_AddRefs(binFile));
6184 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return NS_ERROR_FAILURE;
6185
6186 nsAutoCString canonBinPath;
6187 rv = binFile->GetNativePath(canonBinPath);
6188 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return NS_ERROR_FAILURE;
6189
6190 canonArgs[0] = strdup(canonBinPath.get());
6191
6192 for (int i = 1; i < aArgc; ++i) {
6193 if (aArgv[i]) {
6194 canonArgs[i] = strdup(aArgv[i]);
6195 }
6196 }
6197
6198 NS_ASSERTION(!CommandLine::IsInitialized(), "Bad news!")do { if (!(!CommandLine::IsInitialized())) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "Bad news!", "!CommandLine::IsInitialized()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6198); MOZ_PretendNoReturn(); } } while (0)
;
6199 CommandLine::Init(aArgc, canonArgs);
6200
6201 for (int i = 0; i < aArgc; ++i) free(canonArgs[i]);
6202 delete[] canonArgs;
6203#endif
6204
6205#if defined(MOZ_WIDGET_ANDROID)
6206 // gAppData is non-null iff this is the parent process. Otherwise,
6207 // the `-greomni`/`-appomni` flags are cross-platform and handled in
6208 // ContentProcess::Init.
6209 if (gAppData) {
6210 nsCOMPtr<nsIFile> greOmni = gAppData->xreDirectory;
6211 if (!greOmni) {
6212 return NS_ERROR_FAILURE;
6213 }
6214 mozilla::Omnijar::Init(greOmni, greOmni);
6215 MOZ_RELEASE_ASSERT(IsPackagedBuild(), "Android builds are always packaged")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsPackagedBuild())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsPackagedBuild()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("IsPackagedBuild()"
" (" "Android builds are always packaged" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6215); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "IsPackagedBuild()"
") (" "Android builds are always packaged" ")"); do { *((volatile
int*)__null) = 6215; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
6216 }
6217#endif
6218
6219 return rv;
6220}
6221
6222nsresult XRE_DeinitCommandLine() {
6223 nsresult rv = NS_OK;
6224
6225 CommandLine::Terminate();
6226
6227 return rv;
6228}
6229
6230GeckoProcessType XRE_GetProcessType() { return GetGeckoProcessType(); }
6231
6232const char* XRE_GetProcessTypeString() {
6233 return XRE_GeckoProcessTypeToString(XRE_GetProcessType());
6234}
6235
6236GeckoChildID XRE_GetChildID() { return GetGeckoChildID(); }
6237
6238bool XRE_IsE10sParentProcess() {
6239#ifdef MOZ_WIDGET_ANDROID
6240 return XRE_IsParentProcess() && BrowserTabsRemoteAutostart() &&
6241 mozilla::jni::IsAvailable();
6242#else
6243 return XRE_IsParentProcess() && BrowserTabsRemoteAutostart();
6244#endif
6245}
6246
6247#define GECKO_PROCESS_TYPE(enum_value, enum_name, string_name, proc_typename, \
6248 process_bin_type, procinfo_typename, \
6249 webidl_typename, allcaps_name) \
6250 bool XRE_Is##proc_typename##Process() { \
6251 return XRE_GetProcessType() == GeckoProcessType_##enum_name; \
6252 }
6253#include "mozilla/GeckoProcessTypes.h"
6254#undef GECKO_PROCESS_TYPE
6255
6256bool XRE_UseNativeEventProcessing() {
6257 switch (XRE_GetProcessType()) {
6258#if defined(XP_MACOSX) || defined(XP_WIN)
6259 case GeckoProcessType_RDD:
6260 case GeckoProcessType_Socket:
6261 return false;
6262 case GeckoProcessType_Utility: {
6263# if defined(XP_WIN)
6264 auto upc = mozilla::ipc::UtilityProcessChild::Get();
6265 MOZ_ASSERT(upc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(upc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(upc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("upc", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6265); AnnotateMozCrashReason("MOZ_ASSERT" "(" "upc" ")"); do
{ *((volatile int*)__null) = 6265; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
6266
6267 using SboxKind = mozilla::ipc::SandboxingKind;
6268 // These processes are used as external hosts for accessing Windows
6269 // APIs which (may) require a Windows native event loop.
6270 return upc->mSandbox == SboxKind::WINDOWS_UTILS ||
6271 upc->mSandbox == SboxKind::WINDOWS_FILE_DIALOG;
6272# else
6273 return false;
6274# endif // defined(XP_WIN)
6275 }
6276#endif // defined(XP_MACOSX) || defined(XP_WIN)
6277 case GeckoProcessType_GMPlugin:
6278 return mozilla::gmp::GMPProcessChild::UseNativeEventProcessing();
6279 case GeckoProcessType_Content:
6280 return StaticPrefs::dom_ipc_useNativeEventProcessing_content();
6281 default:
6282 return true;
6283 }
6284}
6285
6286namespace mozilla {
6287
6288uint32_t GetMaxWebProcessCount() {
6289 // multiOptOut is in int to allow us to run multiple experiments without
6290 // introducing multiple prefs a la the autostart.N prefs.
6291 if (Preferences::GetInt("dom.ipc.multiOptOut", 0) >=
6292 nsIXULRuntime::E10S_MULTI_EXPERIMENT) {
6293 return 1;
6294 }
6295
6296 const char* optInPref = "dom.ipc.processCount";
6297 uint32_t optInPrefValue = Preferences::GetInt(optInPref, 1);
6298 return std::max(1u, optInPrefValue);
6299}
6300
6301const char* PlatformBuildID() { return gToolkitBuildID; }
6302
6303} // namespace mozilla
6304
6305void SetupErrorHandling(const char* progname) {
6306#ifdef XP_WIN
6307 /* On Windows XPSP3 and Windows Vista if DEP is configured off-by-default
6308 we still want DEP protection: enable it explicitly and programmatically.
6309
6310 This function is not available on WinXPSP2 so we dynamically load it.
6311 */
6312
6313 HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
6314 SetProcessDEPPolicyFunc _SetProcessDEPPolicy =
6315 (SetProcessDEPPolicyFunc)GetProcAddress(kernel32, "SetProcessDEPPolicy");
6316 if (_SetProcessDEPPolicy) _SetProcessDEPPolicy(PROCESS_DEP_ENABLE);
6317#endif
6318
6319#ifdef XP_WIN
6320 // Suppress the "DLL Foo could not be found" dialog, such that if dependent
6321 // libraries (such as GDI+) are not preset, we gracefully fail to load those
6322 // XPCOM components, instead of being ungraceful.
6323 UINT realMode = SetErrorMode(0);
6324 realMode |= SEM_FAILCRITICALERRORS;
6325 // If XRE_NO_WINDOWS_CRASH_DIALOG is set, suppress displaying the "This
6326 // application has crashed" dialog box. This is mainly useful for
6327 // automated testing environments, e.g. tinderbox, where there's no need
6328 // for a dozen of the dialog boxes to litter the console
6329 if (getenv("XRE_NO_WINDOWS_CRASH_DIALOG"))
6330 realMode |= SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
6331
6332 SetErrorMode(realMode);
6333
6334#endif
6335
6336 InstallSignalHandlers(progname);
6337
6338 // Unbuffer stdout, needed for tinderbox tests.
6339 setbuf(stdoutstdout, 0);
6340}
6341
6342static bool gRunSelfAsContentProc = false;
6343
6344void XRE_EnableSameExecutableForContentProc() {
6345 if (!PR_GetEnv("MOZ_SEPARATE_CHILD_PROCESS")) {
6346 gRunSelfAsContentProc = true;
6347 }
6348}
6349
6350mozilla::BinPathType XRE_GetChildProcBinPathType(
6351 GeckoProcessType aProcessType) {
6352 MOZ_ASSERT(aProcessType != GeckoProcessType_Default)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aProcessType != GeckoProcessType_Default)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aProcessType != GeckoProcessType_Default))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aProcessType != GeckoProcessType_Default"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6352); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aProcessType != GeckoProcessType_Default"
")"); do { *((volatile int*)__null) = 6352; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6353
6354 if (!gRunSelfAsContentProc) {
6355 return BinPathType::PluginContainer;
6356 }
6357
6358#ifdef XP_WIN
6359 // On Windows, plugin-container may or may not be used depending on
6360 // the process type (e.g., actual plugins vs. content processes)
6361 switch (aProcessType) {
6362# define GECKO_PROCESS_TYPE(enum_value, enum_name, string_name, \
6363 proc_typename, process_bin_type, \
6364 procinfo_typename, webidl_typename, allcaps_name) \
6365 case GeckoProcessType_##enum_name: \
6366 return BinPathType::process_bin_type;
6367# include "mozilla/GeckoProcessTypes.h"
6368# undef GECKO_PROCESS_TYPE
6369 default:
6370 return BinPathType::PluginContainer;
6371 }
6372#else
6373 // On (non-macOS) Unix, plugin-container isn't used (except in cases
6374 // like xpcshell that are handled by the gRunSelfAsContentProc check
6375 // above). It isn't necessary the way it is on other platforms, and
6376 // it interferes with using the fork server.
6377 return BinPathType::Self;
6378#endif
6379}
6380
6381// From mozglue/static/rust/lib.rs
6382extern "C" void install_rust_hooks();
6383
6384struct InstallRustHooks {
6385 InstallRustHooks() { install_rust_hooks(); }
6386};
6387
6388MOZ_RUNINIT InstallRustHooks sInstallRustHooks;
6389
6390#ifdef MOZ_ASAN_REPORTER
6391void setASanReporterPath(nsIFile* aDir) {
6392 nsCOMPtr<nsIFile> dir;
6393 aDir->Clone(getter_AddRefs(dir));
6394
6395 dir->Append(u"asan"_ns);
6396 nsresult rv = dir->Create(nsIFile::DIRECTORY_TYPE, 0700);
6397 if (NS_WARN_IF(NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS)NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))) && rv != NS_ERROR_FILE_ALREADY_EXISTS, "NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6397)
) {
6398 MOZ_CRASH("[ASan Reporter] Unable to create crash directory.")do { do { } while (false); MOZ_ReportCrash("" "[ASan Reporter] Unable to create crash directory."
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6398); AnnotateMozCrashReason("MOZ_CRASH(" "[ASan Reporter] Unable to create crash directory."
")"); do { *((volatile int*)__null) = 6398; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6399 }
6400
6401 dir->Append(u"ff_asan_log"_ns);
6402
6403# ifdef XP_WIN
6404 nsAutoString nspathW;
6405 rv = dir->GetPath(nspathW);
6406 NS_ConvertUTF16toUTF8 nspath(nspathW);
6407# else
6408 nsAutoCString nspath;
6409 rv = dir->GetNativePath(nspath);
6410# endif
6411 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6412 MOZ_CRASH("[ASan Reporter] Unable to get native path for crash directory.")do { do { } while (false); MOZ_ReportCrash("" "[ASan Reporter] Unable to get native path for crash directory."
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 6412); AnnotateMozCrashReason("MOZ_CRASH(" "[ASan Reporter] Unable to get native path for crash directory."
")"); do { *((volatile int*)__null) = 6412; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6413 }
6414
6415 __sanitizer_set_report_path(nspath.get());
6416}
6417#endif

/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/CmdLineAndEnvUtils.h

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 https://mozilla.org/MPL/2.0/. */
6
7#ifndef mozilla_CmdLineAndEnvUtils_h
8#define mozilla_CmdLineAndEnvUtils_h
9
10// NB: This code may be used outside of xul and thus must not depend on XPCOM
11
12#if defined(MOZILLA_INTERNAL_API1)
13# include "prenv.h"
14# include "prprf.h"
15# include <string.h>
16#endif
17
18#if defined(XP_WIN)
19# include "mozilla/UniquePtr.h"
20# include "mozilla/Vector.h"
21# include "mozilla/WinHeaderOnlyUtils.h"
22
23# include <wchar.h>
24# include <windows.h>
25#endif // defined(XP_WIN)
26
27#include "mozilla/Maybe.h"
28#include "mozilla/MemoryChecking.h"
29#include "mozilla/TypedEnumBits.h"
30
31#include <ctype.h>
32#include <stdint.h>
33#include <stdlib.h>
34
35#ifndef NS_NO_XPCOM
36# include "nsIFile.h"
37# include "mozilla/AlreadyAddRefed.h"
38#endif
39
40// Undo X11/X.h's definition of None
41#undef None
42
43namespace mozilla {
44
45enum ArgResult {
46 ARG_NONE = 0,
47 ARG_FOUND = 1,
48 ARG_BAD = 2 // you wanted a param, but there isn't one
49};
50
51template <typename CharT>
52inline void RemoveArg(int& argc, CharT** argv) {
53 do {
54 *argv = *(argv + 1);
55 ++argv;
56 } while (*argv);
57
58 --argc;
59}
60
61namespace internal {
62
63#if 'a' == '\x61'
64// Valid option characters must have the same representation in every locale
65// (which is true for most of ASCII, barring \x5C and \x7E).
66static inline constexpr bool isValidOptionCharacter(char c) {
67 // We specifically avoid the use of `islower` here; it's locale-dependent, and
68 // may return true for non-ASCII values in some locales.
69 return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || c == '-';
70};
71
72// Convert uppercase to lowercase, locale-insensitively.
73static inline constexpr char toLowercase(char c) {
74 // We specifically avoid the use of `tolower` here; it's locale-dependent, and
75 // may output ASCII values for non-ASCII input (or vice versa) in some
76 // locales.
77 return ('A' <= c && c <= 'Z') ? char(c | ' ') : c;
78};
79
80// Convert a CharT to a char, ensuring that no CharT is mapped to any valid
81// option character except the unique CharT naturally corresponding thereto.
82template <typename CharT>
83static inline constexpr char toNarrow(CharT c) {
84 // confirmed to compile down to nothing when `CharT` is `char`
85 return (c & static_cast<CharT>(0xff)) == c ? c : 0xff;
86};
87#else
88// The target system's character set isn't even ASCII-compatible. If you're
89// porting Gecko to such a platform, you'll have to implement these yourself.
90# error Character conversion functions not implemented for this platform.
91#endif
92
93// Case-insensitively compare a string taken from the command-line (`mixedstr`)
94// to the text of some known command-line option (`lowerstr`).
95template <typename CharT>
96static inline bool strimatch(const char* lowerstr, const CharT* mixedstr) {
97 while (*lowerstr) {
98 if (!*mixedstr) return false; // mixedstr is shorter
99
100 // Non-ASCII strings may compare incorrectly depending on the user's locale.
101 // Some ASCII-safe characters are also dispermitted for semantic reasons
102 // and simplicity.
103 if (!isValidOptionCharacter(*lowerstr)) return false;
104
105 if (toLowercase(toNarrow(*mixedstr)) != *lowerstr) {
106 return false; // no match
107 }
108
109 ++lowerstr;
110 ++mixedstr;
111 }
112
113 if (*mixedstr) return false; // lowerstr is shorter
114
115 return true;
116}
117
118// Given a command-line argument, return Nothing if it isn't structurally a
119// command-line option, and Some(<the option text>) if it is.
120template <typename CharT>
121mozilla::Maybe<const CharT*> ReadAsOption(const CharT* str) {
122 if (!str) {
123 return Nothing();
124 }
125 if (*str == '-') {
126 str++;
127 if (*str == '-') {
128 str++;
129 }
130 return Some(str);
131 }
132#ifdef XP_WIN
133 if (*str == '/') {
134 return Some(str + 1);
135 }
136#endif
137 return Nothing();
138}
139
140} // namespace internal
141
142using internal::strimatch;
143
144const wchar_t kCommandLineDelimiter[] = L" \t";
145
146enum class CheckArgFlag : uint32_t {
147 None = 0,
148 // (1 << 0) Used to be CheckOSInt
149 RemoveArg = (1 << 1) // Remove the argument from the argv array.
150};
151
152MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CheckArgFlag)inline constexpr mozilla::CastableTypedEnumResult<CheckArgFlag
> operator |( CheckArgFlag a, CheckArgFlag b) { typedef mozilla
::CastableTypedEnumResult<CheckArgFlag> Result; typedef
mozilla::detail::UnsignedIntegerTypeForEnum<CheckArgFlag>
::Type U; return Result(CheckArgFlag(U(a) | U(b))); } inline CheckArgFlag
& operator |=(CheckArgFlag & a, CheckArgFlag b) { return
a = a | b; } inline constexpr mozilla::CastableTypedEnumResult
<CheckArgFlag> operator &( CheckArgFlag a, CheckArgFlag
b) { typedef mozilla::CastableTypedEnumResult<CheckArgFlag
> Result; typedef mozilla::detail::UnsignedIntegerTypeForEnum
<CheckArgFlag>::Type U; return Result(CheckArgFlag(U(a)
& U(b))); } inline CheckArgFlag& operator &=(CheckArgFlag
& a, CheckArgFlag b) { return a = a & b; } inline constexpr
mozilla::CastableTypedEnumResult<CheckArgFlag> operator
^( CheckArgFlag a, CheckArgFlag b) { typedef mozilla::CastableTypedEnumResult
<CheckArgFlag> Result; typedef mozilla::detail::UnsignedIntegerTypeForEnum
<CheckArgFlag>::Type U; return Result(CheckArgFlag(U(a)
^ U(b))); } inline CheckArgFlag& operator ^=(CheckArgFlag
& a, CheckArgFlag b) { return a = a ^ b; } inline constexpr
mozilla::CastableTypedEnumResult<CheckArgFlag> operator
~(CheckArgFlag a) { typedef mozilla::CastableTypedEnumResult<
CheckArgFlag> Result; typedef mozilla::detail::UnsignedIntegerTypeForEnum
<CheckArgFlag>::Type U; return Result(CheckArgFlag(~(U(
a)))); }
153
154/**
155 * Check for a commandline flag. If the flag takes a parameter, the
156 * parameter is returned in aParam. Flags may be in the form -arg or
157 * --arg (or /arg on win32).
158 *
159 * @param aArgc The argc value.
160 * @param aArgv The original argv.
161 * @param aArg the parameter to check. Must be lowercase.
162 * @param aParam if non-null, the -arg <data> will be stored in this pointer.
163 * This is *not* allocated, but rather a pointer to the argv data.
164 * @param aFlags Flags @see CheckArgFlag
165 */
166template <typename CharT>
167inline ArgResult CheckArg(int& aArgc, CharT** aArgv, const char* aArg,
168 const CharT** aParam = nullptr,
169 CheckArgFlag aFlags = CheckArgFlag::RemoveArg) {
170 using internal::ReadAsOption;
171 MOZ_ASSERT(aArgv && aArg)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aArgv && aArg)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aArgv && aArg))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("aArgv && aArg"
, "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/CmdLineAndEnvUtils.h"
, 171); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aArgv && aArg"
")"); do { *((volatile int*)__null) = 171; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
172
173 CharT** curarg = aArgv + 1; // skip argv[0]
174 ArgResult ar = ARG_NONE;
175
176 while (*curarg) {
177 if (const auto arg = ReadAsOption(*curarg)) {
178 if (strimatch(aArg, arg.value())) {
179 if (aFlags & CheckArgFlag::RemoveArg) {
180 RemoveArg(aArgc, curarg);
181 } else {
182 ++curarg;
183 }
184
185 if (!aParam) {
186 ar = ARG_FOUND;
187 break;
188 }
189
190 if (*curarg) {
191 if (ReadAsOption(*curarg)) {
192 return ARG_BAD;
193 }
194
195 *aParam = *curarg;
196
197 if (aFlags & CheckArgFlag::RemoveArg) {
198 RemoveArg(aArgc, curarg);
199 }
200
201 ar = ARG_FOUND;
202 break;
203 }
204
205 return ARG_BAD;
206 }
207 }
208
209 ++curarg;
210 }
211
212 return ar;
213}
214
215template <typename CharT>
216inline ArgResult CheckArg(int& aArgc, CharT** aArgv, const char* aArg,
217 std::nullptr_t,
218 CheckArgFlag aFlags = CheckArgFlag::RemoveArg) {
219 return CheckArg<CharT>(aArgc, aArgv, aArg,
220 static_cast<const CharT**>(nullptr), aFlags);
221}
222
223namespace internal {
224// template <typename T>
225// constexpr bool IsStringRange =
226// std::convertible_to<std::ranges::range_value_t<T>, const char *>;
227
228template <typename CharT, typename ListT>
229// requires IsStringRange<ListT>
230static bool MatchesAnyOf(CharT const* unknown, ListT const& known) {
231 for (const char* k : known) {
232 if (strimatch(k, unknown)) {
233 return true;
234 }
235 }
236 return false;
237}
238
239template <typename CharT, typename ReqContainerT, typename OptContainerT>
240// requires IsStringRange<ReqContainerT> && IsStringRange<OptContainerT>
241inline bool EnsureCommandlineSafeImpl(int aArgc, CharT** aArgv,
242 ReqContainerT const& requiredParams,
243 OptContainerT const& optionalParams) {
244 // We expect either no -osint, or the full commandline to be:
245 //
246 // app -osint [<optional-param>...] <required-param> <required-argument>
247 //
248 // Otherwise, we abort to avoid abuse of other command-line handlers from apps
249 // that do a poor job escaping links they give to the OS.
250 //
251 // Note that the above implies that optional parameters do not themselves take
252 // arguments. This is a security feature, to prevent the possible injection of
253 // additional parameters via such arguments. (See, e.g., bug 384384.)
254
255 static constexpr const char* osintLit = "osint";
256
257 // If "-osint" (or the equivalent) is not present, then this is trivially
258 // satisfied.
259 if (CheckArg(aArgc, aArgv, osintLit, nullptr, CheckArgFlag::None) !=
260 ARG_FOUND) {
261 return true;
262 }
263
264 // There should be at least 4 items present:
265 // <app name> -osint <required param> <arg>.
266 if (aArgc < 4) {
267 return false;
268 }
269
270 // The first parameter must be osint.
271 const auto arg1 = ReadAsOption(aArgv[1]);
272 if (!arg1) return false;
273 if (!strimatch(osintLit, arg1.value())) {
274 return false;
275 }
276 // Following this is any number of optional parameters, terminated by a
277 // required parameter.
278 int pos = 2;
279 while (true) {
280 if (pos >= aArgc) return false;
281
282 auto const arg = ReadAsOption(aArgv[pos]);
283 if (!arg) return false;
284
285 if (MatchesAnyOf(arg.value(), optionalParams)) {
286 ++pos;
287 continue;
288 }
289
290 if (MatchesAnyOf(arg.value(), requiredParams)) {
291 ++pos;
292 break;
293 }
294
295 return false;
296 }
297
298 // There must be one argument remaining...
299 if (pos + 1 != aArgc) return false;
300 // ... which must not be another option.
301 if (ReadAsOption(aArgv[pos])) {
302 return false;
303 }
304
305 // Nothing ill-formed was passed.
306 return true;
307}
308
309// C (and so C++) disallows empty arrays. Rather than require callers to jump
310// through hoops to specify an empty optional-argument list, allow either its
311// omission or its specification as `nullptr`, and do the hoop-jumping here.
312//
313// No such facility is provided for requiredParams, which must have at least one
314// entry.
315template <typename CharT, typename ReqContainerT>
316inline bool EnsureCommandlineSafeImpl(int aArgc, CharT** aArgv,
317 ReqContainerT const& requiredParams,
318 std::nullptr_t _ = nullptr) {
319 struct {
320 inline const char** begin() const { return nullptr; }
321 inline const char** end() const { return nullptr; }
322 } emptyContainer;
323 return EnsureCommandlineSafeImpl(aArgc, aArgv, requiredParams,
324 emptyContainer);
325}
326} // namespace internal
327
328template <typename CharT, typename ReqContainerT,
329 typename OptContainerT = std::nullptr_t>
330inline void EnsureCommandlineSafe(
331 int aArgc, CharT** aArgv, ReqContainerT const& requiredParams,
332 OptContainerT const& optionalParams = nullptr) {
333 if (!internal::EnsureCommandlineSafeImpl(aArgc, aArgv, requiredParams,
334 optionalParams)) {
335 exit(127);
336 }
337}
338
339#if defined(XP_WIN)
340namespace internal {
341
342/**
343 * Attempt to copy the string `s` (considered as a command-line argument) into
344 * the buffer `d` with all necessary escaping and quoting. Returns the number of
345 * characters written.
346 *
347 * If `d` is NULL, doesn't actually write anything to `d`, and merely returns
348 * the number of characters that _would_ have been written.
349 *
350 * (This moderately-awkward conflation ensures that the pre-allocation counting
351 * step and post-allocation copying step use the same algorithm.)
352 */
353inline size_t CopyArgImpl_(wchar_t* d, const wchar_t* s) {
354 size_t len = 0;
355
356 bool const actuallyCopy = d != nullptr;
357 auto const appendChar = [&](wchar_t c) {
358 if (actuallyCopy) {
359 *d++ = c;
360 }
361 len++;
362 };
363
364 bool hasDoubleQuote = wcschr(s, L'"') != nullptr;
365 // Only add doublequotes if...
366 bool addDoubleQuotes =
367 // ... the string is empty, or...
368 *s == '\0' ||
369 // ... the string contains a space or a tab.
370 wcspbrk(s, kCommandLineDelimiter) != nullptr;
371
372 if (addDoubleQuotes) {
373 appendChar('"');
374 }
375
376 if (hasDoubleQuote) {
377 size_t backslashes = 0;
378 while (*s) {
379 if (*s == '\\') {
380 ++backslashes;
381 } else {
382 if (*s == '"') {
383 // Escape the doublequote and all backslashes preceding the
384 // doublequote
385 for (size_t i = 0; i <= backslashes; ++i) {
386 appendChar('\\');
387 }
388 }
389
390 backslashes = 0;
391 }
392
393 appendChar(*s);
394 ++s;
395 }
396 } else {
397 // optimization: just blit
398 auto const src_len = wcslen(s);
399 if (actuallyCopy) {
400 ::wcscpy(d, s);
401 d += src_len;
402 }
403 len += src_len;
404 }
405
406 if (addDoubleQuotes) {
407 appendChar('"');
408 }
409
410 return len;
411}
412
413/**
414 * Compute the space required for the serialized form of this argument. Includes
415 * any additional space needed for quotes and backslash-escapes.
416 */
417inline size_t ArgStrLen(const wchar_t* s) { return CopyArgImpl_(nullptr, s); }
418
419/**
420 * Copy string "s" to string "d", quoting the argument as appropriate and
421 * escaping doublequotes along with any backslashes that immediately precede
422 * doublequotes.
423 * The CRT parses this to retrieve the original argc/argv that we meant,
424 * see STDARGV.C in the MSVC CRT sources.
425 *
426 * @return the end of the string
427 */
428inline wchar_t* ArgToString(wchar_t* d, const wchar_t* s) {
429 return d + CopyArgImpl_(d, s);
430}
431
432} // namespace internal
433
434/**
435 * Creates a command line from a list of arguments.
436 *
437 * @param argc Number of elements in |argv|
438 * @param argv Array of arguments
439 * @param aArgcExtra Number of elements in |aArgvExtra|
440 * @param aArgvExtra Optional array of arguments to be appended to the resulting
441 * command line after those provided by |argv|.
442 */
443inline UniquePtr<wchar_t[]> MakeCommandLine(
444 int argc, const wchar_t* const* argv, int aArgcExtra = 0,
445 const wchar_t* const* aArgvExtra = nullptr) {
446 int i;
447 size_t len = 0;
448
449 // The + 1 for each argument reserves space for either a ' ' or the null
450 // terminator, depending on the position of the argument.
451 for (i = 0; i < argc; ++i) {
452 len += internal::ArgStrLen(argv[i]) + 1;
453 }
454
455 for (i = 0; i < aArgcExtra; ++i) {
456 len += internal::ArgStrLen(aArgvExtra[i]) + 1;
457 }
458
459 // Protect against callers that pass 0 arguments
460 if (len == 0) {
461 len = 1;
462 }
463
464 auto s = MakeUnique<wchar_t[]>(len);
465
466 int totalArgc = argc + aArgcExtra;
467
468 wchar_t* c = s.get();
469 for (i = 0; i < argc; ++i) {
470 c = internal::ArgToString(c, argv[i]);
471 if (i + 1 != totalArgc) {
472 *c = ' ';
473 ++c;
474 }
475 }
476
477 for (i = 0; i < aArgcExtra; ++i) {
478 c = internal::ArgToString(c, aArgvExtra[i]);
479 if (i + 1 != aArgcExtra) {
480 *c = ' ';
481 ++c;
482 }
483 }
484
485 *c = '\0';
486
487 return s;
488}
489
490inline bool SetArgv0ToFullBinaryPath(wchar_t* aArgv[]) {
491 if (!aArgv) {
492 return false;
493 }
494
495 UniquePtr<wchar_t[]> newArgv_0(GetFullBinaryPath());
496 if (!newArgv_0) {
497 return false;
498 }
499
500 // We intentionally leak newArgv_0 into argv[0]
501 aArgv[0] = newArgv_0.release();
502 MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(aArgv[0]);
503 return true;
504}
505
506# if defined(MOZILLA_INTERNAL_API1)
507// This class converts a command line string into an array of the arguments.
508// It's basically the opposite of MakeCommandLine. However, the behavior is
509// different from ::CommandLineToArgvW in several ways, such as escaping a
510// backslash or quoting an argument containing whitespaces. This satisfies
511// the examples at:
512// https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args#results-of-parsing-command-lines
513// https://docs.microsoft.com/en-us/previous-versions/17w5ykft(v=vs.85)
514template <typename T>
515class CommandLineParserWin final {
516 int mArgc;
517 T** mArgv;
518
519 void Release() {
520 if (mArgv) {
521 while (mArgc) {
522 delete[] mArgv[--mArgc];
523 }
524 delete[] mArgv;
525 mArgv = nullptr;
526 }
527 }
528
529 public:
530 CommandLineParserWin() : mArgc(0), mArgv(nullptr) {}
531 ~CommandLineParserWin() { Release(); }
532
533 CommandLineParserWin(const CommandLineParserWin&) = delete;
534 CommandLineParserWin(CommandLineParserWin&&) = delete;
535 CommandLineParserWin& operator=(const CommandLineParserWin&) = delete;
536 CommandLineParserWin& operator=(CommandLineParserWin&&) = delete;
537
538 int Argc() const { return mArgc; }
539 const T* const* Argv() const { return mArgv; }
540
541 // Returns the number of characters handled
542 int HandleCommandLine(const nsTSubstring<T>& aCmdLineString) {
543 Release();
544
545 if (aCmdLineString.IsEmpty()) {
546 return 0;
547 }
548
549 int justCounting = 1;
550 // Flags, etc.
551 int init = 1;
552 int between, quoted, bSlashCount;
553 const T* p;
554 const T* const pEnd = aCmdLineString.EndReading();
555 nsTAutoString<T> arg;
556
557 // We loop if we've not finished the second pass through.
558 while (1) {
559 // Initialize if required.
560 if (init) {
561 p = aCmdLineString.BeginReading();
562 between = 1;
563 mArgc = quoted = bSlashCount = 0;
564
565 init = 0;
566 }
567
568 const T charCurr = (p < pEnd) ? *p : 0;
569 const T charNext = (p + 1 < pEnd) ? *(p + 1) : 0;
570
571 if (between) {
572 // We are traversing whitespace between args.
573 // Check for start of next arg.
574 if (charCurr != 0 && !wcschr(kCommandLineDelimiter, charCurr)) {
575 // Start of another arg.
576 between = 0;
577 arg.Truncate();
578 switch (charCurr) {
579 case '\\':
580 // Count the backslash.
581 bSlashCount = 1;
582 break;
583 case '"':
584 // Remember we're inside quotes.
585 quoted = 1;
586 break;
587 default:
588 // Add character to arg.
589 arg += charCurr;
590 break;
591 }
592 } else {
593 // Another space between args, ignore it.
594 }
595 } else {
596 // We are processing the contents of an argument.
597 // Check for whitespace or end.
598 if (charCurr == 0 ||
599 (!quoted && wcschr(kCommandLineDelimiter, charCurr))) {
600 // Process pending backslashes (interpret them
601 // literally since they're not followed by a ").
602 while (bSlashCount) {
603 arg += '\\';
604 bSlashCount--;
605 }
606 // End current arg.
607 if (!justCounting) {
608 mArgv[mArgc] = new T[arg.Length() + 1];
609 memcpy(mArgv[mArgc], arg.get(), (arg.Length() + 1) * sizeof(T));
610 }
611 mArgc++;
612 // We're now between args.
613 between = 1;
614 } else {
615 // Still inside argument, process the character.
616 switch (charCurr) {
617 case '"':
618 // First, digest preceding backslashes (if any).
619 while (bSlashCount > 1) {
620 // Put one backsplash in arg for each pair.
621 arg += '\\';
622 bSlashCount -= 2;
623 }
624 if (bSlashCount) {
625 // Quote is literal.
626 arg += '"';
627 bSlashCount = 0;
628 } else {
629 // Quote starts or ends a quoted section.
630 if (quoted) {
631 // Check for special case of consecutive double
632 // quotes inside a quoted section.
633 if (charNext == '"') {
634 // This implies a literal double-quote. Fake that
635 // out by causing next double-quote to look as
636 // if it was preceded by a backslash.
637 bSlashCount = 1;
638 } else {
639 quoted = 0;
640 }
641 } else {
642 quoted = 1;
643 }
644 }
645 break;
646 case '\\':
647 // Add to count.
648 bSlashCount++;
649 break;
650 default:
651 // Accept any preceding backslashes literally.
652 while (bSlashCount) {
653 arg += '\\';
654 bSlashCount--;
655 }
656 // Just add next char to the current arg.
657 arg += charCurr;
658 break;
659 }
660 }
661 }
662
663 // Check for end of input.
664 if (charCurr) {
665 // Go to next character.
666 p++;
667 } else {
668 // If on first pass, go on to second.
669 if (justCounting) {
670 // Allocate argv array.
671 mArgv = new T*[mArgc];
672
673 // Start second pass
674 justCounting = 0;
675 init = 1;
676 } else {
677 // Quit.
678 break;
679 }
680 }
681 }
682
683 return p - aCmdLineString.BeginReading();
684 }
685};
686# endif // defined(MOZILLA_INTERNAL_API)
687
688#endif // defined(XP_WIN)
689
690// SaveToEnv and EnvHasValue are only available on Windows or when
691// MOZILLA_INTERNAL_API is defined
692#if defined(MOZILLA_INTERNAL_API1) || defined(XP_WIN)
693
694// Save literal putenv string to environment variable.
695MOZ_NEVER_INLINE__attribute__((noinline)) inline void SaveToEnv(const char* aEnvString) {
696# if defined(MOZILLA_INTERNAL_API1)
697 char* expr = strdup(aEnvString);
26
Memory is allocated
698 if (expr) {
27
Assuming 'expr' is non-null
28
Taking true branch
699 PR_SetEnv(expr);
700 }
701
702 // We intentionally leak |expr| here since it is required by PR_SetEnv.
703 MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(expr);
704# elif defined(XP_WIN)
705 // This is the same as the NSPR implementation
706 // (Note that we don't need to do a strdup for this case; the CRT makes a
707 // copy)
708 _putenv(aEnvString);
709# endif
710}
29
Potential leak of memory pointed to by 'expr'
711
712inline bool EnvHasValue(const char* aVarName) {
713# if defined(MOZILLA_INTERNAL_API1)
714 const char* val = PR_GetEnv(aVarName);
715 return val && *val;
716# elif defined(XP_WIN)
717 // This is the same as the NSPR implementation
718 const char* val = getenv(aVarName);
719 return val && *val;
720# endif
721}
722
723#endif // end windows/internal_api-only definitions
724
725#ifndef NS_NO_XPCOM
726already_AddRefed<nsIFile> GetFileFromEnv(const char* name);
727#endif
728
729} // namespace mozilla
730
731#endif // mozilla_CmdLineAndEnvUtils_h