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