Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre/./../../../toolkit/xre/nsXREDirProvider.cpp
Warning:line 297, column 7
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_toolkit_xre1.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=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/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="157.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=157.0a1 -D MOZ_APP_VERSION_DISPLAY=157.0a1 -D APP_VERSION=157.0a1 -D APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384} -D MOZ_BUILD_APP_IS_BROWSER -D MAR_NSS -D TOPOBJDIR=/root/firefox-clang/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 /root/firefox-clang/toolkit/xre -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre -I /root/firefox-clang/toolkit/components/remote -I /root/firefox-clang/widget -I /root/firefox-clang/widget/gtk -I /root/firefox-clang/toolkit/components/printingui -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/other-licenses/nsis/Contrib/CityHash/cityhash -I /root/firefox-clang/toolkit/components/find -I /root/firefox-clang/toolkit/components/printingui/ipc -I /root/firefox-clang/toolkit/components/windowwatcher -I /root/firefox-clang/toolkit/mozapps/update/common -I /root/firefox-clang/toolkit/profile -I /root/firefox-clang/config -I /root/firefox-clang/dom/base -I /root/firefox-clang/dom/commandhandler -I /root/firefox-clang/dom/ipc -I /root/firefox-clang/dom/webbrowserpersist -I /root/firefox-clang/js/xpconnect/loader -I /root/firefox-clang/testing/gtest/mozilla -I /root/firefox-clang/third_party/sqlite3/ext -I /root/firefox-clang/toolkit/crashreporter -I /root/firefox-clang/xpcom/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/uuid -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gtk-3.0/unix-print -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cloudproviders -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/fribidi -I /usr/include/harfbuzz -I /usr/include/atk-1.0 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/pixman-1 -I /usr/include/sysprof-6 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -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-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 -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_toolkit_xre1.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "nsAppRunner.h"
6#include "nsXREDirProvider.h"
7#ifndef ANDROID
8# include "commonupdatedir.h"
9#endif
10
11#include "jsapi.h"
12#include "xpcpublic.h"
13#include "prprf.h"
14#include "prenv.h"
15
16#include "nsIAppStartup.h"
17#include "nsIFile.h"
18#include "nsIObserver.h"
19#include "nsIObserverService.h"
20#include "nsISimpleEnumerator.h"
21#include "nsIToolkitProfileService.h"
22#include "nsIXULRuntime.h"
23#include "commonupdatedir.h"
24
25#include "nsAppDirectoryServiceDefs.h"
26#include "nsDirectoryServiceDefs.h"
27#include "nsDirectoryServiceUtils.h"
28#include "nsXULAppAPI.h"
29#include "nsCategoryManagerUtils.h"
30
31#include "nsDependentString.h"
32#include "nsCOMArray.h"
33#include "nsArrayEnumerator.h"
34#include "nsEnumeratorUtils.h"
35#include "nsReadableUtils.h"
36
37#include "SpecialSystemDirectory.h"
38
39#include "mozilla/dom/ScriptSettings.h"
40
41#include "mozilla/AppShutdown.h"
42#include "mozilla/AutoRestore.h"
43#ifdef MOZ_BACKGROUNDTASKS1
44# include "mozilla/BackgroundTasks.h"
45#endif
46#include "mozilla/CmdLineAndEnvUtils.h"
47#include "mozilla/Components.h"
48#include "mozilla/DebugOnly.h"
49#include "mozilla/Services.h"
50#include "mozilla/Omnijar.h"
51#include "mozilla/Preferences.h"
52#include "mozilla/ProfilerLabels.h"
53#include "mozilla/glean/ToolkitProfileMetrics.h"
54#include "mozilla/glean/ToolkitXreMetrics.h"
55#include "mozilla/Try.h"
56#include "mozilla/Utf8.h"
57#include "mozilla/XREAppData.h"
58#include "nsPrintfCString.h"
59
60#ifdef MOZ_THUNDERBIRD
61# ifdef XP_MACOSX
62# include "MacApplicationDelegate.h"
63# endif
64# include "ScopedNSSTypes.h"
65# include "nsNSSComponent.h"
66#endif
67
68#include <stdlib.h>
69
70#ifdef XP_WIN
71# include <windows.h>
72# include <shlobj.h>
73# include "WinUtils.h"
74#endif
75#ifdef XP_MACOSX
76# ifdef NIGHTLY_BUILD1
77# include "AppGroupPath.h"
78# endif
79# include "nsILocalFileMac.h"
80// for chflags()
81# include <sys/stat.h>
82# include <unistd.h>
83#endif
84#ifdef XP_IOS
85# include "UIKitDirProvider.h"
86#endif
87
88#if defined(XP_MACOSX)
89# define APP_REGISTRY_NAME"appreg" "Application Registry"
90#elif defined(XP_WIN)
91# define APP_REGISTRY_NAME"appreg" "registry.dat"
92#else
93# define APP_REGISTRY_NAME"appreg" "appreg"
94#endif
95
96#define PREF_OVERRIDE_DIRNAME"preferences" "preferences"
97
98nsXREDirProvider* gDirServiceProvider = nullptr;
99nsIFile* gDataDirHomeLocal = nullptr;
100nsIFile* gDataDirHome = nullptr;
101constinit nsCOMPtr<nsIFile> gDataDirProfileLocal{};
102constinit nsCOMPtr<nsIFile> gDataDirProfile{};
103
104#if defined(MOZ_WIDGET_GTK1)
105nsXREDirProvider::legacyOrXDGHomeTelemetry gXdgTelemetry =
106 nsXREDirProvider::legacyOrXDGHomeTelemetry::empty;
107#endif // defined(MOZ_WIDGET_GTK)
108
109// These are required to allow nsXREDirProvider to be usable in xpcshell tests.
110// where gAppData is null.
111#if defined(XP_MACOSX) || defined(XP_UNIX1)
112static const char* GetAppName() {
113 if (gAppData) {
114 return gAppData->name;
115 }
116 return nullptr;
117}
118#endif
119
120#ifdef XP_MACOSX
121static const char* GetAppVendor() {
122 if (gAppData) {
123 return gAppData->vendor;
124 }
125 return nullptr;
126}
127#endif
128
129nsXREDirProvider::nsXREDirProvider() { gDirServiceProvider = this; }
130
131nsXREDirProvider::~nsXREDirProvider() {
132 gDirServiceProvider = nullptr;
133 gDataDirHomeLocal = nullptr;
134 gDataDirHome = nullptr;
135}
136
137already_AddRefed<nsXREDirProvider> nsXREDirProvider::GetSingleton() {
138 if (!gDirServiceProvider) {
139 new nsXREDirProvider(); // This sets gDirServiceProvider
140 }
141 return do_AddRef(gDirServiceProvider);
142}
143
144nsresult nsXREDirProvider::Initialize(nsIFile* aXULAppDir, nsIFile* aGREDir) {
145 NS_ENSURE_ARG(aXULAppDir)do { if ((__builtin_expect(!!(!(aXULAppDir)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aXULAppDir" ") failed",
nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 145)
; return NS_ERROR_INVALID_ARG; } } while (false)
;
146 NS_ENSURE_ARG(aGREDir)do { if ((__builtin_expect(!!(!(aGREDir)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aGREDir" ") failed", nullptr
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 146); return
NS_ERROR_INVALID_ARG; } } while (false)
;
147
148 mXULAppDir = aXULAppDir;
149 mGREDir = aGREDir;
150 nsCOMPtr<nsIFile> binaryPath;
151 nsresult rv = XRE_GetBinaryPath(getter_AddRefs(binaryPath));
152 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 152); return rv; } } while (false)
;
153 return binaryPath->GetParent(getter_AddRefs(mGREBinDir));
154}
155
156nsresult nsXREDirProvider::SetProfile(nsIFile* aDir, nsIFile* aLocalDir) {
157 MOZ_ASSERT(aDir && aLocalDir, "We don't support no-profile apps!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDir && aLocalDir)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDir && aLocalDir)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("aDir && aLocalDir"
" (" "We don't support no-profile apps!" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 157); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDir && aLocalDir"
") (" "We don't support no-profile apps!" ")"); do { MOZ_CrashSequence
(__null, 157); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
158 MOZ_ASSERT(!mProfileDir && !mProfileLocalDir,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir && !mProfileLocalDir)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mProfileDir && !mProfileLocalDir))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mProfileDir && !mProfileLocalDir"
" (" "You may only set the profile directories once" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 159); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir && !mProfileLocalDir"
") (" "You may only set the profile directories once" ")"); do
{ MOZ_CrashSequence(__null, 159); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
159 "You may only set the profile directories once")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir && !mProfileLocalDir)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mProfileDir && !mProfileLocalDir))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mProfileDir && !mProfileLocalDir"
" (" "You may only set the profile directories once" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 159); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir && !mProfileLocalDir"
") (" "You may only set the profile directories once" ")"); do
{ MOZ_CrashSequence(__null, 159); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
160
161 nsresult rv = EnsureDirectoryExists(aDir);
162 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 162); return rv; } } while (false)
;
163
164 rv = EnsureDirectoryExists(aLocalDir);
165 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 165); return rv; } } while (false)
;
166
167#ifndef XP_WIN
168 nsAutoCString profilePath;
169 rv = aDir->GetNativePath(profilePath);
170 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 170); return rv; } } while (false)
;
171
172 nsAutoCString localProfilePath;
173 rv = aLocalDir->GetNativePath(localProfilePath);
174 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 174); return rv; } } while (false)
;
175
176 if (!mozilla::IsUtf8(profilePath) || !mozilla::IsUtf8(localProfilePath)) {
177 PR_fprintf(
178 PR_STDERRPR_GetSpecialFD(PR_StandardError),
179 "Error: The profile path is not valid UTF-8. Unable to continue.\n");
180 return NS_ERROR_FAILURE;
181 }
182#endif
183
184#ifdef XP_MACOSX
185 bool same;
186 if (NS_SUCCEEDED(aDir->Equals(aLocalDir, &same))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aDir->Equals(aLocalDir
, &same))), 1)))
&& !same) {
187 // Ensure that the cache directory is not indexed by Spotlight
188 // (bug 718910). At least on OS X, the cache directory (under
189 // ~/Library/Caches/) is always the "local" user profile
190 // directory. This is confusing, since *both* user profile
191 // directories are "local" (they both exist under the user's
192 // home directory). But this usage dates back at least as far
193 // as the patch for bug 291033, where "local" seems to mean
194 // "suitable for temporary storage". Don't hide the cache
195 // directory if by some chance it and the "non-local" profile
196 // directory are the same -- there are bad side effects from
197 // hiding a profile directory under /Library/Application Support/
198 // (see bug 801883).
199 nsAutoCString cacheDir;
200 if (NS_SUCCEEDED(aLocalDir->GetNativePath(cacheDir))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aLocalDir->GetNativePath
(cacheDir))), 1)))
) {
201 if (chflags(cacheDir.get(), UF_HIDDEN)) {
202 NS_WARNING("Failed to set Cache directory to HIDDEN.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to set Cache directory to HIDDEN."
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 202
)
;
203 }
204 }
205 }
206#endif
207
208 mProfileDir = aDir;
209 mProfileLocalDir = aLocalDir;
210 return NS_OK;
211}
212
213NS_IMPL_QUERY_INTERFACE(nsXREDirProvider, nsIDirectoryServiceProvider,nsresult nsXREDirProvider::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 215); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsXREDirProvider, nsIDirectoryServiceProvider
>, int32_t( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIDirectoryServiceProvider2>, int32_t
( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider2
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIXREDirProvider>, int32_t( reinterpret_cast
<char*>(static_cast<nsIXREDirProvider*>((nsXREDirProvider
*)0x1000)) - reinterpret_cast<char*>((nsXREDirProvider*
)0x1000))}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsIProfileStartup>, int32_t( reinterpret_cast<char*>
(static_cast<nsIProfileStartup*>((nsXREDirProvider*)0x1000
)) - reinterpret_cast<char*>((nsXREDirProvider*)0x1000)
)}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000))) - reinterpret_cast<char
*>((nsXREDirProvider*)0x1000))}, { nullptr, 0 } } ; static_assert
(std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
214 nsIDirectoryServiceProvider2, nsIXREDirProvider,nsresult nsXREDirProvider::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 215); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsXREDirProvider, nsIDirectoryServiceProvider
>, int32_t( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIDirectoryServiceProvider2>, int32_t
( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider2
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIXREDirProvider>, int32_t( reinterpret_cast
<char*>(static_cast<nsIXREDirProvider*>((nsXREDirProvider
*)0x1000)) - reinterpret_cast<char*>((nsXREDirProvider*
)0x1000))}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsIProfileStartup>, int32_t( reinterpret_cast<char*>
(static_cast<nsIProfileStartup*>((nsXREDirProvider*)0x1000
)) - reinterpret_cast<char*>((nsXREDirProvider*)0x1000)
)}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000))) - reinterpret_cast<char
*>((nsXREDirProvider*)0x1000))}, { nullptr, 0 } } ; static_assert
(std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
215 nsIProfileStartup)nsresult nsXREDirProvider::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 215); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsXREDirProvider, nsIDirectoryServiceProvider
>, int32_t( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIDirectoryServiceProvider2>, int32_t
( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider2
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIXREDirProvider>, int32_t( reinterpret_cast
<char*>(static_cast<nsIXREDirProvider*>((nsXREDirProvider
*)0x1000)) - reinterpret_cast<char*>((nsXREDirProvider*
)0x1000))}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsIProfileStartup>, int32_t( reinterpret_cast<char*>
(static_cast<nsIProfileStartup*>((nsXREDirProvider*)0x1000
)) - reinterpret_cast<char*>((nsXREDirProvider*)0x1000)
)}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000))) - reinterpret_cast<char
*>((nsXREDirProvider*)0x1000))}, { nullptr, 0 } } ; static_assert
(std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
216
217NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
218nsXREDirProvider::AddRef() { return 1; }
219
220NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
221nsXREDirProvider::Release() { return 0; }
222
223nsresult nsXREDirProvider::GetUserProfilesRootDir(nsIFile** aResult) {
224 nsCOMPtr<nsIFile> file;
225 nsresult rv = NS_OK;
226#if defined(XP_MACOSX) && defined(NIGHTLY_BUILD1)
227 const char* appGroup = PR_GetEnv("MOZ_APP_GROUP");
228 if (appGroup && *appGroup && strcmp(appGroup, "0") != 0) {
229 nsCOMPtr<nsIFile> group;
230 rv = GetAppGroupContainerBase(getter_AddRefs(group));
231 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && group) {
232 rv = group->AppendNative("Library"_ns);
233 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 233); return rv; } } while (false)
;
234 rv = group->AppendNative("Application Support"_ns);
235 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 235); return rv; } } while (false)
;
236 rv = group->AppendNative("Profiles"_ns);
237 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 237); return rv; } } while (false)
;
238 file = group;
239 }
240 }
241#endif
242 if (!file) {
243 rv = GetUserDataDirectory(getter_AddRefs(file), false);
244 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 244); return rv; } } while (false)
;
245#if !defined(XP_UNIX1) || defined(XP_MACOSX)
246 rv = file->AppendNative("Profiles"_ns);
247#endif
248 // We must create the profile directory here if it does not exist.
249 nsresult tmp = EnsureDirectoryExists(file);
250 if (NS_FAILED(tmp)((bool)(__builtin_expect(!!(NS_FAILED_impl(tmp)), 0)))) {
251 rv = tmp;
252 }
253
254#if defined(MOZ_WIDGET_GTK1)
255 switch (gXdgTelemetry) {
256 case legacyOrXDGHomeTelemetry::legacyExists:
257 mozilla::glean::profiles::creation_place.Get("legacy_existing"_ns)
258 .Add(1);
259 break;
260 case legacyOrXDGHomeTelemetry::legacyForced:
261 mozilla::glean::profiles::creation_place.Get("legacy_forced"_ns).Add(1);
262 break;
263 case legacyOrXDGHomeTelemetry::xdgDefault:
264 mozilla::glean::profiles::creation_place.Get("xdg_default"_ns).Add(1);
265 break;
266 case legacyOrXDGHomeTelemetry::xdgConfigHome:
267 mozilla::glean::profiles::creation_place.Get("xdg_config"_ns).Add(1);
268 break;
269 default: {
270 nsAutoCString nativePath;
271 nsresult rv_conv = file->GetNativePath(nativePath);
272 if (NS_SUCCEEDED(rv_conv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv_conv)), 1)))) {
273 NS_WARNING(nsPrintfCString(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 276)
274 "Recording no telemetry value with profile path %s",NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 276)
275 nativePath.get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 276)
276 .get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 276)
;
277 }
278 } break;
279 }
280#endif // defined(MOZ_WIDGET_GTK)
281 }
282 file.swap(*aResult);
283 return rv;
284}
285
286nsresult nsXREDirProvider::GetUserProfilesLocalDir(nsIFile** aResult) {
287 nsCOMPtr<nsIFile> file;
288 nsresult rv = GetUserDataDirectory(getter_AddRefs(file), true);
289
290 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
291#if !defined(XP_UNIX1) || defined(XP_MACOSX)
292 rv = file->AppendNative("Profiles"_ns);
293#endif
294 // We must create the profile directory here if it does not exist.
295 nsresult tmp = EnsureDirectoryExists(file);
296 if (NS_FAILED(tmp)((bool)(__builtin_expect(!!(NS_FAILED_impl(tmp)), 0)))) {
297 rv = tmp;
Value stored to 'rv' is never read
298 }
299 }
300 file.swap(*aResult);
301 return NS_OK;
302}
303
304#ifdef MOZ_BACKGROUNDTASKS1
305nsresult nsXREDirProvider::GetBackgroundTasksProfilesRootDir(
306 nsIFile** aResult) {
307 nsCOMPtr<nsIFile> file;
308 nsresult rv = GetUserDataDirectory(getter_AddRefs(file), false);
309
310 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
311# if !defined(XP_UNIX1) || defined(XP_MACOSX)
312 // Sibling to regular user "Profiles" directory.
313 rv = file->AppendNative("Background Tasks Profiles"_ns);
314# endif
315 // We must create the directory here if it does not exist.
316 nsresult tmp = EnsureDirectoryExists(file);
317 if (NS_FAILED(tmp)((bool)(__builtin_expect(!!(NS_FAILED_impl(tmp)), 0)))) {
318 rv = tmp;
319 }
320 }
321 file.swap(*aResult);
322 return rv;
323}
324#endif
325
326#if defined(XP_UNIX1) || defined(XP_MACOSX)
327/**
328 * Get the directory that is the parent of the system-wide directories
329 * for extensions and native manifests.
330 *
331 * On OSX this is /Library/Application Support/Mozilla
332 * On Linux this is /usr/{lib,lib64}/mozilla
333 * (for 32- and 64-bit systems respsectively)
334 */
335static nsresult GetSystemParentDirectory(nsIFile** aFile) {
336 nsresult rv;
337 nsCOMPtr<nsIFile> localDir;
338# if defined(XP_MACOSX)
339 rv = GetOSXFolderType(kOnSystemDisk, kApplicationSupportFolderType,
340 getter_AddRefs(localDir));
341 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
342 rv = localDir->AppendNative("Mozilla"_ns);
343 }
344# else
345 constexpr auto dirname =
346# ifdef HAVE_USR_LIB64_DIR
347 "/usr/lib64/mozilla"_ns
348# elif defined(__OpenBSD__) || defined(__FreeBSD__)
349 "/usr/local/lib/mozilla"_ns
350# else
351 "/usr/lib/mozilla"_ns
352# endif
353 ;
354 rv = NS_NewNativeLocalFile(dirname, getter_AddRefs(localDir));
355# endif
356
357 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
358 localDir.forget(aFile);
359 }
360 return rv;
361}
362#endif
363
364NS_IMETHODIMPnsresult
365nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
366 nsIFile** aFile) {
367 *aPersistent = true;
368 nsresult rv = NS_ERROR_FAILURE;
369
370 nsCOMPtr<nsIFile> file;
371
372 if (!strcmp(aProperty, NS_APP_USER_PROFILE_LOCAL_50_DIR"ProfLD") ||
373 !strcmp(aProperty, NS_APP_PROFILE_LOCAL_DIR_STARTUP"ProfLDS")) {
374 if (mProfileLocalDir) {
375 rv = mProfileLocalDir->Clone(getter_AddRefs(file));
376 } else {
377 // Profile directories are only set up in the parent process.
378 // We don't expect every caller to check if they are in the right process,
379 // so fail immediately to avoid warning spam.
380 NS_WARNING_ASSERTION(!XRE_IsParentProcess(),do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 381); } } while
(false)
381 "tried to get profile in parent too early")do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 381); } } while
(false)
;
382 return NS_ERROR_FAILURE;
383 }
384 } else if (!strcmp(aProperty, NS_APP_USER_PROFILE_50_DIR"ProfD") ||
385 !strcmp(aProperty, NS_APP_PROFILE_DIR_STARTUP"ProfDS")) {
386 rv = GetProfileStartupDir(getter_AddRefs(file));
387 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
388 return rv;
389 }
390 } else if (!strcmp(aProperty, NS_GRE_DIR"GreD")) {
391 // On Android, internal files are inside the APK, a zip file, so this
392 // folder doesn't really make sense.
393#if !defined(MOZ_WIDGET_ANDROID)
394 rv = mGREDir->Clone(getter_AddRefs(file));
395#endif // !defined(MOZ_WIDGET_ANDROID)
396 } else if (!strcmp(aProperty, NS_GRE_BIN_DIR"GreBinD")) {
397 rv = mGREBinDir->Clone(getter_AddRefs(file));
398 } else if (!strcmp(aProperty, NS_OS_CURRENT_PROCESS_DIR"CurProcD") ||
399 !strcmp(aProperty, NS_APP_INSTALL_CLEANUP_DIR"XPIClnupD")) {
400 rv = GetAppDir()->Clone(getter_AddRefs(file));
401 } else if (!strcmp(aProperty, NS_APP_PREF_DEFAULTS_50_DIR"PrfDef")) {
402 // Same as NS_GRE_DIR
403#if !defined(MOZ_WIDGET_ANDROID)
404 // return the GRE default prefs directory here, and the app default prefs
405 // directory (if applicable) in NS_APP_PREFS_DEFAULTS_DIR_LIST.
406 rv = mGREDir->Clone(getter_AddRefs(file));
407 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 407); return rv; } } while (false)
;
408 rv = file->AppendNative("defaults"_ns);
409 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 409); return rv; } } while (false)
;
410 rv = file->AppendNative("pref"_ns);
411#endif // !defined(MOZ_WIDGET_ANDROID)
412 } else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_DIR"AppRegD") ||
413 !strcmp(aProperty, XRE_USER_APP_DATA_DIR"UAppData")) {
414 rv = GetUserAppDataDirectory(getter_AddRefs(file));
415 }
416#if defined(XP_UNIX1) || defined(XP_MACOSX)
417 else if (!strcmp(aProperty, XRE_SYS_NATIVE_MANIFESTS"XRESysNativeManifests")) {
418 rv = ::GetSystemParentDirectory(getter_AddRefs(file));
419 } else if (!strcmp(aProperty, XRE_USER_NATIVE_MANIFESTS"XREUserNativeManifests")) {
420 // Keep forcing the legacy path for compatibility
421 rv = GetUserDataDirectoryHome(getter_AddRefs(file), /* aLocal */ false,
422 /* aForceLegacy */ true);
423 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 423); return rv; } } while (false)
;
424# if defined(XP_MACOSX)
425 rv = file->AppendNative("Mozilla"_ns);
426# else // defined(XP_MACOSX)
427 rv = file->AppendNative(".mozilla"_ns);
428# endif // defined(XP_MACOSX)
429 }
430#endif // defined(XP_UNIX) || defined(XP_MACOSX)
431 else if (!strcmp(aProperty, XRE_UPDATE_ROOT_DIR"UpdRootD")) {
432 rv = GetUpdateRootDir(getter_AddRefs(file));
433 } else if (!strcmp(aProperty, XRE_OLD_UPDATE_ROOT_DIR"OldUpdRootD")) {
434 rv = GetUpdateRootDir(getter_AddRefs(file), true);
435 } else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_FILE"AppRegF")) {
436 rv = GetUserAppDataDirectory(getter_AddRefs(file));
437 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 437); return rv; } } while (false)
;
438 rv = file->AppendNative(nsLiteralCString(APP_REGISTRY_NAME"appreg"));
439 } else if (!strcmp(aProperty, NS_APP_USER_PROFILES_ROOT_DIR"DefProfRt")) {
440 rv = GetUserProfilesRootDir(getter_AddRefs(file));
441 } else if (!strcmp(aProperty, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR"DefProfLRt")) {
442 rv = GetUserProfilesLocalDir(getter_AddRefs(file));
443 } else if (!strcmp(aProperty, XRE_EXECUTABLE_FILE"XREExeF")) {
444 rv = XRE_GetBinaryPath(getter_AddRefs(file));
445 }
446#if defined(XP_UNIX1) || defined(XP_MACOSX)
447 else if (!strcmp(aProperty, XRE_SYS_LOCAL_EXTENSION_PARENT_DIR"XRESysLExtPD")) {
448# ifdef ENABLE_SYSTEM_EXTENSION_DIRS1
449 rv = GetSystemExtensionsDirectory(getter_AddRefs(file));
450# endif
451 }
452#endif // defined(XP_UNIX) || defined(XP_MACOSX)
453#if defined(XP_UNIX1) && !defined(XP_MACOSX)
454 else if (!strcmp(aProperty, XRE_SYS_SHARE_EXTENSION_PARENT_DIR"XRESysSExtPD")) {
455# ifdef ENABLE_SYSTEM_EXTENSION_DIRS1
456# if defined(__OpenBSD__) || defined(__FreeBSD__)
457 static const char* const sysLExtDir = "/usr/local/share/mozilla/extensions";
458# else
459 static const char* const sysLExtDir = "/usr/share/mozilla/extensions";
460# endif
461 rv = NS_NewNativeLocalFile(nsDependentCString(sysLExtDir),
462 getter_AddRefs(file));
463# endif
464 }
465#endif // defined(XP_UNIX) && !defined(XP_MACOSX)
466 else if (!strcmp(aProperty, XRE_USER_SYS_EXTENSION_DIR"XREUSysExt")) {
467#ifdef ENABLE_SYSTEM_EXTENSION_DIRS1
468 rv = GetSysUserExtensionsDirectory(getter_AddRefs(file));
469#endif
470 } else if (!strcmp(aProperty, XRE_USER_RUNTIME_DIR"XREUserRunTimeDir")) {
471#if defined(XP_UNIX1)
472 nsPrintfCString path("/run/user/%d/%s/", getuid(), GetAppName());
473 ToLowerCase(path);
474 rv = NS_NewNativeLocalFile(path, getter_AddRefs(file));
475#endif
476 } else if (!strcmp(aProperty, XRE_APP_DISTRIBUTION_DIR"XREAppDist")) {
477 bool persistent = false;
478 rv = GetFile(NS_GRE_DIR"GreD", &persistent, getter_AddRefs(file));
479 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 479); return rv; } } while (false)
;
480 rv = file->AppendNative("distribution"_ns);
481 } else if (!strcmp(aProperty, XRE_APP_FEATURES_DIR"XREAppFeat")) {
482 rv = GetAppDir()->Clone(getter_AddRefs(file));
483 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 483); return rv; } } while (false)
;
484 rv = file->AppendNative("features"_ns);
485 } else if (!strcmp(aProperty, XRE_ADDON_APP_DIR"XREAddonAppDir")) {
486 nsCOMPtr<nsIDirectoryServiceProvider> dirsvc(
487 do_GetService("@mozilla.org/file/directory_service;1", &rv));
488 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 488); return rv; } } while (false)
;
489 bool unused;
490 rv = dirsvc->GetFile("XCurProcD", &unused, getter_AddRefs(file));
491 } else if (!strcmp(aProperty, NS_APP_USER_CHROME_DIR"UChrm")) {
492 // It isn't clear why this uses GetProfileStartupDir instead of
493 // GetProfileDir. It could theoretically matter in a non-main
494 // process where some other directory provider has defined
495 // NS_APP_USER_PROFILE_50_DIR. In that scenario, using
496 // GetProfileStartupDir means this will fail instead of succeed.
497 rv = GetProfileStartupDir(getter_AddRefs(file));
498 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
499 return rv;
500 }
501 rv = file->AppendNative("chrome"_ns);
502 } else if (!strcmp(aProperty, NS_APP_PREFS_50_DIR"PrefD")) {
503 rv = GetProfileDir(getter_AddRefs(file));
504 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
505 return rv;
506 }
507 } else if (!strcmp(aProperty, NS_APP_PREFS_50_FILE"PrefF")) {
508 rv = GetProfileDir(getter_AddRefs(file));
509 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
510 return rv;
511 }
512 rv = file->AppendNative("prefs.js"_ns);
513 } else if (!strcmp(aProperty, NS_APP_PREFS_OVERRIDE_DIR"PrefDOverride")) {
514 rv = GetProfileDir(getter_AddRefs(file));
515 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
516 return rv;
517 }
518 rv = file->AppendNative(nsLiteralCString(PREF_OVERRIDE_DIRNAME"preferences"));
519 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 519); return rv; } } while (false)
;
520 rv = EnsureDirectoryExists(file);
521 } else {
522 // We don't know anything about this property. Fail without warning, because
523 // otherwise we'll get too much warning spam due to
524 // nsDirectoryService::Get() trying everything it gets with every provider.
525 return NS_ERROR_FAILURE;
526 }
527
528 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 528); return rv; } } while (false)
;
529 NS_ENSURE_TRUE(file, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(file)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "file" ") failed", nullptr
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 529); return
NS_ERROR_FAILURE; } } while (false)
;
530
531 file.forget(aFile);
532 return NS_OK;
533}
534
535static void LoadDirIntoArray(nsIFile* dir, const char* const* aAppendList,
536 nsCOMArray<nsIFile>& aDirectories) {
537 if (!dir) return;
538
539 nsCOMPtr<nsIFile> subdir;
540 dir->Clone(getter_AddRefs(subdir));
541 if (!subdir) return;
542
543 for (const char* const* a = aAppendList; *a; ++a) {
544 subdir->AppendNative(nsDependentCString(*a));
545 }
546
547 bool exists;
548 if (NS_SUCCEEDED(subdir->Exists(&exists))((bool)(__builtin_expect(!!(!NS_FAILED_impl(subdir->Exists
(&exists))), 1)))
&& exists) {
549 aDirectories.AppendObject(subdir);
550 }
551}
552
553static const char* const kAppendPrefDir[] = {"defaults", "preferences",
554 nullptr};
555#ifdef MOZ_BACKGROUNDTASKS1
556static const char* const kAppendBackgroundTasksPrefDir[] = {
557 "defaults", "backgroundtasks", nullptr};
558#endif
559
560NS_IMETHODIMPnsresult
561nsXREDirProvider::GetFiles(const char* aProperty,
562 nsISimpleEnumerator** aResult) {
563 nsresult rv = NS_ERROR_FAILURE;
564 *aResult = nullptr;
565
566 if (!strcmp(aProperty, NS_APP_PREFS_DEFAULTS_DIR_LIST"PrefDL")) {
567 nsCOMArray<nsIFile> directories;
568
569 LoadDirIntoArray(mXULAppDir, kAppendPrefDir, directories);
570#ifdef MOZ_BACKGROUNDTASKS1
571 if (mozilla::BackgroundTasks::IsBackgroundTaskMode()) {
572 LoadDirIntoArray(mGREDir, kAppendBackgroundTasksPrefDir, directories);
573 LoadDirIntoArray(mXULAppDir, kAppendBackgroundTasksPrefDir, directories);
574 }
575#endif
576
577 rv = NS_NewArrayEnumerator(aResult, directories, NS_GET_IID(nsIFile)(nsIFile::kIID));
578 } else if (!strcmp(aProperty, NS_APP_CHROME_DIR_LIST"AChromDL")) {
579 // NS_APP_CHROME_DIR_LIST is only used to get default (native) icons
580 // for OS window decoration.
581
582 static const char* const kAppendChromeDir[] = {"chrome", nullptr};
583 nsCOMArray<nsIFile> directories;
584 LoadDirIntoArray(mXULAppDir, kAppendChromeDir, directories);
585
586 rv = NS_NewArrayEnumerator(aResult, directories, NS_GET_IID(nsIFile)(nsIFile::kIID));
587 }
588 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 588); return rv; } } while (false)
;
589
590 return NS_SUCCESS_AGGREGATE_RESULT;
591}
592
593NS_IMETHODIMPnsresult
594nsXREDirProvider::GetDirectory(nsIFile** aResult) {
595 NS_ENSURE_TRUE(mProfileDir, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mProfileDir)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mProfileDir" ") failed"
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 595
); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
596 return mProfileDir->Clone(aResult);
597}
598
599void nsXREDirProvider::InitializeUserPrefs() {
600 if (!mPrefsInitialized) {
601 mozilla::Preferences::InitializeUserPrefs();
602 }
603}
604
605void nsXREDirProvider::FinishInitializingUserPrefs() {
606 if (!mPrefsInitialized) {
607 mozilla::Preferences::FinishInitializingUserPrefs();
608 mPrefsInitialized = true;
609 }
610}
611
612NS_IMETHODIMPnsresult
613nsXREDirProvider::DoStartup() {
614 nsresult rv;
615
616 if (!mAppStarted) {
617 nsCOMPtr<nsIObserverService> obsSvc =
618 mozilla::services::GetObserverService();
619 if (!obsSvc) return NS_ERROR_FAILURE;
620
621 mAppStarted = true;
622
623 /*
624 Make sure we've setup prefs before profile-do-change to be able to use
625 them to track crashes and because we want to begin crash tracking before
626 other code run from this notification since they may cause crashes.
627 */
628 MOZ_ASSERT(mPrefsInitialized)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPrefsInitialized)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPrefsInitialized))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mPrefsInitialized"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 628); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mPrefsInitialized" ")"); do { MOZ_CrashSequence
(__null, 628); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
629
630 bool safeModeNecessary = false;
631 nsCOMPtr<nsIAppStartup> appStartup(
632 mozilla::components::AppStartup::Service());
633 if (appStartup) {
634 rv = appStartup->TrackStartupCrashBegin(&safeModeNecessary);
635 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_NOT_AVAILABLE)
636 NS_WARNING("Error while beginning startup crash tracking")NS_DebugBreak(NS_DEBUG_WARNING, "Error while beginning startup crash tracking"
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 636
)
;
637
638 if (!gSafeMode && safeModeNecessary) {
639 appStartup->RestartInSafeMode(nsIAppStartup::eForceQuit);
640 return NS_OK;
641 }
642 }
643
644 static const char16_t kStartup[] = {'s', 't', 'a', 'r',
645 't', 'u', 'p', '\0'};
646 obsSvc->NotifyObservers(nullptr, "profile-do-change", kStartup);
647
648 // Initialize the Enterprise Policies service in the parent process
649 // In the content process it's loaded on demand when needed
650 if (XRE_IsParentProcess()) {
651 nsCOMPtr<nsIObserver> policies(
652 do_GetService("@mozilla.org/enterprisepolicies;1"));
653 if (policies) {
654 policies->Observe(nullptr, "policies-startup", nullptr);
655 }
656 }
657
658#ifdef MOZ_THUNDERBIRD
659 bool bgtaskMode = false;
660# ifdef MOZ_BACKGROUNDTASKS1
661 bgtaskMode = mozilla::BackgroundTasks::IsBackgroundTaskMode();
662# endif
663 if (!bgtaskMode &&
664 mozilla::Preferences::GetBool(
665 "security.prompt_for_master_password_on_startup", false)) {
666# ifdef XP_MACOSX
667 // Ensure the application is initialized before the prompt is triggered.
668 // Note: calling InitializeMacApp more than once does nothing.
669 InitializeMacApp();
670# endif
671 // Prompt for the master password prior to opening application windows,
672 // to avoid the race that triggers multiple prompts (see bug 177175).
673 // We use this code until we have a better solution, possibly as
674 // described in bug 177175 comment 384.
675 // Ensure NSS is initialized; it may not be this early in startup.
676 nsCOMPtr<nsINSSComponent> nssComponent(
677 do_GetService(NS_NSSCOMPONENT_CID));
678 mozilla::UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
679 if (slot) {
680 (void)PK11_Authenticate(slot.get(), true, nullptr);
681 }
682 }
683#endif
684
685 bool initExtensionManager =
686#ifdef MOZ_BACKGROUNDTASKS1
687 !mozilla::BackgroundTasks::IsBackgroundTaskMode();
688#else
689 true;
690#endif
691 if (initExtensionManager) {
692 // Init the Extension Manager
693 nsCOMPtr<nsIObserver> em =
694 do_GetService("@mozilla.org/addons/integration;1");
695 if (em) {
696 em->Observe(nullptr, "addons-startup", nullptr);
697 } else {
698 NS_WARNING("Failed to create Addons Manager.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to create Addons Manager."
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 698
)
;
699 }
700 }
701
702 obsSvc->NotifyObservers(nullptr, "profile-after-change", kStartup);
703
704 // Any component that has registered for the profile-after-change category
705 // should also be created at this time.
706 (void)NS_CreateServicesFromCategory("profile-after-change", nullptr,
707 "profile-after-change");
708
709 if (gSafeMode && safeModeNecessary) {
710 static const char16_t kCrashed[] = {'c', 'r', 'a', 's',
711 'h', 'e', 'd', '\0'};
712 obsSvc->NotifyObservers(nullptr, "safemode-forced", kCrashed);
713 }
714
715 // 1 = Regular mode, 2 = Safe mode, 3 = Safe mode forced
716 int mode = 1;
717 if (gSafeMode) {
718 if (safeModeNecessary)
719 mode = 3;
720 else
721 mode = 2;
722 }
723 mozilla::glean::gecko::safe_mode_usage.AccumulateSingleSample(mode);
724
725 obsSvc->NotifyObservers(nullptr, "profile-initial-state", nullptr);
726 }
727 return NS_OK;
728}
729
730void nsXREDirProvider::DoShutdown() {
731 AUTO_PROFILER_LABEL("nsXREDirProvider::DoShutdown", OTHER)mozilla::AutoProfilerLabel raiiObject731( "nsXREDirProvider::DoShutdown"
, nullptr, JS::ProfilingCategoryPair::OTHER)
;
732
733 if (mAppStarted) {
734 mozilla::AppShutdown::AdvanceShutdownPhase(
735 mozilla::ShutdownPhase::AppShutdownNetTeardown, nullptr);
736 mozilla::AppShutdown::AdvanceShutdownPhase(
737 mozilla::ShutdownPhase::AppShutdownTeardown, nullptr);
738
739#ifdef DEBUG1
740 // Not having this causes large intermittent leaks. See bug 1340425.
741 if (JSContext* cx = mozilla::dom::danger::GetJSContext()) {
742 JS_GC(cx);
743 }
744#endif
745
746 mozilla::AppShutdown::AdvanceShutdownPhase(
747 mozilla::ShutdownPhase::AppShutdown, nullptr);
748 mozilla::AppShutdown::AdvanceShutdownPhase(
749 mozilla::ShutdownPhase::AppShutdownQM, nullptr);
750 mozilla::AppShutdown::AdvanceShutdownPhase(
751 mozilla::ShutdownPhase::AppShutdownTelemetry, nullptr);
752 mAppStarted = false;
753 }
754
755 gDataDirProfileLocal = nullptr;
756 gDataDirProfile = nullptr;
757}
758
759#ifdef XP_WIN
760static nsresult GetShellFolderPath(KNOWNFOLDERID folder, nsAString& _retval) {
761 DWORD flags = KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_VERIFY | KF_FLAG_NO_ALIAS;
762 PWSTR path = nullptr;
763
764 if (!SUCCEEDED(SHGetKnownFolderPath(folder, flags, NULL__null, &path))) {
765 return NS_ERROR_NOT_AVAILABLE;
766 }
767
768 _retval = nsDependentString(path);
769 CoTaskMemFree(path);
770 return NS_OK;
771}
772
773/**
774 * Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by
775 * querying the registry when the call to SHGetSpecialFolderLocation or
776 * SHGetPathFromIDListW is unable to provide these paths (Bug 513958).
777 */
778static nsresult GetRegWindowsAppDataFolder(bool aLocal, nsAString& _retval) {
779 HKEY key;
780 LPCWSTR keyName =
781 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
782 DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName, 0, KEY_READ, &key);
783 if (res != ERROR_SUCCESS) {
784 _retval.SetLength(0);
785 return NS_ERROR_NOT_AVAILABLE;
786 }
787
788 DWORD type, size;
789 res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"), nullptr,
790 &type, nullptr, &size);
791 // The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
792 // buffer size must not equal 0, and the buffer size be a multiple of 2.
793 if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0) {
794 ::RegCloseKey(key);
795 _retval.SetLength(0);
796 return NS_ERROR_NOT_AVAILABLE;
797 }
798
799 // |size| may or may not include room for the terminating null character
800 DWORD resultLen = size / 2;
801
802 if (!_retval.SetLength(resultLen, mozilla::fallible)) {
803 ::RegCloseKey(key);
804 _retval.SetLength(0);
805 return NS_ERROR_NOT_AVAILABLE;
806 }
807
808 auto begin = _retval.BeginWriting();
809
810 res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"), nullptr,
811 nullptr, (LPBYTE)begin, &size);
812 ::RegCloseKey(key);
813 if (res != ERROR_SUCCESS) {
814 _retval.SetLength(0);
815 return NS_ERROR_NOT_AVAILABLE;
816 }
817
818 if (!_retval.CharAt(resultLen - 1)) {
819 // It was already null terminated.
820 _retval.Truncate(resultLen - 1);
821 }
822
823 return NS_OK;
824}
825#endif
826
827static nsresult HashInstallPath(nsAString& aInstallPath, nsAString& aPathHash) {
828 mozilla::UniquePtr<NS_tchar[]> hash;
829 bool success = ::GetInstallHash(PromiseFlatStringTPromiseFlatString<char16_t>(aInstallPath).get(), hash);
830 if (!success) {
831 return NS_ERROR_FAILURE;
832 }
833
834 // The hash string is a NS_tchar*, which is wchar* in Windows and char*
835 // elsewhere.
836#ifdef XP_WIN
837 aPathHash.Assign(hash.get());
838#else
839 aPathHash.AssignASCII(hash.get());
840#endif
841 return NS_OK;
842}
843
844/**
845 * Gets a hash of the installation directory.
846 */
847nsresult nsXREDirProvider::GetInstallHash(nsAString& aPathHash) {
848 nsAutoString stringToHash;
849
850#ifdef XP_WIN
851 if (mozilla::widget::WinUtils::HasPackageIdentity()) {
852 // For packages, the install path includes the version number, so it isn't
853 // a stable or consistent identifier for the installation. The package
854 // family name is though, so use that instead of the path.
855 stringToHash = mozilla::widget::WinUtils::GetPackageFamilyName();
856 } else
857#endif
858 {
859 nsCOMPtr<nsIFile> installDir;
860 nsCOMPtr<nsIFile> appFile;
861 bool per = false;
862 nsresult rv = GetFile(XRE_EXECUTABLE_FILE"XREExeF", &per, getter_AddRefs(appFile));
863 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 863); return rv; } } while (false)
;
864 rv = appFile->GetParent(getter_AddRefs(installDir));
865 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 865); return rv; } } while (false)
;
866
867 // It is possible that the path we have is on a case insensitive
868 // filesystem in which case the path may vary depending on how the
869 // application is called. We want to normalize the case somehow.
870#ifdef XP_WIN
871 // Windows provides a way to get the correct case.
872 if (!mozilla::widget::WinUtils::ResolveJunctionPointsAndSymLinks(
873 installDir)) {
874 NS_WARNING("Failed to resolve install directory.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to resolve install directory."
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 874
)
;
875 }
876#elif defined(MOZ_WIDGET_COCOA)
877 // On OSX roundtripping through an FSRef fixes the case.
878 FSRef ref;
879 nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(installDir);
880 rv = macFile->GetFSRef(&ref);
881 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 881); return rv; } } while (false)
;
882 rv = NS_NewLocalFileWithFSRef(&ref, getter_AddRefs(macFile));
883 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 883); return rv; } } while (false)
;
884 installDir = static_cast<nsIFile*>(macFile);
885#endif
886 // On linux XRE_EXECUTABLE_FILE already seems to be set to the correct path.
887
888 rv = installDir->GetPath(stringToHash);
889 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 889); return rv; } } while (false)
;
890 }
891
892 // If we somehow failed to get an actual value, hashing an empty string could
893 // potentially cause some serious problems given all the things this hash is
894 // used for. So we don't allow that.
895 if (stringToHash.IsEmpty()) {
896 return NS_ERROR_FAILURE;
897 }
898
899 return HashInstallPath(stringToHash, aPathHash);
900}
901
902/**
903 * Before bug 1555319 the directory hashed can have had an incorrect case.
904 * Access to that hash is still available through this function. It is needed so
905 * we can migrate users who may have an incorrect hash in profiles.ini. This
906 * support can probably be removed in a few releases time.
907 */
908nsresult nsXREDirProvider::GetLegacyInstallHash(nsAString& aPathHash) {
909 nsCOMPtr<nsIFile> installDir;
910 nsCOMPtr<nsIFile> appFile;
911 bool per = false;
912 nsresult rv = GetFile(XRE_EXECUTABLE_FILE"XREExeF", &per, getter_AddRefs(appFile));
913 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 913); return rv; } } while (false)
;
914 rv = appFile->GetParent(getter_AddRefs(installDir));
915 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 915); return rv; } } while (false)
;
916
917 nsAutoString installPath;
918 rv = installDir->GetPath(installPath);
919 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 919); return rv; } } while (false)
;
920
921#ifdef XP_WIN
922# if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
923 // Convert a 64-bit install path to what would have been the 32-bit install
924 // path to allow users to migrate their profiles from one to the other.
925 PWSTR pathX86 = nullptr;
926 HRESULT hres =
927 SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, nullptr, &pathX86);
928 if (SUCCEEDED(hres)) {
929 nsDependentString strPathX86(pathX86);
930 if (!StringBeginsWith(installPath, strPathX86,
931 nsCaseInsensitiveStringComparator)) {
932 PWSTR path = nullptr;
933 hres = SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, nullptr, &path);
934 if (SUCCEEDED(hres)) {
935 if (StringBeginsWith(installPath, nsDependentString(path),
936 nsCaseInsensitiveStringComparator)) {
937 installPath.Replace(0, wcslen(path), strPathX86);
938 }
939 }
940 CoTaskMemFree(path);
941 }
942 }
943 CoTaskMemFree(pathX86);
944# endif
945#endif
946 return HashInstallPath(installPath, aPathHash);
947}
948
949nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
950 bool aGetOldLocation) {
951#ifndef XP_WIN
952 // There is no old update location on platforms other than Windows. Windows is
953 // the only platform for which we migrated the update directory.
954 if (aGetOldLocation) {
955 return NS_ERROR_NOT_IMPLEMENTED;
956 }
957#endif
958 nsCOMPtr<nsIFile> updRoot;
959 nsCOMPtr<nsIFile> appFile;
960 bool per = false;
961 nsresult rv = GetFile(XRE_EXECUTABLE_FILE"XREExeF", &per, getter_AddRefs(appFile));
962 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 962); return rv; } } while (false)
;
963 rv = appFile->GetParent(getter_AddRefs(updRoot));
964 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 964); return rv; } } while (false)
;
965
966#ifdef XP_MACOSX
967 nsCOMPtr<nsIFile> appRootDirFile;
968 nsCOMPtr<nsIFile> localDir;
969 nsAutoString appDirPath;
970 if (NS_FAILED(appFile->GetParent(getter_AddRefs(appRootDirFile)))((bool)(__builtin_expect(!!(NS_FAILED_impl(appFile->GetParent
(getter_AddRefs(appRootDirFile)))), 0)))
||
971 NS_FAILED(appRootDirFile->GetPath(appDirPath))((bool)(__builtin_expect(!!(NS_FAILED_impl(appRootDirFile->
GetPath(appDirPath))), 0)))
||
972 NS_FAILED(GetUserDataDirectoryHome(getter_AddRefs(localDir),((bool)(__builtin_expect(!!(NS_FAILED_impl(GetUserDataDirectoryHome
(getter_AddRefs(localDir), true))), 0)))
973 /* aLocal */ true))((bool)(__builtin_expect(!!(NS_FAILED_impl(GetUserDataDirectoryHome
(getter_AddRefs(localDir), true))), 0)))
) {
974 return NS_ERROR_FAILURE;
975 }
976
977 int32_t dotIndex = appDirPath.RFind(u".app");
978 if (dotIndex == kNotFound) {
979 dotIndex = appDirPath.Length();
980 }
981 appDirPath = Substring(appDirPath, 1, dotIndex - 1);
982
983 bool hasVendor = GetAppVendor() && strlen(GetAppVendor()) != 0;
984 if (hasVendor || GetAppName()) {
985 if (NS_FAILED(localDir->AppendNative(((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendNative
( nsDependentCString(hasVendor ? GetAppVendor() : GetAppName(
))))), 0)))
986 nsDependentCString(hasVendor ? GetAppVendor() : GetAppName())))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendNative
( nsDependentCString(hasVendor ? GetAppVendor() : GetAppName(
))))), 0)))
) {
987 return NS_ERROR_FAILURE;
988 }
989 } else if (NS_FAILED(localDir->AppendNative("Mozilla"_ns))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendNative
("Mozilla"_ns))), 0)))
) {
990 return NS_ERROR_FAILURE;
991 }
992
993 if (NS_FAILED(localDir->Append(u"updates"_ns))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->Append
(u"updates"_ns))), 0)))
||
994 NS_FAILED(localDir->AppendRelativePath(appDirPath))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendRelativePath
(appDirPath))), 0)))
) {
995 return NS_ERROR_FAILURE;
996 }
997
998 localDir.forget(aResult);
999 return NS_OK;
1000
1001#elif XP_WIN
1002 nsAutoString installPath;
1003 rv = updRoot->GetPath(installPath);
1004 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1004); return rv; } } while (false)
;
1005
1006 mozilla::UniquePtr<wchar_t[]> updatePath;
1007 HRESULT hrv;
1008 if (aGetOldLocation) {
1009 hrv =
1010 GetOldUpdateDirectory(PromiseFlatStringTPromiseFlatString<char16_t>(installPath).get(), updatePath);
1011 } else {
1012 hrv = GetCommonUpdateDirectory(PromiseFlatStringTPromiseFlatString<char16_t>(installPath).get(),
1013 updatePath);
1014 }
1015 if (FAILED(hrv)) {
1016 return NS_ERROR_FAILURE;
1017 }
1018 nsAutoString updatePathStr;
1019 updatePathStr.Assign(updatePath.get());
1020 MOZ_TRY(updRoot->InitWithPath(updatePathStr))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(updRoot->InitWithPath(updatePathStr)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1021 updRoot.forget(aResult);
1022 return NS_OK;
1023#else
1024 updRoot.forget(aResult);
1025 return NS_OK;
1026#endif // XP_WIN
1027}
1028
1029nsresult nsXREDirProvider::GetProfileStartupDir(nsIFile** aResult) {
1030 if (mProfileDir) {
1031 return mProfileDir->Clone(aResult);
1032 }
1033
1034 // Profile directories are only set up in the parent process.
1035 // We don't expect every caller to check if they are in the right process,
1036 // so fail immediately to avoid warning spam.
1037 NS_WARNING_ASSERTION(!XRE_IsParentProcess(),do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 1038); } } while
(false)
1038 "tried to get profile in parent too early")do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 1038); } } while
(false)
;
1039 return NS_ERROR_FAILURE;
1040}
1041
1042nsresult nsXREDirProvider::GetProfileDir(nsIFile** aResult) {
1043 if (!mProfileDir) {
1044 nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR"ProfD",
1045 getter_AddRefs(mProfileDir));
1046 // Guard against potential buggy directory providers that fail while also
1047 // returning something.
1048 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1049 MOZ_ASSERT(!mProfileDir,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mProfileDir))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mProfileDir" " ("
"Directory provider failed but returned a value" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1050); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir"
") (" "Directory provider failed but returned a value" ")");
do { MOZ_CrashSequence(__null, 1050); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1050 "Directory provider failed but returned a value")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mProfileDir))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mProfileDir" " ("
"Directory provider failed but returned a value" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1050); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir"
") (" "Directory provider failed but returned a value" ")");
do { MOZ_CrashSequence(__null, 1050); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1051 mProfileDir = nullptr;
1052 }
1053 }
1054 // If we failed to get mProfileDir, this will warn for us if appropriate.
1055 return GetProfileStartupDir(aResult);
1056}
1057
1058NS_IMETHODIMPnsresult
1059nsXREDirProvider::SetUserDataDirectory(nsIFile* aFile, bool aLocal) {
1060 if (aLocal) {
1061 NS_IF_RELEASE(gDataDirHomeLocal)do { if (gDataDirHomeLocal) { (gDataDirHomeLocal)->Release
(); (gDataDirHomeLocal) = 0; } } while (0)
;
1062 NS_IF_ADDREF(gDataDirHomeLocal = aFile)ns_if_addref(gDataDirHomeLocal = aFile);
1063 } else {
1064 NS_IF_RELEASE(gDataDirHome)do { if (gDataDirHome) { (gDataDirHome)->Release(); (gDataDirHome
) = 0; } } while (0)
;
1065 NS_IF_ADDREF(gDataDirHome = aFile)ns_if_addref(gDataDirHome = aFile);
1066 }
1067
1068 return NS_OK;
1069}
1070
1071/* static */
1072nsresult nsXREDirProvider::SetUserDataProfileDirectory(nsCOMPtr<nsIFile>& aFile,
1073 bool aLocal) {
1074 if (aLocal) {
1075 gDataDirProfileLocal = aFile;
1076 } else {
1077 gDataDirProfile = aFile;
1078 }
1079
1080 return NS_OK;
1081}
1082
1083/* static */
1084nsresult nsXREDirProvider::ClearUserDataProfileDirectoryFromGTest(
1085 nsIFile** aLocal, nsIFile** aGlobal) {
1086 if (gDataDirProfileLocal) {
1087 gDataDirProfileLocal->Clone(aLocal);
1088 gDataDirProfileLocal = nullptr;
1089 }
1090
1091 if (gDataDirProfile) {
1092 gDataDirProfile->Clone(aGlobal);
1093 gDataDirProfile = nullptr;
1094 }
1095
1096 return NS_OK;
1097}
1098
1099/* static */
1100nsresult nsXREDirProvider::RestoreUserDataProfileDirectoryFromGTest(
1101 nsCOMPtr<nsIFile>& aLocal, nsCOMPtr<nsIFile>& aGlobal) {
1102 gDataDirProfileLocal = aLocal;
1103 gDataDirProfile = aGlobal;
1104
1105 return NS_OK;
1106}
1107
1108// Return the home directory that will contain user data
1109nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
1110 bool aLocal,
1111 bool aForceLegacy) {
1112 // Copied from nsAppFileLocationProvider (more or less)
1113 nsCOMPtr<nsIFile> localDir;
1114
1115 if (aLocal && gDataDirHomeLocal) {
1116 return gDataDirHomeLocal->Clone(aFile);
1117 }
1118 if (!aLocal && gDataDirHome) {
1119 return gDataDirHome->Clone(aFile);
1120 }
1121
1122#if defined(XP_MACOSX)
1123 FSRef fsRef;
1124 OSType folderType;
1125 if (aLocal) {
1126 folderType = kCachedDataFolderType;
1127 } else {
1128# ifdef MOZ_THUNDERBIRD
1129 folderType = kDomainLibraryFolderType;
1130# else
1131 folderType = kApplicationSupportFolderType;
1132# endif
1133 }
1134 OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
1135 NS_ENSURE_FALSE(err, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(!(err))), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!(err)" ") failed", nullptr
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 1135); return
NS_ERROR_FAILURE; } } while (false)
;
1136
1137 nsCOMPtr<nsILocalFileMac> dirFileMac;
1138 MOZ_TRY(NS_NewLocalFileWithFSRef(&fsRef, getter_AddRefs(dirFileMac)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewLocalFileWithFSRef(&fsRef, getter_AddRefs(dirFileMac
))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0
))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1139 localDir = dirFileMac.forget();
1140#elif defined(XP_IOS)
1141 nsAutoCString userDir;
1142 nsresult rv;
1143 if (GetUIKitDirectory(aLocal, userDir)) {
1144 rv = NS_NewNativeLocalFile(userDir, getter_AddRefs(localDir));
1145 } else {
1146 rv = NS_ERROR_FAILURE;
1147 }
1148 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1148); return rv; } } while (false)
;
1149#elif defined(XP_WIN)
1150 nsresult rv;
1151 nsString path;
1152 if (aLocal) {
1153 rv = GetShellFolderPath(FOLDERID_LocalAppData, path);
1154 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) rv = GetRegWindowsAppDataFolder(aLocal, path);
1155 }
1156 if (!aLocal || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1157 rv = GetShellFolderPath(FOLDERID_RoamingAppData, path);
1158 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1159 if (!aLocal) rv = GetRegWindowsAppDataFolder(aLocal, path);
1160 }
1161 }
1162 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1162); return rv; } } while (false)
;
1163
1164 MOZ_TRY(NS_NewLocalFile(path, getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewLocalFile(path, getter_AddRefs(localDir))); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1165#elif defined(XP_UNIX1)
1166 const char* homeDir = PR_GetEnv("HOME");
1167 if (!homeDir || !*homeDir) return NS_ERROR_FAILURE;
1168
1169# ifdef ANDROID /* We want (ProfD == ProfLD) on Android. */
1170 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(homeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(homeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1171 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(homeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1172# else
1173 if (aLocal) {
1174 // Not forcing legacy because cache can be lost without consequences, so
1175 // there is no real requirement to keep compatibility here
1176 MOZ_TRY(nsXREDirProvider::GetLegacyOrXDGCachePath(__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGCachePath( homeDir, getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1177 homeDir, getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGCachePath( homeDir, getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1178 } else {
1179 MOZ_TRY(nsXREDirProvider::GetLegacyOrXDGHomePath(__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGHomePath( homeDir, getter_AddRefs
(localDir), aForceLegacy)); if ((__builtin_expect(!!(mozTryVarTempResult
.isErr()), 0))) { return mozTryVarTempResult.propagateErr(); }
mozTryVarTempResult.unwrap(); })
1180 homeDir, getter_AddRefs(localDir), aForceLegacy))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGHomePath( homeDir, getter_AddRefs
(localDir), aForceLegacy)); if ((__builtin_expect(!!(mozTryVarTempResult
.isErr()), 0))) { return mozTryVarTempResult.propagateErr(); }
mozTryVarTempResult.unwrap(); })
;
1181 }
1182# endif // ANDROID
1183#else
1184# error "Don't know how to get product dir on your platform"
1185#endif
1186
1187 localDir.forget(aFile);
1188 return NS_OK;
1189}
1190
1191nsresult nsXREDirProvider::GetSysUserExtensionsDirectory(nsIFile** aFile) {
1192 nsCOMPtr<nsIFile> localDir;
1193 nsresult rv = GetUserDataDirectoryHome(
1194 getter_AddRefs(localDir), /* aLocal */ false, /* aForceLegacy */ true);
1195 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1195); return rv; } } while (false)
;
1196
1197 rv = AppendSysUserExtensionPath(localDir);
1198 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1198); return rv; } } while (false)
;
1199
1200 // We used to unconditionally create the directory here, but that results in
1201 // an unwanted ~/.mozilla/extensions/ in violation of the XDG basedir spec,
1202 // which expresses a preference for ~/.config/mozilla/.
1203 //
1204 // Since we no longer support sideloading from this directory, unless
1205 // MOZ_ALLOW_ADDON_SIDELOAD is set, the creation of the directory is almost
1206 // always redundant, so skip the creation of the directory.
1207
1208 localDir.forget(aFile);
1209 return NS_OK;
1210}
1211
1212#if defined(XP_UNIX1) || defined(XP_MACOSX)
1213nsresult nsXREDirProvider::GetSystemExtensionsDirectory(nsIFile** aFile) {
1214 nsresult rv;
1215 nsCOMPtr<nsIFile> localDir;
1216
1217 rv = GetSystemParentDirectory(getter_AddRefs(localDir));
1218 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1219 constexpr auto sExtensions =
1220# if defined(XP_MACOSX)
1221 "Extensions"_ns
1222# else
1223 "extensions"_ns
1224# endif
1225 ;
1226
1227 rv = localDir->AppendNative(sExtensions);
1228 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1229 localDir.forget(aFile);
1230 }
1231 }
1232 return rv;
1233}
1234#endif
1235
1236nsresult nsXREDirProvider::GetUserDataDirectory(nsIFile** aFile, bool aLocal) {
1237 nsCOMPtr<nsIFile> localDir;
1238 nsCOMPtr<nsIFile> customDir = mozilla::GetFileFromEnv("MOZ_APP_DATA");
1239 nsCOMPtr<nsIFile> customLocalDir =
1240 mozilla::GetFileFromEnv("MOZ_LOCAL_APP_DATA");
1241
1242 if (aLocal && gDataDirProfileLocal) {
1243 return gDataDirProfileLocal->Clone(aFile);
1244 }
1245 if (!aLocal && gDataDirProfile) {
1246 return gDataDirProfile->Clone(aFile);
1247 }
1248
1249 nsresult rv;
1250 if (aLocal && customLocalDir) {
1251 localDir = customLocalDir;
1252 } else if (!aLocal && customDir) {
1253 localDir = customDir;
1254 } else {
1255 rv = GetUserDataDirectoryHome(getter_AddRefs(localDir), aLocal);
1256 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1256); return rv; } } while (false)
;
1257
1258 rv = AppendProfilePath(localDir, aLocal);
1259 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1259); return rv; } } while (false)
;
1260 }
1261
1262 rv = EnsureDirectoryExists(localDir);
1263 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1263); return rv; } } while (false)
;
1264
1265 nsXREDirProvider::SetUserDataProfileDirectory(localDir, aLocal);
1266
1267 localDir.forget(aFile);
1268 return NS_OK;
1269}
1270
1271nsresult nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory) {
1272 nsresult rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0700);
1273
1274 if (rv == NS_ERROR_FILE_ALREADY_EXISTS) {
1275 rv = NS_OK;
1276 }
1277 return rv;
1278}
1279
1280nsresult nsXREDirProvider::AppendSysUserExtensionPath(nsIFile* aFile) {
1281 NS_ASSERTION(aFile, "Null pointer!")do { if (!(aFile)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null pointer!"
, "aFile", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1281
); MOZ_PretendNoReturn(); } } while (0)
;
1282
1283 nsresult rv;
1284
1285#if defined(XP_MACOSX) || defined(XP_WIN)
1286
1287 static const char* const sXR = "Mozilla";
1288 rv = aFile->AppendNative(nsDependentCString(sXR));
1289 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1289); return rv; } } while (false)
;
1290
1291 static const char* const sExtensions = "Extensions";
1292 rv = aFile->AppendNative(nsDependentCString(sExtensions));
1293 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1293); return rv; } } while (false)
;
1294
1295#elif defined(XP_UNIX1)
1296
1297 static const char* const sXR = ".mozilla";
1298 rv = aFile->AppendNative(nsDependentCString(sXR));
1299 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1299); return rv; } } while (false)
;
1300
1301 static const char* const sExtensions = "extensions";
1302 rv = aFile->AppendNative(nsDependentCString(sExtensions));
1303 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1303); return rv; } } while (false)
;
1304
1305#else
1306# error "Don't know how to get XRE user extension path on your platform"
1307#endif
1308 return NS_OK;
1309}
1310
1311#if defined(MOZ_WIDGET_GTK1)
1312/*
1313 * Return whether MOZ_LEGACY_HOME == 1, via environment or at build time
1314 */
1315bool nsXREDirProvider::IsForceLegacyHome() {
1316# if !defined(MOZ_LEGACY_HOME)
1317 const char* legacyhomedir = PR_GetEnv("MOZ_LEGACY_HOME");
1318 return legacyhomedir && legacyhomedir[0] == '1';
1319# else
1320 return true;
1321# endif
1322}
1323
1324/* static */
1325nsresult nsXREDirProvider::AppendFromAppData(nsIFile* aFile, bool aIsDotted) {
1326 // This might happen in xpcshell so assert that it is indeed in a xpcshell
1327 // test. This assumes the xpcshell are ran through test harness.
1328 if (!gAppData) {
1329 mozilla::DebugOnly<const char*> xpcshell =
1330 PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
1331 MOZ_ASSERT(xpcshell, "gAppData can only be nullptr in xpcshell tests")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(xpcshell)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(xpcshell))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("xpcshell" " (" "gAppData can only be nullptr in xpcshell tests"
")", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1331); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "xpcshell" ") (" "gAppData can only be nullptr in xpcshell tests"
")"); do { MOZ_CrashSequence(__null, 1331); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1332 return NS_OK;
1333 }
1334
1335 // Similar to nsXREDirProvider::AppendProfilePath.
1336 // TODO: Bug 1990407 - Evaluate if refactoring might be required there in the
1337 // future?
1338 if (gAppData->profile) {
1339 nsAutoCString profile;
1340# if defined(MOZ_THUNDERBIRD)
1341 if (gAppData->profile[0] != '.') {
1342 profile.Assign('.');
1343 }
1344# endif
1345 profile.Append(gAppData->profile);
1346 MOZ_TRY(aFile->AppendRelativeNativePath(profile))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(profile)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1347 } else {
1348 nsAutoCString vendor;
1349 nsAutoCString appName;
1350 vendor = gAppData->vendor;
1351 appName = gAppData->name;
1352 ToLowerCase(vendor);
1353 ToLowerCase(appName);
1354
1355 MOZ_TRY(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor)__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor
) : vendor)); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1356 : vendor))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor
) : vendor)); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1357 MOZ_TRY(aFile->AppendRelativeNativePath(appName))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(appName)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1358 }
1359
1360 return NS_OK;
1361}
1362
1363/*
1364 * Check if legacy directory exists, which can be:
1365 * (1) $HOME/.<gAppData->vendor>/<gAppData->appName>
1366 * (2) $HOME/<gAppData->profile> on Firefox or
1367 * $HOME/.<gAppData->profile> on Thunderbird
1368 * (3) $HOME/<MOZ_USER_DIR>
1369 *
1370 * The MOZ_USER_DIR will also be defined in case (1), so first check the deeper
1371 * directory.
1372 */
1373bool nsXREDirProvider::LegacyHomeExists(nsIFile** aFile) {
1374 bool exists;
1375 nsDependentCString homeDir(PR_GetEnv("HOME"));
1376 nsCOMPtr<nsIFile> localDir;
1377 nsCOMPtr<nsIFile> parentDir;
1378
1379 // check old config ~/.mozilla
1380 nsresult rv = NS_NewNativeLocalFile(homeDir, getter_AddRefs(localDir));
1381 NS_ENSURE_SUCCESS(rv, false)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", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1381); return false; } } while (false)
;
1382
1383 rv = localDir->Clone(getter_AddRefs(parentDir));
1384 NS_ENSURE_SUCCESS(rv, false)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", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1384); return false; } } while (false)
;
1385
1386 // Handle (1) and (2)
1387 rv = AppendFromAppData(localDir, true);
1388 NS_ENSURE_SUCCESS(rv, false)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", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1388); return false; } } while (false)
;
1389
1390 rv = localDir->Exists(&exists);
1391 NS_ENSURE_SUCCESS(rv, false)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", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1391); return false; } } while (false)
;
1392
1393 // Give a chance to (3)
1394 if (!exists) {
1395 nsCOMPtr<nsIFile> userDir;
1396 rv = parentDir->Clone(getter_AddRefs(userDir));
1397 NS_ENSURE_SUCCESS(rv, false)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", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1397); return false; } } while (false)
;
1398
1399 nsAutoCString mozUserDir;
1400 mozUserDir = nsLiteralCString(MOZ_USER_DIR"mozilla");
1401
1402 rv = userDir->AppendRelativeNativePath(mozUserDir);
1403 NS_ENSURE_SUCCESS(rv, false)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", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1403); return false; } } while (false)
;
1404
1405 rv = userDir->Exists(&exists);
1406 NS_ENSURE_SUCCESS(rv, false)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", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1406); return false; } } while (false)
;
1407 }
1408
1409 // If required, return the parent dir that may exist.
1410 if (aFile) {
1411 parentDir.forget(aFile);
1412 }
1413
1414 return exists;
1415}
1416
1417void MaybeRecordXdgTelemetry(
1418 nsXREDirProvider::legacyOrXDGHomeTelemetry aValue) {
1419 if (gXdgTelemetry == nsXREDirProvider::legacyOrXDGHomeTelemetry::empty) {
1420 gXdgTelemetry = aValue;
1421 }
1422}
1423
1424/* static */
1425nsresult nsXREDirProvider::GetLegacyOrXDGEnvValue(const char* aHomeDir,
1426 const char* aEnvName,
1427 nsCString aSubdir,
1428 nsIFile** aFile,
1429 bool* aWasFromEnv) {
1430 nsCOMPtr<nsIFile> localDir;
1431 nsresult rv = NS_OK;
1432
1433 const char* envValue = PR_GetEnv(aEnvName);
1434 if (envValue && *envValue) {
1435 rv = NS_NewNativeLocalFile(nsDependentCString(envValue),
1436 getter_AddRefs(localDir));
1437 if (aWasFromEnv) {
1438 *aWasFromEnv = true;
1439 }
1440 }
1441
1442 // Explicitly check for rv failure because in case we get passed an env
1443 // value that is an invalid dir by the XDG specification level, it should
1444 // be ignored. Per
1445 // https://specifications.freedesktop.org/basedir-spec/0.8/:
1446 // "If an implementation encounters a relative path in any of
1447 // these variables it should consider the path invalid and ignore it."
1448 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !envValue || !*envValue) {
1449 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1450 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1451 MOZ_TRY(localDir->AppendNative(aSubdir))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(localDir->AppendNative(aSubdir)); if ((__builtin_expect(!
!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1452 if (aWasFromEnv) {
1453 *aWasFromEnv = false;
1454 }
1455 }
1456
1457 localDir.forget(aFile);
1458 return NS_OK;
1459}
1460
1461/* static */
1462nsresult nsXREDirProvider::GetLegacyOrXDGCachePath(const char* aHomeDir,
1463 nsIFile** aFile) {
1464 return GetLegacyOrXDGEnvValue(aHomeDir, "XDG_CACHE_HOME", ".cache"_ns, aFile,
1465 nullptr);
1466}
1467
1468/*
1469 * Check if XDG_CONFIG_HOME is here and use it or default to ${aHomeDir}/.config
1470 */
1471/* static */
1472nsresult nsXREDirProvider::GetLegacyOrXDGConfigHome(const char* aHomeDir,
1473 nsIFile** aFile) {
1474 bool wasFromEnv = false;
1475 nsresult rv = GetLegacyOrXDGEnvValue(aHomeDir, "XDG_CONFIG_HOME",
1476 ".config"_ns, aFile, &wasFromEnv);
1477 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && wasFromEnv) {
1478 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::xdgConfigHome);
1479 } else {
1480 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::xdgDefault);
1481 }
1482 return rv;
1483}
1484
1485// Attempt to construct the HOME path depending on XDG or legacy status.
1486nsresult nsXREDirProvider::GetLegacyOrXDGHomePath(const char* aHomeDir,
1487 nsIFile** aFile,
1488 bool aForceLegacy) {
1489 nsCOMPtr<nsIFile> parentDir;
1490 nsDependentCString homeDir(aHomeDir);
1491
1492 bool exists = LegacyHomeExists(getter_AddRefs(parentDir));
1493 if (exists || IsForceLegacyHome() || aForceLegacy) {
1494 if (exists) {
1495 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::legacyExists);
1496 } else {
1497 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::legacyForced);
1498 }
1499 parentDir.forget(aFile);
1500 return NS_OK;
1501 }
1502
1503 nsCOMPtr<nsIFile> localDir;
1504
1505 // If the build was made with --with-user-appdir=.fooProfile it needs to be
1506 // applied and considered as a legacy path.
1507 nsAutoCString mozUserDir;
1508 mozUserDir = nsLiteralCString(MOZ_USER_DIR"mozilla");
1509 if (mozUserDir.get()[0] == '.') {
1510 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1511 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1512 MOZ_TRY(localDir->AppendRelativeNativePath(mozUserDir))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(localDir->AppendRelativeNativePath(mozUserDir)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1513 } else {
1514 // This might happen in xpcshell so assert that it is indeed in a xpcshell
1515 // test
1516 if (!gAppData) {
1517 mozilla::DebugOnly<const char*> xpcshell =
1518 PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
1519 MOZ_ASSERT(xpcshell, "gAppData can only be nullptr in xpcshell tests")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(xpcshell)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(xpcshell))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("xpcshell" " (" "gAppData can only be nullptr in xpcshell tests"
")", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1519); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "xpcshell" ") (" "gAppData can only be nullptr in xpcshell tests"
")"); do { MOZ_CrashSequence(__null, 1519); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1520 return NS_OK;
1521 }
1522
1523 // If the build was made against a specific profile name, MOZ_APP_PROFILE=
1524 // then make sure we respect this and dont move to XDG directory
1525 //
1526 // Only do this on Firefox.
1527 //
1528 // For Thunderbird, it always defines MOZ_APP_PROFILE=thunderbird. Hence,
1529 // check if the gAppData->profile value is set to something else, indicating
1530 // of a specific build where legacy needs to be forced, similar to the
1531 // Firefox handling. Both casing are verified to account for systems where
1532 // that matters.
1533 if (gAppData->profile
1534# if defined(MOZ_THUNDERBIRD)
1535 && strcmp(gAppData->profile, "thunderbird") != 0 &&
1536 strcmp(gAppData->profile, "Thunderbird") != 0
1537# endif
1538 ) {
1539 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1540 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1541 } else {
1542 MOZ_TRY(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir))
); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0))
) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1543 MOZ_TRY(localDir->Clone(getter_AddRefs(parentDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(localDir->Clone(getter_AddRefs(parentDir))); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1544 }
1545
1546 MOZ_TRY(AppendFromAppData(localDir, false))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(AppendFromAppData(localDir, false)); if ((__builtin_expect(!
!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1547 }
1548
1549 // If required return the parent directory that matches the profile root
1550 // directory.
1551 if (aFile) {
1552 parentDir.forget(aFile);
1553 }
1554
1555 // The profile root directory needs to exists at that point.
1556 MOZ_TRY(EnsureDirectoryExists(localDir))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(EnsureDirectoryExists(localDir)); if ((__builtin_expect(!!(mozTryVarTempResult
.isErr()), 0))) { return mozTryVarTempResult.propagateErr(); }
mozTryVarTempResult.unwrap(); })
;
1557
1558 return NS_OK;
1559}
1560#endif // defined(MOZ_WIDGET_GTK)
1561
1562nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
1563 NS_ASSERTION(aFile, "Null pointer!")do { if (!(aFile)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null pointer!"
, "aFile", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1563
); MOZ_PretendNoReturn(); } } while (0)
;
1564
1565 // If there is no XREAppData then there is no information to use to build
1566 // the profile path so just do nothing. This should only happen in xpcshell
1567 // tests.
1568 if (!gAppData) {
1569 return NS_OK;
1570 }
1571
1572 // Similar to nsXREDirProvider::AppendFromAppData.
1573 // TODO: evaluate if refactoring might be required there in the future?
1574
1575 nsAutoCString profile;
1576 nsAutoCString appName;
1577 nsAutoCString vendor;
1578 if (gAppData->profile) {
1579 profile = gAppData->profile;
1580 } else {
1581 appName = gAppData->name;
1582 vendor = gAppData->vendor;
1583 }
1584
1585 nsresult rv = NS_OK;
1586
1587#if defined(XP_MACOSX)
1588 if (!profile.IsEmpty()) {
1589 rv = AppendProfileString(aFile, profile.get());
1590 } else {
1591 // Note that MacOS ignores the vendor when creating the profile hierarchy -
1592 // all application preferences directories live alongside one another in
1593 // ~/Library/Application Support/
1594 rv = aFile->AppendNative(appName);
1595 }
1596 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1596); return rv; } } while (false)
;
1597
1598#elif defined(XP_WIN)
1599 if (!profile.IsEmpty()) {
1600 rv = AppendProfileString(aFile, profile.get());
1601 } else {
1602 if (!vendor.IsEmpty()) {
1603 rv = aFile->AppendNative(vendor);
1604 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1604); return rv; } } while (false)
;
1605 }
1606 rv = aFile->AppendNative(appName);
1607 }
1608 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1608); return rv; } } while (false)
;
1609
1610#elif defined(ANDROID)
1611 // The directory used for storing profiles
1612 // The parent of this directory is set in GetUserDataDirectoryHome
1613 // XXX: handle gAppData->profile properly
1614 // XXXsmaug ...and the rest of the profile creation!
1615 rv = aFile->AppendNative(nsDependentCString("mozilla"));
1616 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1616); return rv; } } while (false)
;
1617#elif defined(XP_UNIX1)
1618 nsAutoCString folder;
1619 // Make it hidden (by starting with "."), except when local (the
1620 // profile is already under ~/.cache or XDG_CACHE_HOME).
1621 if (!aLocal
1622# if defined(MOZ_WIDGET_GTK1)
1623 && (IsForceLegacyHome() || LegacyHomeExists(nullptr))
1624# endif
1625 ) {
1626 folder.Assign('.');
1627 }
1628
1629 if (!profile.IsEmpty()) {
1630 // Skip any leading path characters
1631 const char* profileStart = profile.get();
1632 while (*profileStart == '/' || *profileStart == '\\') profileStart++;
1633
1634 // On the off chance that someone wanted their folder to be hidden don't
1635 // let it become ".."
1636 if (*profileStart == '.' && !aLocal) profileStart++;
1637
1638 folder.Append(profileStart);
1639 ToLowerCase(folder);
1640
1641 rv = AppendProfileString(aFile, folder.get());
1642 } else {
1643 if (!vendor.IsEmpty()) {
1644 folder.Append(vendor);
1645 ToLowerCase(folder);
1646
1647 rv = aFile->AppendNative(folder);
1648 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1648); return rv; } } while (false)
;
1649
1650 folder.Truncate();
1651 }
1652
1653 // This can be the case in tests.
1654 if (!appName.IsEmpty()) {
1655 folder.Append(appName);
1656 ToLowerCase(folder);
1657
1658 rv = aFile->AppendNative(folder);
1659 }
1660 }
1661 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1661); return rv; } } while (false)
;
1662
1663#else
1664# error "Don't know how to get profile path on your platform"
1665#endif
1666 return NS_OK;
1667}
1668
1669nsresult nsXREDirProvider::AppendProfileString(nsIFile* aFile,
1670 const char* aPath) {
1671 NS_ASSERTION(aFile, "Null file!")do { if (!(aFile)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null file!"
, "aFile", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1671
); MOZ_PretendNoReturn(); } } while (0)
;
1672 NS_ASSERTION(aPath, "Null path!")do { if (!(aPath)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null path!"
, "aPath", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1672
); MOZ_PretendNoReturn(); } } while (0)
;
1673
1674 nsAutoCString pathDup(aPath);
1675
1676 char* path = pathDup.BeginWriting();
1677
1678 nsresult rv;
1679 char* subdir;
1680 while ((subdir = NS_strtok("/\\", &path))) {
1681 rv = aFile->AppendNative(nsDependentCString(subdir));
1682 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, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1682); return rv; } } while (false)
;
1683 }
1684
1685 return NS_OK;
1686}