Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/cxxalloc.h
Warning:line 60, column 10
Attempt to free released memory

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name BasePrincipal.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/caps -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/caps -resource-dir /usr/lib/llvm-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/caps -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/caps -I /var/lib/jenkins/workspace/firefox-scan-build/docshell/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/cookie -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/jsoncpp/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-16-034744-15991-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp

/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp

1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=2 sw=2 et tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "mozilla/BasePrincipal.h"
8
9#include "nsDocShell.h"
10
11#include "ExpandedPrincipal.h"
12#include "nsNetUtil.h"
13#include "nsContentUtils.h"
14#include "nsIOService.h"
15#include "nsIURIWithSpecialOrigin.h"
16#include "nsScriptSecurityManager.h"
17#include "nsServiceManagerUtils.h"
18#include "nsAboutProtocolUtils.h"
19#include "ThirdPartyUtil.h"
20#include "mozilla/ContentPrincipal.h"
21#include "mozilla/ExtensionPolicyService.h"
22#include "mozilla/NullPrincipal.h"
23#include "mozilla/dom/BlobURLProtocolHandler.h"
24#include "mozilla/dom/ChromeUtils.h"
25#include "mozilla/dom/ReferrerInfo.h"
26#include "mozilla/dom/ToJSValue.h"
27#include "mozilla/dom/nsMixedContentBlocker.h"
28#include "mozilla/Components.h"
29#include "mozilla/dom/StorageUtils.h"
30#include "mozilla/dom/StorageUtils.h"
31#include "mozilla/JSONStringWriteFuncs.h"
32#include "mozilla/JSONWriter.h"
33#include "nsIURL.h"
34#include "nsEffectiveTLDService.h"
35#include "nsIURIMutator.h"
36#include "mozilla/StaticPrefs_permissions.h"
37#include "nsIURIMutator.h"
38#include "nsMixedContentBlocker.h"
39#include "prnetdb.h"
40#include "nsIURIFixup.h"
41#include "mozilla/dom/StorageUtils.h"
42#include "mozilla/StorageAccess.h"
43#include "nsPIDOMWindow.h"
44#include "nsIURIMutator.h"
45#include "mozilla/PermissionManager.h"
46
47#include "nsSerializationHelper.h"
48
49#include "js/JSON.h"
50#include "ContentPrincipalJSONHandler.h"
51#include "ExpandedPrincipalJSONHandler.h"
52#include "NullPrincipalJSONHandler.h"
53#include "PrincipalJSONHandler.h"
54#include "SubsumedPrincipalJSONHandler.h"
55
56namespace mozilla {
57
58BasePrincipal::BasePrincipal(PrincipalKind aKind,
59 const nsACString& aOriginNoSuffix,
60 const OriginAttributes& aOriginAttributes)
61 : mOriginNoSuffix(NS_Atomize(aOriginNoSuffix)),
62 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
63 mOriginAttributes(aOriginAttributes),
64 mKind(aKind),
65 mHasExplicitDomain(false) {}
66
67BasePrincipal::BasePrincipal(BasePrincipal* aOther,
68 const OriginAttributes& aOriginAttributes)
69 : mOriginNoSuffix(aOther->mOriginNoSuffix),
70 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
71 mOriginAttributes(aOriginAttributes),
72 mKind(aOther->mKind),
73 mHasExplicitDomain(aOther->mHasExplicitDomain.load()) {}
74
75BasePrincipal::~BasePrincipal() = default;
76
77NS_IMETHODIMPnsresult
78BasePrincipal::GetOrigin(nsACString& aOrigin) {
79 nsresult rv = GetOriginNoSuffix(aOrigin);
80 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 80); return rv; } } while (false)
;
81
82 nsAutoCString suffix;
83 rv = GetOriginSuffix(suffix);
84 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 84); return rv; } } while (false)
;
85 aOrigin.Append(suffix);
86 return NS_OK;
87}
88
89NS_IMETHODIMPnsresult
90BasePrincipal::GetWebExposedOriginSerialization(nsACString& aOrigin) {
91 aOrigin.Truncate();
92 nsCOMPtr<nsIURI> prinURI;
93 nsresult rv = GetURI(getter_AddRefs(prinURI));
94 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
95 return NS_ERROR_NOT_AVAILABLE;
96 }
97 return nsContentUtils::GetWebExposedOriginSerialization(prinURI, aOrigin);
98}
99
100NS_IMETHODIMPnsresult
101BasePrincipal::GetHostPort(nsACString& aRes) {
102 aRes.Truncate();
103 nsCOMPtr<nsIURI> prinURI;
104 nsresult rv = GetURI(getter_AddRefs(prinURI));
105 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
106 return NS_OK;
107 }
108 return prinURI->GetHostPort(aRes);
109}
110
111NS_IMETHODIMPnsresult
112BasePrincipal::GetHost(nsACString& aRes) {
113 aRes.Truncate();
114 nsCOMPtr<nsIURI> prinURI;
115 nsresult rv = GetURI(getter_AddRefs(prinURI));
116 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
117 return NS_OK;
118 }
119 return prinURI->GetHost(aRes);
120}
121
122NS_IMETHODIMPnsresult
123BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) {
124 mOriginNoSuffix->ToUTF8String(aOrigin);
125 return NS_OK;
126}
127
128NS_IMETHODIMPnsresult
129BasePrincipal::GetSiteOrigin(nsACString& aSiteOrigin) {
130 nsresult rv = GetSiteOriginNoSuffix(aSiteOrigin);
131 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 131); return rv; } } while (false)
;
132
133 nsAutoCString suffix;
134 rv = GetOriginSuffix(suffix);
135 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 135); return rv; } } while (false)
;
136 aSiteOrigin.Append(suffix);
137 return NS_OK;
138}
139
140NS_IMETHODIMPnsresult
141BasePrincipal::GetSiteOriginNoSuffix(nsACString& aSiteOrigin) {
142 return GetOriginNoSuffix(aSiteOrigin);
143}
144
145template <typename HandlerTypesT>
146bool ContainerPrincipalJSONHandler<HandlerTypesT>::ProcessInnerResult(
147 bool aResult) {
148 if (!aResult) {
149 NS_WARNING("Failed to parse inner object")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to parse inner object"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 149)
;
150 mState = State::Error;
151 return false;
152 }
153 return true;
154}
155
156template <typename HandlerTypesT>
157bool ContainerPrincipalJSONHandler<HandlerTypesT>::startObject() {
158 if (mInnerHandler.isSome()) {
159 return CallOnInner([&](auto& aInner) { return aInner.startObject(); });
160 }
161
162 switch (mState) {
163 case State::Init:
164 mState = State::StartObject;
165 break;
166 case State::SystemPrincipal_Key:
167 mState = State::SystemPrincipal_StartObject;
168 break;
169 default:
170 NS_WARNING("Unexpected object value")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected object value", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 170)
;
171 mState = State::Error;
172 return false;
173 }
174
175 return true;
176}
177
178template <typename HandlerTypesT>
179bool ContainerPrincipalJSONHandler<HandlerTypesT>::propertyName(
180 const JS::Latin1Char* name, size_t length) {
181 if (mInnerHandler.isSome()) {
182 return CallOnInner(
183 [&](auto& aInner) { return aInner.propertyName(name, length); });
184 }
185
186 switch (mState) {
187 case State::StartObject: {
188 if (length != 1) {
189 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name length: %zu"
, length) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 191)
190 nsPrintfCString("Unexpected property name length: %zu", length)NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name length: %zu"
, length) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 191)
191 .get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name length: %zu"
, length) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 191)
;
192 mState = State::Error;
193 return false;
194 }
195
196 char key = char(name[0]);
197 switch (key) {
198 case BasePrincipal::NullPrincipalKey:
199 mState = State::NullPrincipal_Inner;
200 mInnerHandler.emplace(VariantType<NullPrincipalJSONHandler>());
201 break;
202 case BasePrincipal::ContentPrincipalKey:
203 mState = State::ContentPrincipal_Inner;
204 mInnerHandler.emplace(VariantType<ContentPrincipalJSONHandler>());
205 break;
206 case BasePrincipal::SystemPrincipalKey:
207 mState = State::SystemPrincipal_Key;
208 break;
209 default:
210 if constexpr (CanContainExpandedPrincipal) {
211 if (key == BasePrincipal::ExpandedPrincipalKey) {
212 mState = State::ExpandedPrincipal_Inner;
213 mInnerHandler.emplace(
214 VariantType<ExpandedPrincipalJSONHandler>());
215 break;
216 }
217 }
218 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name: '%c'"
, key).get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 219)
219 nsPrintfCString("Unexpected property name: '%c'", key).get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name: '%c'"
, key).get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 219)
;
220 mState = State::Error;
221 return false;
222 }
223 break;
224 }
225 default:
226 NS_WARNING("Unexpected property name")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected property name", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 226)
;
227 mState = State::Error;
228 return false;
229 }
230
231 return true;
232}
233
234template <typename HandlerTypesT>
235bool ContainerPrincipalJSONHandler<HandlerTypesT>::endObject() {
236 if (mInnerHandler.isSome()) {
237 return CallOnInner([&](auto& aInner) {
238 if (!aInner.endObject()) {
239 return false;
240 }
241 if (aInner.HasAccepted()) {
242 this->mPrincipal = aInner.mPrincipal.forget();
243 MOZ_ASSERT(this->mPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->mPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(this->mPrincipal))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("this->mPrincipal"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->mPrincipal"
")"); do { *((volatile int*)__null) = 243; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
244 mInnerHandler.reset();
245 }
246 return true;
247 });
248 }
249
250 switch (mState) {
251 case State::SystemPrincipal_StartObject:
252 mState = State::SystemPrincipal_EndObject;
253 break;
254 case State::SystemPrincipal_EndObject:
255 this->mPrincipal =
256 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
257 mState = State::EndObject;
258 break;
259 case State::NullPrincipal_Inner:
260 mState = State::EndObject;
261 break;
262 case State::ContentPrincipal_Inner:
263 mState = State::EndObject;
264 break;
265 default:
266 if constexpr (CanContainExpandedPrincipal) {
267 if (mState == State::ExpandedPrincipal_Inner) {
268 mState = State::EndObject;
269 break;
270 }
271 }
272 NS_WARNING("Unexpected end of object")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected end of object", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 272)
;
273 mState = State::Error;
274 return false;
275 }
276
277 return true;
278}
279
280template <typename HandlerTypesT>
281bool ContainerPrincipalJSONHandler<HandlerTypesT>::startArray() {
282 if constexpr (CanContainExpandedPrincipal) {
283 if (mInnerHandler.isSome()) {
284 return CallOnInner([&](auto& aInner) { return aInner.startArray(); });
285 }
286 }
287
288 NS_WARNING("Unexpected array value")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected array value", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 288)
;
289 mState = State::Error;
290 return false;
291}
292
293template <typename HandlerTypesT>
294bool ContainerPrincipalJSONHandler<HandlerTypesT>::endArray() {
295 if constexpr (CanContainExpandedPrincipal) {
296 if (mInnerHandler.isSome()) {
297 return CallOnInner([&](auto& aInner) { return aInner.endArray(); });
298 }
299 }
300
301 NS_WARNING("Unexpected array value")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected array value", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 301)
;
302 mState = State::Error;
303 return false;
304}
305
306template <typename HandlerTypesT>
307bool ContainerPrincipalJSONHandler<HandlerTypesT>::stringValue(
308 const JS::Latin1Char* str, size_t length) {
309 if (mInnerHandler.isSome()) {
310 return CallOnInner(
311 [&](auto& aInner) { return aInner.stringValue(str, length); });
312 }
313
314 NS_WARNING("Unexpected string value")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected string value", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 314)
;
315 mState = State::Error;
316 return false;
317}
318
319template class ContainerPrincipalJSONHandler<PrincipalJSONHandlerTypes>;
320template class ContainerPrincipalJSONHandler<SubsumedPrincipalJSONHandlerTypes>;
321
322// Takes a JSON string and parses it turning it into a principal of the
323// corresponding type
324//
325// Given a content principal:
326//
327// inner JSON object
328// |
329// ---------------------------------------------------------
330// | |
331// {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
332// | | | | |
333// | ----------------------------- |
334// | | | |
335// PrincipalKind | | |
336// | ----------------------------
337// SerializableKeys |
338// Value
339//
340already_AddRefed<BasePrincipal> BasePrincipal::FromJSON(
341 const nsACString& aJSON) {
342 PrincipalJSONHandler handler;
343
344 if (!JS::ParseJSONWithHandler(
345 reinterpret_cast<const JS::Latin1Char*>(aJSON.BeginReading()),
346 aJSON.Length(), &handler)) {
347 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unable to parse: %s"
, aJSON.BeginReading()).get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 348)
348 nsPrintfCString("Unable to parse: %s", aJSON.BeginReading()).get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unable to parse: %s"
, aJSON.BeginReading()).get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 348)
;
349 MOZ_ASSERT(false,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Unable to parse string as JSON to deserialize as a principal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Unable to parse string as JSON to deserialize as a principal"
")"); do { *((volatile int*)__null) = 350; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
350 "Unable to parse string as JSON to deserialize as a principal")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Unable to parse string as JSON to deserialize as a principal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Unable to parse string as JSON to deserialize as a principal"
")"); do { *((volatile int*)__null) = 350; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
351 return nullptr;
352 }
353
354 return handler.Get();
355}
356
357// Returns a JSON representation of the principal.
358// Calling BasePrincipal::FromJSON will deserialize the JSON into
359// the corresponding principal type.
360nsresult BasePrincipal::ToJSON(nsACString& aJSON) {
361 MOZ_ASSERT(aJSON.IsEmpty(), "ToJSON only supports an empty result input")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aJSON.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aJSON.IsEmpty()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("aJSON.IsEmpty()"
" (" "ToJSON only supports an empty result input" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aJSON.IsEmpty()"
") (" "ToJSON only supports an empty result input" ")"); do {
*((volatile int*)__null) = 361; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
362 aJSON.Truncate();
363
364 // NOTE: JSONWriter emits raw UTF-8 code units for non-ASCII range.
365 JSONStringRefWriteFunc func(aJSON);
366 JSONWriter writer(func, JSONWriter::CollectionStyle::SingleLineStyle);
367
368 nsresult rv = ToJSON(writer);
369 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 369); return rv; } } while (false)
;
370
371 return NS_OK;
372}
373
374nsresult BasePrincipal::ToJSON(JSONWriter& aWriter) {
375 static_assert(eKindMax < ArrayLength(JSONEnumKeyStrings));
376
377 aWriter.Start(JSONWriter::CollectionStyle::SingleLineStyle);
378
379 nsresult rv = WriteJSONProperties(aWriter);
380 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 380); return rv; } } while (false)
;
381
382 aWriter.End();
383
384 return NS_OK;
385}
386
387nsresult BasePrincipal::WriteJSONProperties(JSONWriter& aWriter) {
388 aWriter.StartObjectProperty(JSONEnumKeyStrings[Kind()],
389 JSONWriter::CollectionStyle::SingleLineStyle);
390
391 nsresult rv = WriteJSONInnerProperties(aWriter);
392 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 392); return rv; } } while (false)
;
393
394 aWriter.EndObject();
395
396 return NS_OK;
397}
398
399nsresult BasePrincipal::WriteJSONInnerProperties(JSONWriter& aWriter) {
400 return NS_OK;
401}
402
403bool BasePrincipal::FastSubsumesIgnoringFPD(
404 nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) {
405 MOZ_ASSERT(aOther)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aOther)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aOther))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aOther", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 405); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOther" ")")
; do { *((volatile int*)__null) = 405; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
406
407 if (Kind() == eContentPrincipal &&
408 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
409 mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
410 return false;
411 }
412
413 return SubsumesInternal(aOther, aConsideration);
414}
415
416bool BasePrincipal::Subsumes(nsIPrincipal* aOther,
417 DocumentDomainConsideration aConsideration) {
418 MOZ_ASSERT(aOther)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aOther)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aOther))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aOther", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 418); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOther" ")")
; do { *((volatile int*)__null) = 418; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
419 MOZ_ASSERT_IF(Kind() == eContentPrincipal, mOriginSuffix)do { if (Kind() == eContentPrincipal) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(mOriginSuffix)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mOriginSuffix))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mOriginSuffix", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 419); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mOriginSuffix"
")"); do { *((volatile int*)__null) = 419; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
420
421 // Expanded principals handle origin attributes for each of their
422 // sub-principals individually, null principals do only simple checks for
423 // pointer equality, and system principals are immune to origin attributes
424 // checks, so only do this check for content principals.
425 if (Kind() == eContentPrincipal &&
426 mOriginSuffix != Cast(aOther)->mOriginSuffix) {
427 return false;
428 }
429
430 return SubsumesInternal(aOther, aConsideration);
431}
432
433NS_IMETHODIMPnsresult
434BasePrincipal::Equals(nsIPrincipal* aOther, bool* aResult) {
435 NS_ENSURE_ARG_POINTER(aOther)do { if ((__builtin_expect(!!(!(aOther)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOther" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 435); return NS_ERROR_INVALID_POINTER; } } while (false)
;
436
437 *aResult = FastEquals(aOther);
438
439 return NS_OK;
440}
441
442NS_IMETHODIMPnsresult
443BasePrincipal::EqualsForPermission(nsIPrincipal* aOther, bool aExactHost,
444 bool* aResult) {
445 *aResult = false;
446 NS_ENSURE_ARG_POINTER(aOther)do { if ((__builtin_expect(!!(!(aOther)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOther" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 446); return NS_ERROR_INVALID_POINTER; } } while (false)
;
447 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 447); return NS_ERROR_INVALID_POINTER; } } while (false)
;
448
449 auto* other = Cast(aOther);
450 if (Kind() != other->Kind()) {
451 // Principals of different kinds can't be equal.
452 return NS_OK;
453 }
454
455 if (Kind() == eSystemPrincipal) {
456 *aResult = this == other;
457 return NS_OK;
458 }
459
460 if (Kind() == eNullPrincipal) {
461 // We don't store permissions for NullPrincipals.
462 return NS_OK;
463 }
464
465 MOZ_ASSERT(Kind() == eExpandedPrincipal || Kind() == eContentPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(Kind() == eExpandedPrincipal || Kind() == eContentPrincipal
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(Kind() == eExpandedPrincipal || Kind() == eContentPrincipal
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"Kind() == eExpandedPrincipal || Kind() == eContentPrincipal"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 465); AnnotateMozCrashReason("MOZ_ASSERT" "(" "Kind() == eExpandedPrincipal || Kind() == eContentPrincipal"
")"); do { *((volatile int*)__null) = 465; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
466
467 // Certain origin attributes should not be used to isolate permissions.
468 // Create a stripped copy of both OA sets to compare.
469 mozilla::OriginAttributes ourAttrs = mOriginAttributes;
470 PermissionManager::MaybeStripOriginAttributes(false, ourAttrs);
471 mozilla::OriginAttributes theirAttrs = aOther->OriginAttributesRef();
472 PermissionManager::MaybeStripOriginAttributes(false, theirAttrs);
473
474 if (ourAttrs != theirAttrs) {
475 return NS_OK;
476 }
477
478 if (mOriginNoSuffix == other->mOriginNoSuffix) {
479 *aResult = true;
480 return NS_OK;
481 }
482
483 // If we are matching with an exact host, we're done now - the permissions
484 // don't match otherwise, we need to start comparing subdomains!
485 if (aExactHost) {
486 return NS_OK;
487 }
488
489 nsCOMPtr<nsIURI> ourURI;
490 nsresult rv = GetURI(getter_AddRefs(ourURI));
491 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 491); return rv; } } while (false)
;
492 // Some principal types may indicate success, but still return nullptr for
493 // URI.
494 NS_ENSURE_TRUE(ourURI, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(ourURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "ourURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 494); return NS_ERROR_FAILURE; } } while (false)
;
495
496 nsCOMPtr<nsIURI> otherURI;
497 rv = other->GetURI(getter_AddRefs(otherURI));
498 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 498); return rv; } } while (false)
;
499 NS_ENSURE_TRUE(otherURI, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(otherURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "otherURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 499); return NS_ERROR_FAILURE; } } while (false)
;
500
501 // Compare schemes
502 nsAutoCString otherScheme;
503 rv = otherURI->GetScheme(otherScheme);
504 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 504); return rv; } } while (false)
;
505
506 nsAutoCString ourScheme;
507 rv = ourURI->GetScheme(ourScheme);
508 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 508); return rv; } } while (false)
;
509
510 if (otherScheme != ourScheme) {
511 return NS_OK;
512 }
513
514 // Compare ports
515 int32_t otherPort;
516 rv = otherURI->GetPort(&otherPort);
517 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 517); return rv; } } while (false)
;
518
519 int32_t ourPort;
520 rv = ourURI->GetPort(&ourPort);
521 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 521); return rv; } } while (false)
;
522
523 if (otherPort != ourPort) {
524 return NS_OK;
525 }
526
527 // Check if the host or any subdomain of their host matches.
528 nsAutoCString otherHost;
529 rv = otherURI->GetHost(otherHost);
530 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || otherHost.IsEmpty()) {
531 return NS_OK;
532 }
533
534 nsAutoCString ourHost;
535 rv = ourURI->GetHost(ourHost);
536 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || ourHost.IsEmpty()) {
537 return NS_OK;
538 }
539
540 nsCOMPtr<nsIEffectiveTLDService> tldService =
541 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID"@mozilla.org/network/effective-tld-service;1");
542 if (!tldService) {
543 NS_ERROR("Should have a tld service!")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Should have a tld service!"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 543); MOZ_PretendNoReturn(); } while (0)
;
544 return NS_ERROR_FAILURE;
545 }
546
547 // This loop will not loop forever, as GetNextSubDomain will eventually fail
548 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
549 while (otherHost != ourHost) {
550 rv = tldService->GetNextSubDomain(otherHost, otherHost);
551 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
552 if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
553 return NS_OK;
554 }
555 return rv;
556 }
557 }
558
559 *aResult = true;
560 return NS_OK;
561}
562
563NS_IMETHODIMPnsresult
564BasePrincipal::EqualsConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
565 NS_ENSURE_ARG_POINTER(aOther)do { if ((__builtin_expect(!!(!(aOther)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOther" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 565); return NS_ERROR_INVALID_POINTER; } } while (false)
;
566
567 *aResult = FastEqualsConsideringDomain(aOther);
568
569 return NS_OK;
570}
571
572NS_IMETHODIMPnsresult
573BasePrincipal::EqualsURI(nsIURI* aOtherURI, bool* aResult) {
574 *aResult = false;
575 nsCOMPtr<nsIURI> prinURI;
576 nsresult rv = GetURI(getter_AddRefs(prinURI));
577 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
578 return NS_OK;
579 }
580 return prinURI->EqualsExceptRef(aOtherURI, aResult);
581}
582
583NS_IMETHODIMPnsresult
584BasePrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult) {
585 NS_ENSURE_ARG_POINTER(aOther)do { if ((__builtin_expect(!!(!(aOther)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOther" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 585); return NS_ERROR_INVALID_POINTER; } } while (false)
;
586
587 *aResult = FastSubsumes(aOther);
588
589 return NS_OK;
590}
591
592NS_IMETHODIMPnsresult
593BasePrincipal::SubsumesConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
594 NS_ENSURE_ARG_POINTER(aOther)do { if ((__builtin_expect(!!(!(aOther)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOther" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 594); return NS_ERROR_INVALID_POINTER; } } while (false)
;
595
596 *aResult = FastSubsumesConsideringDomain(aOther);
597
598 return NS_OK;
599}
600
601NS_IMETHODIMPnsresult
602BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther,
603 bool* aResult) {
604 NS_ENSURE_ARG_POINTER(aOther)do { if ((__builtin_expect(!!(!(aOther)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOther" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 604); return NS_ERROR_INVALID_POINTER; } } while (false)
;
605
606 *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
607
608 return NS_OK;
609}
610
611NS_IMETHODIMPnsresult
612BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aAllowIfInheritsPrincipal) {
613 AssertIsOnMainThread();
614 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, false, 0);
615}
616
617NS_IMETHODIMPnsresult
618BasePrincipal::CheckMayLoadWithReporting(nsIURI* aURI,
619 bool aAllowIfInheritsPrincipal,
620 uint64_t aInnerWindowID) {
621 AssertIsOnMainThread();
622 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, true,
623 aInnerWindowID);
624}
625
626nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI,
627 bool aAllowIfInheritsPrincipal,
628 bool aReport,
629 uint64_t aInnerWindowID) {
630 AssertIsOnMainThread(); // Accesses non-threadsafe URI flags and the
631 // non-threadsafe ExtensionPolicyService
632 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 632); return NS_ERROR_INVALID_POINTER; } } while (false)
;
633 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aReport || aInnerWindowID == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aReport || aInnerWindowID ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aReport || aInnerWindowID == 0" " (" "Why do we have an inner window id if we're not supposed to report?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 635); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aReport || aInnerWindowID == 0"
") (" "Why do we have an inner window id if we're not supposed to report?"
")"); do { *((volatile int*)__null) = 635; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
634 aReport || aInnerWindowID == 0,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aReport || aInnerWindowID == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aReport || aInnerWindowID ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aReport || aInnerWindowID == 0" " (" "Why do we have an inner window id if we're not supposed to report?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 635); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aReport || aInnerWindowID == 0"
") (" "Why do we have an inner window id if we're not supposed to report?"
")"); do { *((volatile int*)__null) = 635; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
635 "Why do we have an inner window id if we're not supposed to report?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aReport || aInnerWindowID == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aReport || aInnerWindowID ==
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aReport || aInnerWindowID == 0" " (" "Why do we have an inner window id if we're not supposed to report?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 635); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aReport || aInnerWindowID == 0"
") (" "Why do we have an inner window id if we're not supposed to report?"
")"); do { *((volatile int*)__null) = 635; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
636
637 // Check the internal method first, which allows us to quickly approve loads
638 // for the System Principal.
639 if (MayLoadInternal(aURI)) {
640 return NS_OK;
641 }
642
643 nsresult rv;
644 if (aAllowIfInheritsPrincipal) {
645 // If the caller specified to allow loads of URIs that inherit
646 // our principal, allow the load if this URI inherits its principal.
647 bool doesInheritSecurityContext;
648 rv = NS_URIChainHasFlags(aURI,
649 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
650 &doesInheritSecurityContext);
651 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && doesInheritSecurityContext) {
652 return NS_OK;
653 }
654 }
655
656 // Web Accessible Resources in MV2 Extensions are marked with
657 // URI_FETCHABLE_BY_ANYONE
658 bool fetchableByAnyone;
659 rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE,
660 &fetchableByAnyone);
661 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && fetchableByAnyone) {
662 return NS_OK;
663 }
664
665 // Get the principal uri for the last flag check or error.
666 nsCOMPtr<nsIURI> prinURI;
667 rv = GetURI(getter_AddRefs(prinURI));
668 if (!(NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && prinURI)) {
669 return NS_ERROR_DOM_BAD_URI;
670 }
671
672 // If MV3 Extension uris are web accessible by this principal it is allowed to
673 // load.
674 bool maybeWebAccessible = false;
675 NS_URIChainHasFlags(aURI, nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE,
676 &maybeWebAccessible);
677 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 677); return rv; } } while (false)
;
678 if (maybeWebAccessible) {
679 bool isWebAccessible = false;
680 rv = ExtensionPolicyService::GetSingleton().SourceMayLoadExtensionURI(
681 prinURI, aURI, &isWebAccessible);
682 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && isWebAccessible) {
683 return NS_OK;
684 }
685 }
686
687 if (aReport) {
688 nsScriptSecurityManager::ReportError(
689 "CheckSameOriginError", prinURI, aURI,
690 mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
691 }
692
693 return NS_ERROR_DOM_BAD_URI;
694}
695
696NS_IMETHODIMPnsresult
697BasePrincipal::IsThirdPartyURI(nsIURI* aURI, bool* aRes) {
698 if (IsSystemPrincipal() || (AddonPolicyCore() && AddonAllowsLoad(aURI))) {
699 *aRes = false;
700 return NS_OK;
701 }
702
703 *aRes = true;
704 // If we do not have a URI its always 3rd party.
705 nsCOMPtr<nsIURI> prinURI;
706 nsresult rv = GetURI(getter_AddRefs(prinURI));
707 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
708 return NS_OK;
709 }
710 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
711 return thirdPartyUtil->IsThirdPartyURI(prinURI, aURI, aRes);
712}
713
714NS_IMETHODIMPnsresult
715BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal* aPrin, bool* aRes) {
716 *aRes = true;
717 nsCOMPtr<nsIURI> prinURI;
718 nsresult rv = GetURI(getter_AddRefs(prinURI));
719 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
720 return NS_OK;
721 }
722 return aPrin->IsThirdPartyURI(prinURI, aRes);
723}
724
725NS_IMETHODIMPnsresult
726BasePrincipal::IsThirdPartyChannel(nsIChannel* aChan, bool* aRes) {
727 AssertIsOnMainThread();
728 if (IsSystemPrincipal()) {
729 // Nothing is 3rd party to the system principal.
730 *aRes = false;
731 return NS_OK;
732 }
733
734 nsCOMPtr<nsIURI> prinURI;
735 GetURI(getter_AddRefs(prinURI));
736 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
737 return thirdPartyUtil->IsThirdPartyChannel(aChan, prinURI, aRes);
738}
739
740NS_IMETHODIMPnsresult
741BasePrincipal::IsSameOrigin(nsIURI* aURI, bool* aRes) {
742 *aRes = false;
743 nsCOMPtr<nsIURI> prinURI;
744 nsresult rv = GetURI(getter_AddRefs(prinURI));
745 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
746 // Note that expanded and system principals return here, because they have
747 // no URI.
748 return NS_OK;
749 }
750 *aRes = nsScriptSecurityManager::SecurityCompareURIs(prinURI, aURI);
751 return NS_OK;
752}
753
754NS_IMETHODIMPnsresult
755BasePrincipal::IsL10nAllowed(nsIURI* aURI, bool* aRes) {
756 AssertIsOnMainThread(); // URI_DANGEROUS_TO_LOAD is not threadsafe to query.
757 *aRes = false;
758
759 if (nsContentUtils::IsErrorPage(aURI)) {
760 *aRes = true;
761 return NS_OK;
762 }
763
764 // The system principal is always allowed.
765 if (IsSystemPrincipal()) {
766 *aRes = true;
767 return NS_OK;
768 }
769
770 nsCOMPtr<nsIURI> uri;
771 nsresult rv = GetURI(getter_AddRefs(uri));
772 NS_ENSURE_SUCCESS(rv, NS_OK)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_OK", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 772); return NS_OK; } } while (false)
;
773
774 bool hasFlags;
775
776 // Allow access to uris that cannot be loaded by web content.
777 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
778 &hasFlags);
779 NS_ENSURE_SUCCESS(rv, NS_OK)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_OK", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 779); return NS_OK; } } while (false)
;
780 if (hasFlags) {
781 *aRes = true;
782 return NS_OK;
783 }
784
785 // UI resources also get access.
786 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
787 &hasFlags);
788 NS_ENSURE_SUCCESS(rv, NS_OK)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_OK", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 788); return NS_OK; } } while (false)
;
789 if (hasFlags) {
790 *aRes = true;
791 return NS_OK;
792 }
793
794 auto policy = AddonPolicyCore();
795 *aRes = (policy && policy->IsPrivileged());
796 return NS_OK;
797}
798
799NS_IMETHODIMPnsresult
800BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) {
801 *aRes = false;
802 nsCOMPtr<nsIURI> prinURI;
803 nsresult rv = GetURI(getter_AddRefs(prinURI));
804 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
805 return NS_OK;
806 }
807 *aRes = NS_RelaxStrictFileOriginPolicy(aURI, prinURI);
808 return NS_OK;
809}
810
811NS_IMETHODIMPnsresult
812BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
813 const OriginAttributes& aOriginAttributes,
814 nsACString& _retval) {
815 _retval.Truncate();
816 constexpr auto space = " "_ns;
817
818 nsCOMPtr<nsIURI> uri;
819 nsresult rv = GetURI(getter_AddRefs(uri));
820 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 820); return rv; } } while (false)
;
821
822 nsAutoCString scheme, host, port;
823 if (uri) {
824 uri->GetScheme(scheme);
825 uri->GetHost(host);
826 port.AppendInt(NS_GetRealPort(uri));
827 }
828
829 if (aWithCredentials) {
830 _retval.AssignLiteral("cred");
831 } else {
832 _retval.AssignLiteral("nocred");
833 }
834
835 nsAutoCString spec;
836 rv = aURI->GetSpec(spec);
837 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 837); return rv; } } while (false)
;
838
839 nsAutoCString originAttributesSuffix;
840 aOriginAttributes.CreateSuffix(originAttributesSuffix);
841
842 _retval.Append(space + scheme + space + host + space + port + space + spec +
843 space + originAttributesSuffix);
844
845 return NS_OK;
846}
847
848NS_IMETHODIMPnsresult
849BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
850 uint32_t* aRejectedReason,
851 bool* aOutAllowed) {
852 AssertIsOnMainThread();
853 *aRejectedReason = 0;
854 *aOutAllowed = false;
855
856 nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aCheckWindow);
857 nsCOMPtr<nsIURI> uri;
858 nsresult rv = GetURI(getter_AddRefs(uri));
859 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
860 return rv;
861 }
862 *aOutAllowed = ShouldAllowAccessFor(win, uri, aRejectedReason);
863 return NS_OK;
864}
865
866NS_IMETHODIMPnsresult
867BasePrincipal::GetIsNullPrincipal(bool* aResult) {
868 *aResult = Kind() == eNullPrincipal;
869 return NS_OK;
870}
871
872NS_IMETHODIMPnsresult
873BasePrincipal::GetIsContentPrincipal(bool* aResult) {
874 *aResult = Kind() == eContentPrincipal;
875 return NS_OK;
876}
877
878NS_IMETHODIMPnsresult
879BasePrincipal::GetIsExpandedPrincipal(bool* aResult) {
880 *aResult = Kind() == eExpandedPrincipal;
881 return NS_OK;
882}
883
884NS_IMETHODIMPnsresult
885BasePrincipal::GetAsciiSpec(nsACString& aSpec) {
886 aSpec.Truncate();
887 nsCOMPtr<nsIURI> prinURI;
888 nsresult rv = GetURI(getter_AddRefs(prinURI));
889 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
890 return NS_OK;
891 }
892 return prinURI->GetAsciiSpec(aSpec);
893}
894
895NS_IMETHODIMPnsresult
896BasePrincipal::GetSpec(nsACString& aSpec) {
897 aSpec.Truncate();
898 nsCOMPtr<nsIURI> prinURI;
899 nsresult rv = GetURI(getter_AddRefs(prinURI));
900 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
901 return NS_OK;
902 }
903 return prinURI->GetSpec(aSpec);
904}
905
906NS_IMETHODIMPnsresult
907BasePrincipal::GetAsciiHost(nsACString& aHost) {
908 aHost.Truncate();
909 nsCOMPtr<nsIURI> prinURI;
910 nsresult rv = GetURI(getter_AddRefs(prinURI));
911 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
912 return NS_OK;
913 }
914 return prinURI->GetAsciiHost(aHost);
915}
916
917NS_IMETHODIMPnsresult
918BasePrincipal::GetExposablePrePath(nsACString& aPrepath) {
919 aPrepath.Truncate();
920 nsCOMPtr<nsIURI> prinURI;
921 nsresult rv = GetURI(getter_AddRefs(prinURI));
922 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
923 return NS_OK;
924 }
925
926 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(prinURI);
927 return exposableURI->GetDisplayPrePath(aPrepath);
928}
929
930NS_IMETHODIMPnsresult
931BasePrincipal::GetExposableSpec(nsACString& aSpec) {
932 aSpec.Truncate();
933 nsCOMPtr<nsIURI> prinURI;
934 nsresult rv = GetURI(getter_AddRefs(prinURI));
935 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
936 return NS_OK;
937 }
938 nsCOMPtr<nsIURI> clone;
939 rv = NS_MutateURI(prinURI)
940 .SetQuery(""_ns)
941 .SetRef(""_ns)
942 .SetUserPass(""_ns)
943 .Finalize(clone);
944 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 944); return rv; } } while (false)
;
945 return clone->GetAsciiSpec(aSpec);
946}
947
948NS_IMETHODIMPnsresult
949BasePrincipal::GetPrePath(nsACString& aPath) {
950 aPath.Truncate();
951 nsCOMPtr<nsIURI> prinURI;
952 nsresult rv = GetURI(getter_AddRefs(prinURI));
953 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
954 return NS_OK;
955 }
956 return prinURI->GetPrePath(aPath);
957}
958
959NS_IMETHODIMPnsresult
960BasePrincipal::GetFilePath(nsACString& aPath) {
961 aPath.Truncate();
962 nsCOMPtr<nsIURI> prinURI;
963 nsresult rv = GetURI(getter_AddRefs(prinURI));
964 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
965 return NS_OK;
966 }
967 return prinURI->GetFilePath(aPath);
968}
969
970NS_IMETHODIMPnsresult
971BasePrincipal::GetIsSystemPrincipal(bool* aResult) {
972 *aResult = IsSystemPrincipal();
973 return NS_OK;
974}
975
976NS_IMETHODIMPnsresult
977BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult) {
978 *aResult = AddonPolicyCore() || ContentScriptAddonPolicyCore();
979 return NS_OK;
980}
981
982NS_IMETHODIMPnsresult BasePrincipal::GetIsOnion(bool* aIsOnion) {
983 *aIsOnion = false;
984 nsCOMPtr<nsIURI> prinURI;
985 nsresult rv = GetURI(getter_AddRefs(prinURI));
986 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
987 return NS_OK;
988 }
989
990 nsAutoCString host;
991 rv = prinURI->GetHost(host);
992 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
993 return NS_OK;
994 }
995 *aIsOnion = StringEndsWith(host, ".onion"_ns);
996 return NS_OK;
997}
998
999NS_IMETHODIMPnsresult BasePrincipal::GetIsIpAddress(bool* aIsIpAddress) {
1000 *aIsIpAddress = false;
1001
1002 nsCOMPtr<nsIURI> prinURI;
1003 nsresult rv = GetURI(getter_AddRefs(prinURI));
1004 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1005 return NS_OK;
1006 }
1007
1008 nsAutoCString host;
1009 rv = prinURI->GetHost(host);
1010 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1011 return NS_OK;
1012 }
1013
1014 PRNetAddr prAddr;
1015 memset(&prAddr, 0, sizeof(prAddr));
1016
1017 if (PR_StringToNetAddr(host.get(), &prAddr) == PR_SUCCESS) {
1018 *aIsIpAddress = true;
1019 }
1020
1021 return NS_OK;
1022}
1023
1024NS_IMETHODIMPnsresult BasePrincipal::GetIsLocalIpAddress(bool* aIsIpAddress) {
1025 *aIsIpAddress = false;
1026
1027 nsCOMPtr<nsIURI> prinURI;
1028 nsresult rv = GetURI(getter_AddRefs(prinURI));
1029 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1030 return NS_OK;
1031 }
1032
1033 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
1034 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !ioService) {
1035 return NS_OK;
1036 }
1037 rv = ioService->HostnameIsLocalIPAddress(prinURI, aIsIpAddress);
1038 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1039 *aIsIpAddress = false;
1040 }
1041 return NS_OK;
1042}
1043
1044NS_IMETHODIMPnsresult
1045BasePrincipal::GetScheme(nsACString& aScheme) {
1046 aScheme.Truncate();
1047
1048 nsCOMPtr<nsIURI> prinURI;
1049 nsresult rv = GetURI(getter_AddRefs(prinURI));
1050 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1051 return NS_OK;
1052 }
1053
1054 return prinURI->GetScheme(aScheme);
1055}
1056
1057NS_IMETHODIMPnsresult
1058BasePrincipal::SchemeIs(const char* aScheme, bool* aResult) {
1059 *aResult = false;
1060 nsCOMPtr<nsIURI> prinURI;
1061 nsresult rv = GetURI(getter_AddRefs(prinURI));
1062 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1062)
|| !prinURI) {
1063 return NS_OK;
1064 }
1065 *aResult = prinURI->SchemeIs(aScheme);
1066 return NS_OK;
1067}
1068
1069NS_IMETHODIMPnsresult
1070BasePrincipal::IsURIInPrefList(const char* aPref, bool* aResult) {
1071 AssertIsOnMainThread();
1072 *aResult = false;
1073 nsCOMPtr<nsIURI> prinURI;
1074 nsresult rv = GetURI(getter_AddRefs(prinURI));
1075 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1076 return NS_OK;
1077 }
1078 *aResult = nsContentUtils::IsURIInPrefList(prinURI, aPref);
1079 return NS_OK;
1080}
1081
1082NS_IMETHODIMPnsresult
1083BasePrincipal::IsURIInList(const nsACString& aList, bool* aResult) {
1084 *aResult = false;
1085 nsCOMPtr<nsIURI> prinURI;
1086
1087 nsresult rv = GetURI(getter_AddRefs(prinURI));
1088 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1089 return NS_OK;
1090 }
1091
1092 *aResult = nsContentUtils::IsURIInList(prinURI, nsCString(aList));
1093 return NS_OK;
1094}
1095
1096NS_IMETHODIMPnsresult
1097BasePrincipal::IsContentAccessibleAboutURI(bool* aResult) {
1098 *aResult = false;
1099
1100 nsCOMPtr<nsIURI> prinURI;
1101 nsresult rv = GetURI(getter_AddRefs(prinURI));
1102 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1103 return NS_OK;
1104 }
1105
1106 if (!prinURI->SchemeIs("about")) {
1107 return NS_OK;
1108 }
1109
1110 *aResult = NS_IsContentAccessibleAboutURI(prinURI);
1111 return NS_OK;
1112}
1113
1114NS_IMETHODIMPnsresult
1115BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult) {
1116 AssertIsOnMainThread();
1117 *aResult = false;
1118
1119 nsCOMPtr<nsIURI> uri;
1120 nsresult rv = GetURI(getter_AddRefs(uri));
1121 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !uri) {
1122 return NS_OK;
1123 }
1124
1125 *aResult = nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri);
1126 return NS_OK;
1127}
1128
1129NS_IMETHODIMPnsresult
1130BasePrincipal::GetIsLoopbackHost(bool* aRes) {
1131 AssertIsOnMainThread();
1132 *aRes = false;
1133 nsAutoCString host;
1134 nsresult rv = GetHost(host);
1135 // Swallow potential failure as this method is infallible.
1136 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1137 return NS_OK;
1138 }
1139
1140 *aRes = nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(host);
1141 return NS_OK;
1142}
1143
1144NS_IMETHODIMPnsresult
1145BasePrincipal::GetAboutModuleFlags(uint32_t* flags) {
1146 AssertIsOnMainThread();
1147 *flags = 0;
1148 nsCOMPtr<nsIURI> prinURI;
1149 nsresult rv = GetURI(getter_AddRefs(prinURI));
1150 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1151 return NS_ERROR_NOT_AVAILABLE;
1152 }
1153 if (!prinURI->SchemeIs("about")) {
1154 return NS_OK;
1155 }
1156
1157 nsCOMPtr<nsIAboutModule> aboutModule;
1158 rv = NS_GetAboutModule(prinURI, getter_AddRefs(aboutModule));
1159 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !aboutModule) {
1160 return rv;
1161 }
1162 return aboutModule->GetURIFlags(prinURI, flags);
1163}
1164
1165NS_IMETHODIMPnsresult
1166BasePrincipal::GetOriginAttributes(JSContext* aCx,
1167 JS::MutableHandle<JS::Value> aVal) {
1168 if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))NS_warn_if_impl(!ToJSValue(aCx, mOriginAttributes, aVal), "!ToJSValue(aCx, mOriginAttributes, aVal)"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1168)
) {
1169 return NS_ERROR_FAILURE;
1170 }
1171 return NS_OK;
1172}
1173
1174NS_IMETHODIMPnsresult
1175BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) {
1176 MOZ_ASSERT(mOriginSuffix)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mOriginSuffix)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mOriginSuffix))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mOriginSuffix",
"/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1176); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mOriginSuffix"
")"); do { *((volatile int*)__null) = 1176; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1177 mOriginSuffix->ToUTF8String(aOriginAttributes);
1178 return NS_OK;
1179}
1180
1181NS_IMETHODIMPnsresult
1182BasePrincipal::GetUserContextId(uint32_t* aUserContextId) {
1183 *aUserContextId = UserContextId();
1184 return NS_OK;
1185}
1186
1187NS_IMETHODIMPnsresult
1188BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) {
1189 *aPrivateBrowsingId = PrivateBrowsingId();
1190 return NS_OK;
1191}
1192
1193nsresult BasePrincipal::GetAddonPolicy(
1194 extensions::WebExtensionPolicy** aResult) {
1195 AssertIsOnMainThread();
1196 RefPtr<extensions::WebExtensionPolicy> policy(AddonPolicy());
1197 policy.forget(aResult);
1198 return NS_OK;
1199}
1200
1201nsresult BasePrincipal::GetContentScriptAddonPolicy(
1202 extensions::WebExtensionPolicy** aResult) {
1203 RefPtr<extensions::WebExtensionPolicy> policy(ContentScriptAddonPolicy());
1204 policy.forget(aResult);
1205 return NS_OK;
1206}
1207
1208extensions::WebExtensionPolicy* BasePrincipal::AddonPolicy() {
1209 AssertIsOnMainThread();
1210 RefPtr<extensions::WebExtensionPolicyCore> core = AddonPolicyCore();
1211 return core ? core->GetMainThreadPolicy() : nullptr;
1212}
1213
1214RefPtr<extensions::WebExtensionPolicyCore> BasePrincipal::AddonPolicyCore() {
1215 if (Is<ContentPrincipal>()) {
1216 return As<ContentPrincipal>()->AddonPolicyCore();
1217 }
1218 return nullptr;
1219}
1220
1221bool BasePrincipal::AddonHasPermission(const nsAtom* aPerm) {
1222 if (auto policy = AddonPolicyCore()) {
1223 return policy->HasPermission(aPerm);
1224 }
1225 return false;
1226}
1227
1228nsIPrincipal* BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
1229 if (Is<ExpandedPrincipal>()) {
1230 return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI);
1231 }
1232 return this;
1233}
1234
1235bool BasePrincipal::OverridesCSP(nsIPrincipal* aDocumentPrincipal) {
1236 MOZ_ASSERT(aDocumentPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDocumentPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDocumentPrincipal))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("aDocumentPrincipal"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1236); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDocumentPrincipal"
")"); do { *((volatile int*)__null) = 1236; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1237
1238 // Expanded principals override CSP if and only if they subsume the document
1239 // principal.
1240 if (mKind == eExpandedPrincipal) {
1241 return FastSubsumes(aDocumentPrincipal);
1242 }
1243 // Extension principals always override the CSP of non-extension principals.
1244 // This is primarily for the sake of their stylesheets, which are usually
1245 // loaded from channels and cannot have expanded principals.
1246 return (AddonPolicyCore() &&
1247 !BasePrincipal::Cast(aDocumentPrincipal)->AddonPolicyCore());
1248}
1249
1250already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1251 nsIURI* aURI, const OriginAttributes& aAttrs, nsIURI* aInitialDomain) {
1252 MOZ_ASSERT(aURI)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aURI)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aURI))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aURI", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1252); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ")");
do { *((volatile int*)__null) = 1252; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1253
1254 nsAutoCString originNoSuffix;
1255 nsresult rv =
1256 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
1257 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1258 // If the generation of the origin fails, we still want to have a valid
1259 // principal. Better to return a null principal here.
1260 return NullPrincipal::Create(aAttrs);
1261 }
1262
1263 return CreateContentPrincipal(aURI, aAttrs, originNoSuffix, aInitialDomain);
1264}
1265
1266already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1267 nsIURI* aURI, const OriginAttributes& aAttrs,
1268 const nsACString& aOriginNoSuffix, nsIURI* aInitialDomain) {
1269 MOZ_ASSERT(aURI)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aURI)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aURI))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aURI", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1269); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ")");
do { *((volatile int*)__null) = 1269; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1270 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aOriginNoSuffix.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aOriginNoSuffix.IsEmpty()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!aOriginNoSuffix.IsEmpty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1270); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aOriginNoSuffix.IsEmpty()"
")"); do { *((volatile int*)__null) = 1270; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1271
1272 // If the URI is supposed to inherit the security context of whoever loads it,
1273 // we shouldn't make a content principal for it.
1274 bool inheritsPrincipal;
1275 nsresult rv = NS_URIChainHasFlags(
1276 aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
1277 &inheritsPrincipal);
1278 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || inheritsPrincipal) {
1279 return NullPrincipal::Create(aAttrs);
1280 }
1281
1282 // Check whether the URI knows what its principal is supposed to be.
1283#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1284 nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
1285 do_QueryInterface(aURI);
1286 if (uriWithSpecialOrigin) {
1287 nsCOMPtr<nsIURI> origin;
1288 rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
1289 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1289)
) {
1290 return nullptr;
1291 }
1292 MOZ_ASSERT(origin)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(origin)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(origin))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("origin", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "origin" ")"
); do { *((volatile int*)__null) = 1292; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1293 OriginAttributes attrs;
1294 RefPtr<BasePrincipal> principal =
1295 CreateContentPrincipal(origin, attrs, aInitialDomain);
1296 return principal.forget();
1297 }
1298#endif
1299
1300 nsCOMPtr<nsIPrincipal> blobPrincipal;
1301 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1302 aURI, getter_AddRefs(blobPrincipal))) {
1303 MOZ_ASSERT(blobPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(blobPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(blobPrincipal))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("blobPrincipal",
"/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1303); AnnotateMozCrashReason("MOZ_ASSERT" "(" "blobPrincipal"
")"); do { *((volatile int*)__null) = 1303; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1304 MOZ_ASSERT(!aInitialDomain,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aInitialDomain)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aInitialDomain))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!aInitialDomain"
" (" "an initial domain for a blob URI makes no sense" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1305); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aInitialDomain"
") (" "an initial domain for a blob URI makes no sense" ")")
; do { *((volatile int*)__null) = 1305; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1305 "an initial domain for a blob URI makes no sense")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aInitialDomain)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aInitialDomain))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!aInitialDomain"
" (" "an initial domain for a blob URI makes no sense" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1305); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aInitialDomain"
") (" "an initial domain for a blob URI makes no sense" ")")
; do { *((volatile int*)__null) = 1305; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1306 RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
1307 return principal.forget();
1308 }
1309
1310 // Mint a content principal.
1311 RefPtr<ContentPrincipal> principal =
1312 new ContentPrincipal(aURI, aAttrs, aOriginNoSuffix, aInitialDomain);
1313 return principal.forget();
1314}
1315
1316already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1317 const nsACString& aOrigin) {
1318 MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!StringBeginsWith(aOrigin, "["_ns))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!StringBeginsWith(aOrigin, "["_ns
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!StringBeginsWith(aOrigin, \"[\"_ns)" " (" "CreateContentPrincipal does not support System and Expanded "
"principals" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!StringBeginsWith(aOrigin, \"[\"_ns)"
") (" "CreateContentPrincipal does not support System and Expanded "
"principals" ")"); do { *((volatile int*)__null) = 1320; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1319 "CreateContentPrincipal does not support System and Expanded "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!StringBeginsWith(aOrigin, "["_ns))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!StringBeginsWith(aOrigin, "["_ns
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!StringBeginsWith(aOrigin, \"[\"_ns)" " (" "CreateContentPrincipal does not support System and Expanded "
"principals" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!StringBeginsWith(aOrigin, \"[\"_ns)"
") (" "CreateContentPrincipal does not support System and Expanded "
"principals" ")"); do { *((volatile int*)__null) = 1320; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
1320 "principals")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!StringBeginsWith(aOrigin, "["_ns))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!StringBeginsWith(aOrigin, "["_ns
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!StringBeginsWith(aOrigin, \"[\"_ns)" " (" "CreateContentPrincipal does not support System and Expanded "
"principals" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!StringBeginsWith(aOrigin, \"[\"_ns)"
") (" "CreateContentPrincipal does not support System and Expanded "
"principals" ")"); do { *((volatile int*)__null) = 1320; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
1321
1322 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!StringBeginsWith(aOrigin, nsLiteralCString("moz-nullprincipal"
":")))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!StringBeginsWith(aOrigin, nsLiteralCString("moz-nullprincipal"
":"))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!StringBeginsWith(aOrigin, nsLiteralCString(\"moz-nullprincipal\" \":\"))"
" (" "CreateContentPrincipal does not support NullPrincipal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1324); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!StringBeginsWith(aOrigin, nsLiteralCString(\"moz-nullprincipal\" \":\"))"
") (" "CreateContentPrincipal does not support NullPrincipal"
")"); do { *((volatile int*)__null) = 1324; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1323 !StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!StringBeginsWith(aOrigin, nsLiteralCString("moz-nullprincipal"
":")))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!StringBeginsWith(aOrigin, nsLiteralCString("moz-nullprincipal"
":"))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!StringBeginsWith(aOrigin, nsLiteralCString(\"moz-nullprincipal\" \":\"))"
" (" "CreateContentPrincipal does not support NullPrincipal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1324); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!StringBeginsWith(aOrigin, nsLiteralCString(\"moz-nullprincipal\" \":\"))"
") (" "CreateContentPrincipal does not support NullPrincipal"
")"); do { *((volatile int*)__null) = 1324; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1324 "CreateContentPrincipal does not support NullPrincipal")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!StringBeginsWith(aOrigin, nsLiteralCString("moz-nullprincipal"
":")))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!StringBeginsWith(aOrigin, nsLiteralCString("moz-nullprincipal"
":"))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!StringBeginsWith(aOrigin, nsLiteralCString(\"moz-nullprincipal\" \":\"))"
" (" "CreateContentPrincipal does not support NullPrincipal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1324); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!StringBeginsWith(aOrigin, nsLiteralCString(\"moz-nullprincipal\" \":\"))"
") (" "CreateContentPrincipal does not support NullPrincipal"
")"); do { *((volatile int*)__null) = 1324; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1325
1326 nsAutoCString originNoSuffix;
1327 OriginAttributes attrs;
1328 if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
1329 return nullptr;
1330 }
1331
1332 nsCOMPtr<nsIURI> uri;
1333 nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
1334 NS_ENSURE_SUCCESS(rv, nullptr)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", "nullptr", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1334); return nullptr; } } while (false)
;
1335
1336 return BasePrincipal::CreateContentPrincipal(uri, attrs);
1337}
1338
1339already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingOriginAttributes(
1340 const OriginAttributes& aOriginAttributes) {
1341 if (NS_WARN_IF(!IsContentPrincipal())NS_warn_if_impl(!IsContentPrincipal(), "!IsContentPrincipal()"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1341)
) {
1342 return nullptr;
1343 }
1344
1345 nsAutoCString originNoSuffix;
1346 nsresult rv = GetOriginNoSuffix(originNoSuffix);
1347 NS_ENSURE_SUCCESS(rv, nullptr)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", "nullptr", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1347); return nullptr; } } while (false)
;
1348
1349 nsCOMPtr<nsIURI> uri;
1350 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri)))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetURI(getter_AddRefs(uri)))), 1)))), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "NS_SUCCEEDED(GetURI(getter_AddRefs(uri)))" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1350); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(GetURI(getter_AddRefs(uri)))" ")"); do {
*((volatile int*)__null) = 1350; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (false
)
;
1351
1352 // XXX: This does not copy over the domain. Should it?
1353 RefPtr<ContentPrincipal> copy =
1354 new ContentPrincipal(uri, aOriginAttributes, originNoSuffix, nullptr);
1355 return copy.forget();
1356}
1357
1358extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
1359 AssertIsOnMainThread();
1360 RefPtr<extensions::WebExtensionPolicyCore> core =
1361 ContentScriptAddonPolicyCore();
1362 return core ? core->GetMainThreadPolicy() : nullptr;
1363}
1364
1365RefPtr<extensions::WebExtensionPolicyCore>
1366BasePrincipal::ContentScriptAddonPolicyCore() {
1367 if (!Is<ExpandedPrincipal>()) {
1368 return nullptr;
1369 }
1370
1371 auto* expanded = As<ExpandedPrincipal>();
1372 for (const auto& prin : expanded->AllowList()) {
1373 if (RefPtr<extensions::WebExtensionPolicyCore> policy =
1374 BasePrincipal::Cast(prin)->AddonPolicyCore()) {
1375 return policy;
1376 }
1377 }
1378
1379 return nullptr;
1380}
1381
1382bool BasePrincipal::AddonAllowsLoad(nsIURI* aURI,
1383 bool aExplicit /* = false */) {
1384 if (Is<ExpandedPrincipal>()) {
1385 return As<ExpandedPrincipal>()->AddonAllowsLoad(aURI, aExplicit);
1386 }
1387 if (auto policy = AddonPolicyCore()) {
1388 return policy->CanAccessURI(aURI, aExplicit);
1389 }
1390 return false;
1391}
1392
1393NS_IMETHODIMPnsresult
1394BasePrincipal::GetLocalStorageQuotaKey(nsACString& aKey) {
1395 aKey.Truncate();
1396
1397 nsCOMPtr<nsIURI> uri;
1398 nsresult rv = GetURI(getter_AddRefs(uri));
1399 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1399); return rv; } } while (false)
;
1400 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(uri)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "uri" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1400); return NS_ERROR_UNEXPECTED; } } while (false)
;
1401
1402 // The special handling of the file scheme should be consistent with
1403 // GetStorageOriginKey.
1404
1405 nsAutoCString baseDomain;
1406 rv = uri->GetAsciiHost(baseDomain);
1407 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1407); return rv; } } while (false)
;
1408
1409 if (baseDomain.IsEmpty() && uri->SchemeIs("file")) {
1410 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1411 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1411); return rv; } } while (false)
;
1412
1413 rv = url->GetDirectory(baseDomain);
1414 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1414); return rv; } } while (false)
;
1415 } else {
1416 nsCOMPtr<nsIEffectiveTLDService> eTLDService(
1417 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID"@mozilla.org/network/effective-tld-service;1", &rv));
1418 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1418); return rv; } } while (false)
;
1419
1420 nsAutoCString eTLDplusOne;
1421 rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
1422 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1423 baseDomain = eTLDplusOne;
1424 } else if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
1425 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
1426 rv = NS_OK;
1427 }
1428 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1428); return rv; } } while (false)
;
1429 }
1430
1431 OriginAttributesRef().CreateSuffix(aKey);
1432
1433 nsAutoCString subdomainsDBKey;
1434 rv = dom::StorageUtils::CreateReversedDomain(baseDomain, subdomainsDBKey);
1435 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1435); return rv; } } while (false)
;
1436
1437 aKey.Append(':');
1438 aKey.Append(subdomainsDBKey);
1439
1440 return NS_OK;
1441}
1442
1443NS_IMETHODIMPnsresult
1444BasePrincipal::GetNextSubDomainPrincipal(
1445 nsIPrincipal** aNextSubDomainPrincipal) {
1446 nsCOMPtr<nsIURI> uri;
1447 nsresult rv = GetURI(getter_AddRefs(uri));
1448 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !uri) {
1449 return NS_OK;
1450 }
1451
1452 nsAutoCString host;
1453 rv = uri->GetHost(host);
1454 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || host.IsEmpty()) {
1455 return NS_OK;
1456 }
1457
1458 nsCString subDomain;
1459 rv = nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host, subDomain);
1460
1461 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || subDomain.IsEmpty()) {
1462 return NS_OK;
1463 }
1464
1465 nsCOMPtr<nsIURI> subDomainURI;
1466 rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI);
1467 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !subDomainURI) {
1468 return NS_OK;
1469 }
1470 // Copy the attributes over
1471 mozilla::OriginAttributes attrs = OriginAttributesRef();
1472
1473 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1474 // Disable userContext for permissions.
1475 attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
1476 }
1477 RefPtr<nsIPrincipal> principal =
1478 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
1479
1480 if (!principal) {
1481 return NS_OK;
1482 }
1483 principal.forget(aNextSubDomainPrincipal);
1484 return NS_OK;
1485}
1486
1487NS_IMETHODIMPnsresult
1488BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
1489 aOriginKey.Truncate();
1490
1491 nsCOMPtr<nsIURI> uri;
1492 nsresult rv = GetURI(getter_AddRefs(uri));
1493 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1493); return rv; } } while (false)
;
1494 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(uri)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "uri" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1494); return NS_ERROR_UNEXPECTED; } } while (false)
;
1495
1496 // The special handling of the file scheme should be consistent with
1497 // GetLocalStorageQuotaKey.
1498
1499 nsAutoCString domainOrigin;
1500 rv = uri->GetAsciiHost(domainOrigin);
1501 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1501); return rv; } } while (false)
;
1502
1503 if (domainOrigin.IsEmpty()) {
1504 // For the file:/// protocol use the exact directory as domain.
1505 if (uri->SchemeIs("file")) {
1506 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1507 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1507); return rv; } } while (false)
;
1508 rv = url->GetDirectory(domainOrigin);
1509 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1509); return rv; } } while (false)
;
1510 }
1511 }
1512
1513 // Append reversed domain
1514 nsAutoCString reverseDomain;
1515 rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
1516 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1516); return rv; } } while (false)
;
1517
1518 aOriginKey.Append(reverseDomain);
1519
1520 // Append scheme
1521 nsAutoCString scheme;
1522 rv = uri->GetScheme(scheme);
1523 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1523); return rv; } } while (false)
;
1524
1525 aOriginKey.Append(':');
1526 aOriginKey.Append(scheme);
1527
1528 // Append port if any
1529 int32_t port = NS_GetRealPort(uri);
1530 if (port != -1) {
1531 aOriginKey.Append(nsPrintfCString(":%d", port));
1532 }
1533
1534 return NS_OK;
1535}
1536
1537NS_IMETHODIMPnsresult
1538BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
1539 AssertIsOnMainThread();
1540 *aIsScriptAllowedByPolicy = false;
1541 nsCOMPtr<nsIURI> prinURI;
1542 nsresult rv = GetURI(getter_AddRefs(prinURI));
1543 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1544 return NS_OK;
1545 }
1546 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1547 if (!ssm) {
1548 return NS_ERROR_UNEXPECTED;
1549 }
1550 return ssm->PolicyAllowsScript(prinURI, aIsScriptAllowedByPolicy);
1551}
1552
1553bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
1554 MOZ_ASSERT(IsInitialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsInitialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsInitialized()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("IsInitialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1554); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsInitialized()"
")"); do { *((volatile int*)__null) = 1554; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1555 MOZ_ASSERT(aOther.IsInitialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aOther.IsInitialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aOther.IsInitialized()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aOther.IsInitialized()"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1555); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOther.IsInitialized()"
")"); do { *((volatile int*)__null) = 1555; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1556 return mPrincipal->FastEquals(aOther.mPrincipal);
1557}
1558
1559NS_IMETHODIMPnsresult
1560BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
1561 nsIReferrerInfo** _retval) {
1562 nsCOMPtr<nsIURI> prinURI;
1563 RefPtr<dom::ReferrerInfo> info;
1564 nsresult rv = GetURI(getter_AddRefs(prinURI));
1565 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !prinURI) {
1566 info = new dom::ReferrerInfo(nullptr);
1567 info.forget(_retval);
1568 return NS_OK;
1569 }
1570 info = new dom::ReferrerInfo(prinURI, aReferrerPolicy);
1571 info.forget(_retval);
1572 return NS_OK;
1573}
1574
1575NS_IMETHODIMPnsresult
1576BasePrincipal::GetPrecursorPrincipal(nsIPrincipal** aPrecursor) {
1577 *aPrecursor = nullptr;
1578 return NS_OK;
1579}
1580
1581NS_IMPL_ADDREF(BasePrincipal::Deserializer)MozExternalRefCountType BasePrincipal::Deserializer::AddRef(void
) { static_assert(!std::is_destructible_v<BasePrincipal::Deserializer
>, "Reference-counted class " "BasePrincipal::Deserializer"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1581); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1581; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BasePrincipal::Deserializer" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("BasePrincipal::Deserializer" != nullptr))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("\"BasePrincipal::Deserializer\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1581); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BasePrincipal::Deserializer\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1581; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BasePrincipal::Deserializer" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"BasePrincipal::Deserializer"), (uint32_t)(sizeof(*this))); return
count; }
1582NS_IMPL_RELEASE(BasePrincipal::Deserializer)MozExternalRefCountType BasePrincipal::Deserializer::Release(
void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1582); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1582
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BasePrincipal::Deserializer" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("BasePrincipal::Deserializer" != nullptr))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("\"BasePrincipal::Deserializer\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1582); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BasePrincipal::Deserializer\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1582; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BasePrincipal::Deserializer" " not thread-safe"
); const char* const nametmp = "BasePrincipal::Deserializer";
nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; }
1583
1584NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer)nsresult BasePrincipal::Deserializer::QueryInterface(const nsIID
& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) {
NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1584); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
1585 NS_INTERFACE_MAP_ENTRY(nsISupports)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(this); else
1586 NS_INTERFACE_MAP_ENTRY(nsISerializable)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISerializable>)) foundInterface
= static_cast<nsISerializable*>(this); else
1587 if (mPrincipal) {
1588 return mPrincipal->QueryInterface(aIID, aInstancePtr);
1589 } else
1590NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::COMTypeInfo<nsISupports
, void>::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::COMTypeInfo
<nsISupports, void>::kIID))))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
, "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 1590; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1591
1592NS_IMETHODIMPnsresult
1593BasePrincipal::Deserializer::Write(nsIObjectOutputStream* aStream) {
1594 // Read is used still for legacy principals
1595 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Old style serialization is removed"
")", "/var/lib/jenkins/workspace/firefox-scan-build/caps/BasePrincipal.cpp"
, 1595); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "false"
") (" "Old style serialization is removed" ")"); do { *((volatile
int*)__null) = 1595; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1596 return NS_OK;
1597}
1598
1599/* static */
1600void BasePrincipal::WriteJSONProperty(JSONWriter& aWriter,
1601 const Span<const char>& aKey,
1602 const nsCString& aValue) {
1603 aWriter.StringProperty(aKey, aValue);
1
Calling 'JSONWriter::StringProperty'
1604}
1605
1606} // namespace mozilla

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

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/* A JSON pretty-printer class. */
8
9// A typical JSON-writing library requires you to first build up a data
10// structure that represents a JSON object and then serialize it (to file, or
11// somewhere else). This approach makes for a clean API, but building the data
12// structure takes up memory. Sometimes that isn't desirable, such as when the
13// JSON data is produced for memory reporting.
14//
15// The JSONWriter class instead allows JSON data to be written out
16// incrementally without building up large data structures.
17//
18// The API is slightly uglier than you would see in a typical JSON-writing
19// library, but still fairly easy to use. It's possible to generate invalid
20// JSON with JSONWriter, but typically the most basic testing will identify any
21// such problems.
22//
23// Similarly, there are no RAII facilities for automatically closing objects
24// and arrays. These would be nice if you are generating all your code within
25// nested functions, but in other cases you'd have to maintain an explicit
26// stack of RAII objects and manually unwind it, which is no better than just
27// calling "end" functions. Furthermore, the consequences of forgetting to
28// close an object or array are obvious and, again, will be identified via
29// basic testing, unlike other cases where RAII is typically used (e.g. smart
30// pointers) and the consequences of defects are more subtle.
31//
32// Importantly, the class does solve the two hard problems of JSON
33// pretty-printing, which are (a) correctly escaping strings, and (b) adding
34// appropriate indentation and commas between items.
35//
36// By default, every property is placed on its own line. However, it is
37// possible to request that objects and arrays be placed entirely on a single
38// line, which can reduce output size significantly in some cases.
39//
40// Strings used (for property names and string property values) are |const
41// char*| throughout, and can be ASCII or UTF-8.
42//
43// EXAMPLE
44// -------
45// Assume that |MyWriteFunc| is a class that implements |JSONWriteFunc|. The
46// following code:
47//
48// JSONWriter w(MakeUnique<MyWriteFunc>());
49// w.Start();
50// {
51// w.NullProperty("null");
52// w.BoolProperty("bool", true);
53// w.IntProperty("int", 1);
54// w.StartArrayProperty("array");
55// {
56// w.StringElement("string");
57// w.StartObjectElement();
58// {
59// w.DoubleProperty("double", 3.4);
60// w.StartArrayProperty("single-line array", w.SingleLineStyle);
61// {
62// w.IntElement(1);
63// w.StartObjectElement(); // SingleLineStyle is inherited from
64// w.EndObjectElement(); // above for this collection
65// }
66// w.EndArray();
67// }
68// w.EndObjectElement();
69// }
70// w.EndArrayProperty();
71// }
72// w.End();
73//
74// will produce pretty-printed output for the following JSON object:
75//
76// {
77// "null": null,
78// "bool": true,
79// "int": 1,
80// "array": [
81// "string",
82// {
83// "double": 3.4,
84// "single-line array": [1, {}]
85// }
86// ]
87// }
88//
89// The nesting in the example code is obviously optional, but can aid
90// readability.
91
92#ifndef mozilla_JSONWriter_h
93#define mozilla_JSONWriter_h
94
95#include "double-conversion/double-conversion.h"
96#include "mozilla/Assertions.h"
97#include "mozilla/IntegerPrintfMacros.h"
98#include "mozilla/PodOperations.h"
99#include "mozilla/Span.h"
100#include "mozilla/Sprintf.h"
101#include "mozilla/UniquePtr.h"
102#include "mozilla/Vector.h"
103
104#include <utility>
105
106namespace mozilla {
107
108// A quasi-functor for JSONWriter. We don't use a true functor because that
109// requires templatizing JSONWriter, and the templatization seeps to lots of
110// places we don't want it to.
111class JSONWriteFunc {
112 public:
113 virtual void Write(const Span<const char>& aStr) = 0;
114 virtual ~JSONWriteFunc() = default;
115};
116
117// Ideally this would be within |EscapedString| but when compiling with GCC
118// on Linux that caused link errors, whereas this formulation didn't.
119namespace detail {
120extern MFBT_DATA__attribute__((weak)) __attribute__((visibility("default"))) const char gTwoCharEscapes[256];
121} // namespace detail
122
123class JSONWriter {
124 // From http://www.ietf.org/rfc/rfc4627.txt:
125 //
126 // "All Unicode characters may be placed within the quotation marks except
127 // for the characters that must be escaped: quotation mark, reverse
128 // solidus, and the control characters (U+0000 through U+001F)."
129 //
130 // This implementation uses two-char escape sequences where possible, namely:
131 //
132 // \", \\, \b, \f, \n, \r, \t
133 //
134 // All control characters not in the above list are represented with a
135 // six-char escape sequence, e.g. '\u000b' (a.k.a. '\v').
136 //
137 class EscapedString {
138 // `mStringSpan` initially points at the user-provided string. If that
139 // string needs escaping, `mStringSpan` will point at `mOwnedStr` below.
140 Span<const char> mStringSpan;
141 // String storage in case escaping is actually needed, null otherwise.
142 UniquePtr<char[]> mOwnedStr;
143
144 void CheckInvariants() const {
145 // Either there was no escaping so `mOwnedStr` is null, or escaping was
146 // needed, in which case `mStringSpan` should point at `mOwnedStr`.
147 MOZ_ASSERT(!mOwnedStr || mStringSpan.data() == mOwnedStr.get())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mOwnedStr || mStringSpan.data() == mOwnedStr.get())
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mOwnedStr || mStringSpan.data() == mOwnedStr.get())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!mOwnedStr || mStringSpan.data() == mOwnedStr.get()"
, "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 147); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mOwnedStr || mStringSpan.data() == mOwnedStr.get()"
")"); do { *((volatile int*)__null) = 147; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
148 }
149
150 static char hexDigitToAsciiChar(uint8_t u) {
151 u = u & 0xf;
152 return u < 10 ? '0' + u : 'a' + (u - 10);
153 }
154
155 public:
156 explicit EscapedString(const Span<const char>& aStr) : mStringSpan(aStr) {
157 // First, see if we need to modify the string.
158 size_t nExtra = 0;
159 for (const char& c : aStr) {
160 // ensure it can't be interpreted as negative
161 uint8_t u = static_cast<uint8_t>(c);
162 if (u == 0) {
163 // Null terminator within the span, assume we may have been given a
164 // span to a buffer that contains a null-terminated string in it.
165 // We need to truncate the Span so that it doesn't include this null
166 // terminator and anything past it; Either we will return it as-is, or
167 // processing should stop there.
168 mStringSpan = mStringSpan.First(&c - mStringSpan.data());
169 break;
170 }
171 if (detail::gTwoCharEscapes[u]) {
172 nExtra += 1;
173 } else if (u <= 0x1f) {
174 nExtra += 5;
175 }
176 }
177
178 // Note: Don't use `aStr` anymore, as it could contain a null terminator;
179 // use the correctly-sized `mStringSpan` instead.
180
181 if (nExtra == 0) {
182 // No escapes needed. mStringSpan already points at the original string.
183 CheckInvariants();
184 return;
185 }
186
187 // Escapes are needed. We'll create a new string.
188 mOwnedStr = MakeUnique<char[]>(mStringSpan.Length() + nExtra);
189
190 size_t i = 0;
191 for (const char c : mStringSpan) {
192 // ensure it can't be interpreted as negative
193 uint8_t u = static_cast<uint8_t>(c);
194 MOZ_ASSERT(u != 0, "Null terminator should have been handled above")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(u != 0)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(u != 0))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("u != 0" " (" "Null terminator should have been handled above"
")", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 194); AnnotateMozCrashReason("MOZ_ASSERT" "(" "u != 0" ") ("
"Null terminator should have been handled above" ")"); do { *
((volatile int*)__null) = 194; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
195 if (detail::gTwoCharEscapes[u]) {
196 mOwnedStr[i++] = '\\';
197 mOwnedStr[i++] = detail::gTwoCharEscapes[u];
198 } else if (u <= 0x1f) {
199 mOwnedStr[i++] = '\\';
200 mOwnedStr[i++] = 'u';
201 mOwnedStr[i++] = '0';
202 mOwnedStr[i++] = '0';
203 mOwnedStr[i++] = hexDigitToAsciiChar((u & 0x00f0) >> 4);
204 mOwnedStr[i++] = hexDigitToAsciiChar(u & 0x000f);
205 } else {
206 mOwnedStr[i++] = u;
207 }
208 }
209 MOZ_ASSERT(i == mStringSpan.Length() + nExtra)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(i == mStringSpan.Length() + nExtra)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(i == mStringSpan.Length() + nExtra
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"i == mStringSpan.Length() + nExtra", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 209); AnnotateMozCrashReason("MOZ_ASSERT" "(" "i == mStringSpan.Length() + nExtra"
")"); do { *((volatile int*)__null) = 209; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
210 mStringSpan = Span<const char>(mOwnedStr.get(), i);
211 CheckInvariants();
212 }
213
214 explicit EscapedString(const char* aStr) = delete;
215
216 const Span<const char>& SpanRef() const { return mStringSpan; }
217 };
218
219 public:
220 // Collections (objects and arrays) are printed in a multi-line style by
221 // default. This can be changed to a single-line style if SingleLineStyle is
222 // specified. If a collection is printed in single-line style, every nested
223 // collection within it is also printed in single-line style, even if
224 // multi-line style is requested.
225 // If SingleLineStyle is set in the constructer, all JSON whitespace is
226 // eliminated, including spaces after colons and commas, for the most compact
227 // encoding possible.
228 enum CollectionStyle {
229 MultiLineStyle, // the default
230 SingleLineStyle
231 };
232
233 protected:
234 static constexpr Span<const char> scArrayBeginString = MakeStringSpan("[");
235 static constexpr Span<const char> scArrayEndString = MakeStringSpan("]");
236 static constexpr Span<const char> scCommaString = MakeStringSpan(",");
237 static constexpr Span<const char> scEmptyString = MakeStringSpan("");
238 static constexpr Span<const char> scFalseString = MakeStringSpan("false");
239 static constexpr Span<const char> scNewLineString = MakeStringSpan("\n");
240 static constexpr Span<const char> scNullString = MakeStringSpan("null");
241 static constexpr Span<const char> scObjectBeginString = MakeStringSpan("{");
242 static constexpr Span<const char> scObjectEndString = MakeStringSpan("}");
243 static constexpr Span<const char> scPropertyBeginString =
244 MakeStringSpan("\"");
245 static constexpr Span<const char> scPropertyEndString = MakeStringSpan("\":");
246 static constexpr Span<const char> scQuoteString = MakeStringSpan("\"");
247 static constexpr Span<const char> scSpaceString = MakeStringSpan(" ");
248 static constexpr Span<const char> scTopObjectBeginString =
249 MakeStringSpan("{");
250 static constexpr Span<const char> scTopObjectEndString = MakeStringSpan("}");
251 static constexpr Span<const char> scTrueString = MakeStringSpan("true");
252
253 JSONWriteFunc& mWriter;
254 const UniquePtr<JSONWriteFunc> mMaybeOwnedWriter;
255 Vector<bool, 8> mNeedComma; // do we need a comma at depth N?
256 Vector<bool, 8> mNeedNewlines; // do we need newlines at depth N?
257 size_t mDepth; // the current nesting depth
258
259 void Indent() {
260 for (size_t i = 0; i < mDepth; i++) {
261 mWriter.Write(scSpaceString);
262 }
263 }
264
265 // Adds whatever is necessary (maybe a comma, and then a newline and
266 // whitespace) to separate an item (property or element) from what's come
267 // before.
268 void Separator() {
269 if (mNeedComma[mDepth]) {
270 mWriter.Write(scCommaString);
271 }
272 if (mDepth > 0 && mNeedNewlines[mDepth]) {
273 mWriter.Write(scNewLineString);
274 Indent();
275 } else if (mNeedComma[mDepth] && mNeedNewlines[0]) {
276 mWriter.Write(scSpaceString);
277 }
278 }
279
280 void PropertyNameAndColon(const Span<const char>& aName) {
281 mWriter.Write(scPropertyBeginString);
282 mWriter.Write(EscapedString(aName).SpanRef());
283 mWriter.Write(scPropertyEndString);
284 if (mNeedNewlines[0]) {
285 mWriter.Write(scSpaceString);
286 }
287 }
288
289 void Scalar(const Span<const char>& aMaybePropertyName,
290 const Span<const char>& aStringValue) {
291 Separator();
292 if (!aMaybePropertyName.empty()) {
293 PropertyNameAndColon(aMaybePropertyName);
294 }
295 mWriter.Write(aStringValue);
296 mNeedComma[mDepth] = true;
297 }
298
299 void QuotedScalar(const Span<const char>& aMaybePropertyName,
300 const Span<const char>& aStringValue) {
301 Separator();
302 if (!aMaybePropertyName.empty()) {
303 PropertyNameAndColon(aMaybePropertyName);
304 }
305 mWriter.Write(scQuoteString);
306 mWriter.Write(aStringValue);
307 mWriter.Write(scQuoteString);
308 mNeedComma[mDepth] = true;
309 }
310
311 void NewVectorEntries(bool aNeedNewLines) {
312 // If these tiny allocations OOM we might as well just crash because we
313 // must be in serious memory trouble.
314 MOZ_RELEASE_ASSERT(mNeedComma.resizeUninitialized(mDepth + 1))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mNeedComma.resizeUninitialized(mDepth + 1))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mNeedComma.resizeUninitialized(mDepth + 1)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mNeedComma.resizeUninitialized(mDepth + 1)"
, "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 314); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mNeedComma.resizeUninitialized(mDepth + 1)"
")"); do { *((volatile int*)__null) = 314; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
315 MOZ_RELEASE_ASSERT(mNeedNewlines.resizeUninitialized(mDepth + 1))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mNeedNewlines.resizeUninitialized(mDepth + 1))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mNeedNewlines.resizeUninitialized(mDepth + 1)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("mNeedNewlines.resizeUninitialized(mDepth + 1)"
, "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 315); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mNeedNewlines.resizeUninitialized(mDepth + 1)"
")"); do { *((volatile int*)__null) = 315; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
316 mNeedComma[mDepth] = false;
317 mNeedNewlines[mDepth] = aNeedNewLines;
318 }
319
320 void StartCollection(const Span<const char>& aMaybePropertyName,
321 const Span<const char>& aStartChar,
322 CollectionStyle aStyle = MultiLineStyle) {
323 Separator();
324 if (!aMaybePropertyName.empty()) {
325 PropertyNameAndColon(aMaybePropertyName);
326 }
327 mWriter.Write(aStartChar);
328 mNeedComma[mDepth] = true;
329 mDepth++;
330 NewVectorEntries(mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle);
331 }
332
333 // Adds the whitespace and closing char necessary to end a collection.
334 void EndCollection(const Span<const char>& aEndChar) {
335 MOZ_ASSERT(mDepth > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDepth > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDepth > 0))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mDepth > 0",
"/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 335); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDepth > 0"
")"); do { *((volatile int*)__null) = 335; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
336 if (mNeedNewlines[mDepth]) {
337 mWriter.Write(scNewLineString);
338 mDepth--;
339 Indent();
340 } else {
341 mDepth--;
342 }
343 mWriter.Write(aEndChar);
344 }
345
346 public:
347 explicit JSONWriter(JSONWriteFunc& aWriter,
348 CollectionStyle aStyle = MultiLineStyle)
349 : mWriter(aWriter), mNeedComma(), mNeedNewlines(), mDepth(0) {
350 NewVectorEntries(aStyle == MultiLineStyle);
351 }
352
353 explicit JSONWriter(UniquePtr<JSONWriteFunc> aWriter,
354 CollectionStyle aStyle = MultiLineStyle)
355 : mWriter(*aWriter),
356 mMaybeOwnedWriter(std::move(aWriter)),
357 mNeedComma(),
358 mNeedNewlines(),
359 mDepth(0) {
360 MOZ_RELEASE_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mMaybeOwnedWriter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mMaybeOwnedWriter))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mMaybeOwnedWriter"
" (" "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>"
")", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 362); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mMaybeOwnedWriter"
") (" "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>"
")"); do { *((volatile int*)__null) = 362; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
361 mMaybeOwnedWriter,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mMaybeOwnedWriter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mMaybeOwnedWriter))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mMaybeOwnedWriter"
" (" "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>"
")", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 362); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mMaybeOwnedWriter"
") (" "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>"
")"); do { *((volatile int*)__null) = 362; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
362 "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mMaybeOwnedWriter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mMaybeOwnedWriter))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mMaybeOwnedWriter"
" (" "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>"
")", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 362); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mMaybeOwnedWriter"
") (" "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>"
")"); do { *((volatile int*)__null) = 362; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
363 NewVectorEntries(aStyle == MultiLineStyle);
364 }
365
366 // Returns the JSONWriteFunc passed in at creation, for temporary use. The
367 // JSONWriter object still owns the JSONWriteFunc.
368 JSONWriteFunc& WriteFunc() const { return mWriter; }
369
370 // For all the following functions, the "Prints:" comment indicates what the
371 // basic output looks like. However, it doesn't indicate the whitespace and
372 // trailing commas, which are automatically added as required.
373 //
374 // All property names and string properties are escaped as necessary.
375
376 // Prints: {
377 void Start(CollectionStyle aStyle = MultiLineStyle) {
378 StartCollection(scEmptyString, scTopObjectBeginString, aStyle);
379 }
380
381 // Prints: } and final newline.
382 void End() {
383 EndCollection(scTopObjectEndString);
384 if (mNeedNewlines[mDepth]) {
385 mWriter.Write(scNewLineString);
386 }
387 }
388
389 // Prints: "<aName>": null
390 void NullProperty(const Span<const char>& aName) {
391 Scalar(aName, scNullString);
392 }
393
394 template <size_t N>
395 void NullProperty(const char (&aName)[N]) {
396 // Keep null terminator from literal strings, will be removed by
397 // EscapedString. This way C buffer arrays can be used as well.
398 NullProperty(Span<const char>(aName, N));
399 }
400
401 // Prints: null
402 void NullElement() { NullProperty(scEmptyString); }
403
404 // Prints: "<aName>": <aBool>
405 void BoolProperty(const Span<const char>& aName, bool aBool) {
406 Scalar(aName, aBool ? scTrueString : scFalseString);
407 }
408
409 template <size_t N>
410 void BoolProperty(const char (&aName)[N], bool aBool) {
411 // Keep null terminator from literal strings, will be removed by
412 // EscapedString. This way C buffer arrays can be used as well.
413 BoolProperty(Span<const char>(aName, N), aBool);
414 }
415
416 // Prints: <aBool>
417 void BoolElement(bool aBool) { BoolProperty(scEmptyString, aBool); }
418
419 // Prints: "<aName>": <aInt>
420 void IntProperty(const Span<const char>& aName, int64_t aInt) {
421 char buf[64];
422 int len = SprintfLiteral(buf, "%" PRId64"l" "d", aInt);
423 MOZ_RELEASE_ASSERT(len > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(len > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(len > 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("len > 0", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/JSONWriter.h"
, 423); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "len > 0"
")"); do { *((volatile int*)__null) = 423; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
424 Scalar(aName, Span<const char>(buf, size_t(len)));
425 }
426
427 template <size_t N>
428 void IntProperty(const char (&aName)[N], int64_t aInt) {
429 // Keep null terminator from literal strings, will be removed by
430 // EscapedString. This way C buffer arrays can be used as well.
431 IntProperty(Span<const char>(aName, N), aInt);
432 }
433
434 // Prints: <aInt>
435 void IntElement(int64_t aInt) { IntProperty(scEmptyString, aInt); }
436
437 // Prints: "<aName>": <aDouble>
438 void DoubleProperty(const Span<const char>& aName, double aDouble) {
439 static const size_t buflen = 64;
440 char buf[buflen];
441 const double_conversion::DoubleToStringConverter& converter =
442 double_conversion::DoubleToStringConverter::EcmaScriptConverter();
443 double_conversion::StringBuilder builder(buf, buflen);
444 converter.ToShortest(aDouble, &builder);
445 // TODO: The builder should know the length?!
446 Scalar(aName, MakeStringSpan(builder.Finalize()));
447 }
448
449 template <size_t N>
450 void DoubleProperty(const char (&aName)[N], double aDouble) {
451 // Keep null terminator from literal strings, will be removed by
452 // EscapedString. This way C buffer arrays can be used as well.
453 DoubleProperty(Span<const char>(aName, N), aDouble);
454 }
455
456 // Prints: <aDouble>
457 void DoubleElement(double aDouble) { DoubleProperty(scEmptyString, aDouble); }
458
459 // Prints: "<aName>": "<aStr>"
460 void StringProperty(const Span<const char>& aName,
461 const Span<const char>& aStr) {
462 QuotedScalar(aName, EscapedString(aStr).SpanRef());
2
Calling implicit destructor for 'EscapedString'
3
Calling '~UniquePtr'
463 }
464
465 template <size_t NN>
466 void StringProperty(const char (&aName)[NN], const Span<const char>& aStr) {
467 // Keep null terminator from literal strings, will be removed by
468 // EscapedString. This way C buffer arrays can be used as well.
469 StringProperty(Span<const char>(aName, NN), aStr);
470 }
471
472 template <size_t SN>
473 void StringProperty(const Span<const char>& aName, const char (&aStr)[SN]) {
474 // Keep null terminator from literal strings, will be removed by
475 // EscapedString. This way C buffer arrays can be used as well.
476 StringProperty(aName, Span<const char>(aStr, SN));
477 }
478
479 template <size_t NN, size_t SN>
480 void StringProperty(const char (&aName)[NN], const char (&aStr)[SN]) {
481 // Keep null terminators from literal strings, will be removed by
482 // EscapedString. This way C buffer arrays can be used as well.
483 StringProperty(Span<const char>(aName, NN), Span<const char>(aStr, SN));
484 }
485
486 // Prints: "<aStr>"
487 void StringElement(const Span<const char>& aStr) {
488 StringProperty(scEmptyString, aStr);
489 }
490
491 template <size_t N>
492 void StringElement(const char (&aName)[N]) {
493 // Keep null terminator from literal strings, will be removed by
494 // EscapedString. This way C buffer arrays can be used as well.
495 StringElement(Span<const char>(aName, N));
496 }
497
498 // Prints: "<aName>": [
499 void StartArrayProperty(const Span<const char>& aName,
500 CollectionStyle aStyle = MultiLineStyle) {
501 StartCollection(aName, scArrayBeginString, aStyle);
502 }
503
504 template <size_t N>
505 void StartArrayProperty(const char (&aName)[N],
506 CollectionStyle aStyle = MultiLineStyle) {
507 // Keep null terminator from literal strings, will be removed by
508 // EscapedString. This way C buffer arrays can be used as well.
509 StartArrayProperty(Span<const char>(aName, N), aStyle);
510 }
511
512 // Prints: [
513 void StartArrayElement(CollectionStyle aStyle = MultiLineStyle) {
514 StartArrayProperty(scEmptyString, aStyle);
515 }
516
517 // Prints: ]
518 void EndArray() { EndCollection(scArrayEndString); }
519
520 // Prints: "<aName>": {
521 void StartObjectProperty(const Span<const char>& aName,
522 CollectionStyle aStyle = MultiLineStyle) {
523 StartCollection(aName, scObjectBeginString, aStyle);
524 }
525
526 template <size_t N>
527 void StartObjectProperty(const char (&aName)[N],
528 CollectionStyle aStyle = MultiLineStyle) {
529 // Keep null terminator from literal strings, will be removed by
530 // EscapedString. This way C buffer arrays can be used as well.
531 StartObjectProperty(Span<const char>(aName, N), aStyle);
532 }
533
534 // Prints: {
535 void StartObjectElement(CollectionStyle aStyle = MultiLineStyle) {
536 StartObjectProperty(scEmptyString, aStyle);
537 }
538
539 // Prints: }
540 void EndObject() { EndCollection(scObjectEndString); }
541};
542
543} // namespace mozilla
544
545#endif /* mozilla_JSONWriter_h */

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

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/* Smart pointer managing sole ownership of a resource. */
8
9#ifndef mozilla_UniquePtr_h
10#define mozilla_UniquePtr_h
11
12#include <memory>
13#include <type_traits>
14#include <utility>
15
16#include "mozilla/Assertions.h"
17#include "mozilla/Attributes.h"
18#include "mozilla/CompactPair.h"
19#include "mozilla/Compiler.h"
20
21namespace mozilla {
22
23template <typename T>
24class DefaultDelete;
25template <typename T, class D = DefaultDelete<T>>
26class UniquePtr;
27
28} // namespace mozilla
29
30namespace mozilla {
31
32namespace detail {
33
34struct HasPointerTypeHelper {
35 template <class U>
36 static double Test(...);
37 template <class U>
38 static char Test(typename U::pointer* = 0);
39};
40
41template <class T>
42class HasPointerType
43 : public std::integral_constant<bool, sizeof(HasPointerTypeHelper::Test<T>(
44 0)) == 1> {};
45
46template <class T, class D, bool = HasPointerType<D>::value>
47struct PointerTypeImpl {
48 typedef typename D::pointer Type;
49};
50
51template <class T, class D>
52struct PointerTypeImpl<T, D, false> {
53 typedef T* Type;
54};
55
56template <class T, class D>
57struct PointerType {
58 typedef typename PointerTypeImpl<T, std::remove_reference_t<D>>::Type Type;
59};
60
61} // namespace detail
62
63/**
64 * UniquePtr is a smart pointer that wholly owns a resource. Ownership may be
65 * transferred out of a UniquePtr through explicit action, but otherwise the
66 * resource is destroyed when the UniquePtr is destroyed.
67 *
68 * UniquePtr is similar to C++98's std::auto_ptr, but it improves upon auto_ptr
69 * in one crucial way: it's impossible to copy a UniquePtr. Copying an auto_ptr
70 * obviously *can't* copy ownership of its singly-owned resource. So what
71 * happens if you try to copy one? Bizarrely, ownership is implicitly
72 * *transferred*, preserving single ownership but breaking code that assumes a
73 * copy of an object is identical to the original. (This is why auto_ptr is
74 * prohibited in STL containers.)
75 *
76 * UniquePtr solves this problem by being *movable* rather than copyable.
77 * Instead of passing a |UniquePtr u| directly to the constructor or assignment
78 * operator, you pass |Move(u)|. In doing so you indicate that you're *moving*
79 * ownership out of |u|, into the target of the construction/assignment. After
80 * the transfer completes, |u| contains |nullptr| and may be safely destroyed.
81 * This preserves single ownership but also allows UniquePtr to be moved by
82 * algorithms that have been made move-safe. (Note: if |u| is instead a
83 * temporary expression, don't use |Move()|: just pass the expression, because
84 * it's already move-ready. For more information see Move.h.)
85 *
86 * UniquePtr is also better than std::auto_ptr in that the deletion operation is
87 * customizable. An optional second template parameter specifies a class that
88 * (through its operator()(T*)) implements the desired deletion policy. If no
89 * policy is specified, mozilla::DefaultDelete<T> is used -- which will either
90 * |delete| or |delete[]| the resource, depending whether the resource is an
91 * array. Custom deletion policies ideally should be empty classes (no member
92 * fields, no member fields in base classes, no virtual methods/inheritance),
93 * because then UniquePtr can be just as efficient as a raw pointer.
94 *
95 * Use of UniquePtr proceeds like so:
96 *
97 * UniquePtr<int> g1; // initializes to nullptr
98 * g1.reset(new int); // switch resources using reset()
99 * g1 = nullptr; // clears g1, deletes the int
100 *
101 * UniquePtr<int> g2(new int); // owns that int
102 * int* p = g2.release(); // g2 leaks its int -- still requires deletion
103 * delete p; // now freed
104 *
105 * struct S { int x; S(int x) : x(x) {} };
106 * UniquePtr<S> g3, g4(new S(5));
107 * g3 = std::move(g4); // g3 owns the S, g4 cleared
108 * S* p = g3.get(); // g3 still owns |p|
109 * assert(g3->x == 5); // operator-> works (if .get() != nullptr)
110 * assert((*g3).x == 5); // also operator* (again, if not cleared)
111 * std::swap(g3, g4); // g4 now owns the S, g3 cleared
112 * g3.swap(g4); // g3 now owns the S, g4 cleared
113 * UniquePtr<S> g5(std::move(g3)); // g5 owns the S, g3 cleared
114 * g5.reset(); // deletes the S, g5 cleared
115 *
116 * struct FreePolicy { void operator()(void* p) { free(p); } };
117 * UniquePtr<int, FreePolicy> g6(static_cast<int*>(malloc(sizeof(int))));
118 * int* ptr = g6.get();
119 * g6 = nullptr; // calls free(ptr)
120 *
121 * Now, carefully note a few things you *can't* do:
122 *
123 * UniquePtr<int> b1;
124 * b1 = new int; // BAD: can only assign another UniquePtr
125 * int* ptr = b1; // BAD: no auto-conversion to pointer, use get()
126 *
127 * UniquePtr<int> b2(b1); // BAD: can't copy a UniquePtr
128 * UniquePtr<int> b3 = b1; // BAD: can't copy-assign a UniquePtr
129 *
130 * (Note that changing a UniquePtr to store a direct |new| expression is
131 * permitted, but usually you should use MakeUnique, defined at the end of this
132 * header.)
133 *
134 * A few miscellaneous notes:
135 *
136 * UniquePtr, when not instantiated for an array type, can be move-constructed
137 * and move-assigned, not only from itself but from "derived" UniquePtr<U, E>
138 * instantiations where U converts to T and E converts to D. If you want to use
139 * this, you're going to have to specify a deletion policy for both UniquePtr
140 * instantations, and T pretty much has to have a virtual destructor. In other
141 * words, this doesn't work:
142 *
143 * struct Base { virtual ~Base() {} };
144 * struct Derived : Base {};
145 *
146 * UniquePtr<Base> b1;
147 * // BAD: DefaultDelete<Base> and DefaultDelete<Derived> don't interconvert
148 * UniquePtr<Derived> d1(std::move(b));
149 *
150 * UniquePtr<Base> b2;
151 * UniquePtr<Derived, DefaultDelete<Base>> d2(std::move(b2)); // okay
152 *
153 * UniquePtr is specialized for array types. Specializing with an array type
154 * creates a smart-pointer version of that array -- not a pointer to such an
155 * array.
156 *
157 * UniquePtr<int[]> arr(new int[5]);
158 * arr[0] = 4;
159 *
160 * What else is different? Deletion of course uses |delete[]|. An operator[]
161 * is provided. Functionality that doesn't make sense for arrays is removed.
162 * The constructors and mutating methods only accept array pointers (not T*, U*
163 * that converts to T*, or UniquePtr<U[]> or UniquePtr<U>) or |nullptr|.
164 *
165 * It's perfectly okay for a function to return a UniquePtr. This transfers
166 * the UniquePtr's sole ownership of the data, to the fresh UniquePtr created
167 * in the calling function, that will then solely own that data. Such functions
168 * can return a local variable UniquePtr, |nullptr|, |UniquePtr(ptr)| where
169 * |ptr| is a |T*|, or a UniquePtr |Move()|'d from elsewhere.
170 *
171 * UniquePtr will commonly be a member of a class, with lifetime equivalent to
172 * that of that class. If you want to expose the related resource, you could
173 * expose a raw pointer via |get()|, but ownership of a raw pointer is
174 * inherently unclear. So it's better to expose a |const UniquePtr&| instead.
175 * This prohibits mutation but still allows use of |get()| when needed (but
176 * operator-> is preferred). Of course, you can only use this smart pointer as
177 * long as the enclosing class instance remains live -- no different than if you
178 * exposed the |get()| raw pointer.
179 *
180 * To pass a UniquePtr-managed resource as a pointer, use a |const UniquePtr&|
181 * argument. To specify an inout parameter (where the method may or may not
182 * take ownership of the resource, or reset it), or to specify an out parameter
183 * (where simply returning a |UniquePtr| isn't possible), use a |UniquePtr&|
184 * argument. To unconditionally transfer ownership of a UniquePtr
185 * into a method, use a |UniquePtr| argument. To conditionally transfer
186 * ownership of a resource into a method, should the method want it, use a
187 * |UniquePtr&&| argument.
188 */
189template <typename T, class D>
190class UniquePtr {
191 public:
192 typedef T ElementType;
193 typedef D DeleterType;
194 typedef typename detail::PointerType<T, DeleterType>::Type Pointer;
195
196 private:
197 mozilla::CompactPair<Pointer, DeleterType> mTuple;
198
199 Pointer& ptr() { return mTuple.first(); }
200 const Pointer& ptr() const { return mTuple.first(); }
201
202 DeleterType& del() { return mTuple.second(); }
203 const DeleterType& del() const { return mTuple.second(); }
204
205 public:
206 /**
207 * Construct a UniquePtr containing |nullptr|.
208 */
209 constexpr UniquePtr() : mTuple(static_cast<Pointer>(nullptr), DeleterType()) {
210 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance");
211 static_assert(!std::is_reference_v<D>, "must provide a deleter instance");
212 }
213
214 /**
215 * Construct a UniquePtr containing |aPtr|.
216 */
217 explicit UniquePtr(Pointer aPtr) : mTuple(aPtr, DeleterType()) {
218 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance");
219 static_assert(!std::is_reference_v<D>, "must provide a deleter instance");
220 }
221
222 UniquePtr(Pointer aPtr,
223 std::conditional_t<std::is_reference_v<D>, D, const D&> aD1)
224 : mTuple(aPtr, aD1) {}
225
226 UniquePtr(Pointer aPtr, std::remove_reference_t<D>&& aD2)
227 : mTuple(aPtr, std::move(aD2)) {
228 static_assert(!std::is_reference_v<D>,
229 "rvalue deleter can't be stored by reference");
230 }
231
232 UniquePtr(UniquePtr&& aOther)
233 : mTuple(aOther.release(),
234 std::forward<DeleterType>(aOther.get_deleter())) {}
235
236 MOZ_IMPLICIT constexpr UniquePtr(decltype(nullptr)) : UniquePtr() {}
237
238 template <typename U, class E>
239 MOZ_IMPLICIT UniquePtr(
240 UniquePtr<U, E>&& aOther,
241 std::enable_if_t<
242 std::is_convertible_v<typename UniquePtr<U, E>::Pointer, Pointer> &&
243 !std::is_array_v<U> &&
244 (std::is_reference_v<D> ? std::is_same_v<D, E>
245 : std::is_convertible_v<E, D>),
246 int>
247 aDummy = 0)
248 : mTuple(aOther.release(), std::forward<E>(aOther.get_deleter())) {}
249
250 ~UniquePtr() { reset(nullptr); }
251
252 UniquePtr& operator=(UniquePtr&& aOther) {
253 reset(aOther.release());
254 get_deleter() = std::forward<DeleterType>(aOther.get_deleter());
255 return *this;
256 }
257
258 template <typename U, typename E>
259 UniquePtr& operator=(UniquePtr<U, E>&& aOther) {
260 static_assert(
261 std::is_convertible_v<typename UniquePtr<U, E>::Pointer, Pointer>,
262 "incompatible UniquePtr pointees");
263 static_assert(!std::is_array_v<U>,
264 "can't assign from UniquePtr holding an array");
265
266 reset(aOther.release());
267 get_deleter() = std::forward<E>(aOther.get_deleter());
268 return *this;
269 }
270
271 UniquePtr& operator=(decltype(nullptr)) {
272 reset(nullptr);
273 return *this;
274 }
275
276 std::add_lvalue_reference_t<T> operator*() const {
277 MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr with *")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(get())>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(get()))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("get()" " (" "dereferencing a UniquePtr containing nullptr with *"
")", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/UniquePtr.h"
, 277); AnnotateMozCrashReason("MOZ_ASSERT" "(" "get()" ") ("
"dereferencing a UniquePtr containing nullptr with *" ")"); do
{ *((volatile int*)__null) = 277; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
278 return *get();
279 }
280 Pointer operator->() const {
281 MOZ_ASSERT(get(), "dereferencing a UniquePtr containing nullptr with ->")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(get())>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(get()))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("get()" " (" "dereferencing a UniquePtr containing nullptr with ->"
")", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/UniquePtr.h"
, 281); AnnotateMozCrashReason("MOZ_ASSERT" "(" "get()" ") ("
"dereferencing a UniquePtr containing nullptr with ->" ")"
); do { *((volatile int*)__null) = 281; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
282 return get();
283 }
284
285 explicit operator bool() const { return get() != nullptr; }
286
287 Pointer get() const { return ptr(); }
288
289 DeleterType& get_deleter() { return del(); }
290 const DeleterType& get_deleter() const { return del(); }
291
292 [[nodiscard]] Pointer release() {
293 Pointer p = ptr();
294 ptr() = nullptr;
295 return p;
296 }
297
298 void reset(Pointer aPtr = Pointer()) {
299 Pointer old = ptr();
300 ptr() = aPtr;
301 if (old != nullptr) {
302 get_deleter()(old);
303 }
304 }
305
306 void swap(UniquePtr& aOther) { mTuple.swap(aOther.mTuple); }
307
308 UniquePtr(const UniquePtr& aOther) = delete; // construct using std::move()!
309 void operator=(const UniquePtr& aOther) =
310 delete; // assign using std::move()!
311};
312
313// In case you didn't read the comment by the main definition (you should!): the
314// UniquePtr<T[]> specialization exists to manage array pointers. It deletes
315// such pointers using delete[], it will reject construction and modification
316// attempts using U* or U[]. Otherwise it works like the normal UniquePtr.
317template <typename T, class D>
318class UniquePtr<T[], D> {
319 public:
320 typedef T* Pointer;
321 typedef T ElementType;
322 typedef D DeleterType;
323
324 private:
325 mozilla::CompactPair<Pointer, DeleterType> mTuple;
326
327 public:
328 /**
329 * Construct a UniquePtr containing nullptr.
330 */
331 constexpr UniquePtr() : mTuple(static_cast<Pointer>(nullptr), DeleterType()) {
332 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance");
333 static_assert(!std::is_reference_v<D>, "must provide a deleter instance");
334 }
335
336 /**
337 * Construct a UniquePtr containing |aPtr|.
338 */
339 explicit UniquePtr(Pointer aPtr) : mTuple(aPtr, DeleterType()) {
340 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance");
341 static_assert(!std::is_reference_v<D>, "must provide a deleter instance");
342 }
343
344 // delete[] knows how to handle *only* an array of a single class type. For
345 // delete[] to work correctly, it must know the size of each element, the
346 // fields and base classes of each element requiring destruction, and so on.
347 // So forbid all overloads which would end up invoking delete[] on a pointer
348 // of the wrong type.
349 template <typename U>
350 UniquePtr(U&& aU,
351 std::enable_if_t<
352 std::is_pointer_v<U> && std::is_convertible_v<U, Pointer>, int>
353 aDummy = 0) = delete;
354
355 UniquePtr(Pointer aPtr,
356 std::conditional_t<std::is_reference_v<D>, D, const D&> aD1)
357 : mTuple(aPtr, aD1) {}
358
359 UniquePtr(Pointer aPtr, std::remove_reference_t<D>&& aD2)
360 : mTuple(aPtr, std::move(aD2)) {
361 static_assert(!std::is_reference_v<D>,
362 "rvalue deleter can't be stored by reference");
363 }
364
365 // Forbidden for the same reasons as stated above.
366 template <typename U, typename V>
367 UniquePtr(U&& aU, V&& aV,
368 std::enable_if_t<
369 std::is_pointer_v<U> && std::is_convertible_v<U, Pointer>, int>
370 aDummy = 0) = delete;
371
372 UniquePtr(UniquePtr&& aOther)
373 : mTuple(aOther.release(),
374 std::forward<DeleterType>(aOther.get_deleter())) {}
375
376 MOZ_IMPLICIT
377 UniquePtr(decltype(nullptr)) : mTuple(nullptr, DeleterType()) {
378 static_assert(!std::is_pointer_v<D>, "must provide a deleter instance");
379 static_assert(!std::is_reference_v<D>, "must provide a deleter instance");
380 }
381
382 ~UniquePtr() { reset(nullptr); }
4
Calling 'UniquePtr::reset'
383
384 UniquePtr& operator=(UniquePtr&& aOther) {
385 reset(aOther.release());
386 get_deleter() = std::forward<DeleterType>(aOther.get_deleter());
387 return *this;
388 }
389
390 UniquePtr& operator=(decltype(nullptr)) {
391 reset();
392 return *this;
393 }
394
395 explicit operator bool() const { return get() != nullptr; }
396
397 T& operator[](decltype(sizeof(int)) aIndex) const { return get()[aIndex]; }
398 Pointer get() const { return mTuple.first(); }
399
400 DeleterType& get_deleter() { return mTuple.second(); }
401 const DeleterType& get_deleter() const { return mTuple.second(); }
402
403 [[nodiscard]] Pointer release() {
404 Pointer p = mTuple.first();
405 mTuple.first() = nullptr;
406 return p;
407 }
408
409 void reset(Pointer aPtr = Pointer()) {
410 Pointer old = mTuple.first();
411 mTuple.first() = aPtr;
412 if (old != nullptr) {
413 mTuple.second()(old);
414 }
415 }
416
417 void reset(decltype(nullptr)) {
418 Pointer old = mTuple.first();
419 mTuple.first() = nullptr;
420 if (old != nullptr) {
5
Assuming the condition is true
6
Taking true branch
421 mTuple.second()(old);
7
Calling 'DefaultDelete::operator()'
422 }
423 }
424
425 template <typename U>
426 void reset(U) = delete;
427
428 void swap(UniquePtr& aOther) { mTuple.swap(aOther.mTuple); }
429
430 UniquePtr(const UniquePtr& aOther) = delete; // construct using std::move()!
431 void operator=(const UniquePtr& aOther) =
432 delete; // assign using std::move()!
433};
434
435/**
436 * A default deletion policy using plain old operator delete.
437 *
438 * Note that this type can be specialized, but authors should beware of the risk
439 * that the specialization may at some point cease to match (either because it
440 * gets moved to a different compilation unit or the signature changes). If the
441 * non-specialized (|delete|-based) version compiles for that type but does the
442 * wrong thing, bad things could happen.
443 *
444 * This is a non-issue for types which are always incomplete (i.e. opaque handle
445 * types), since |delete|-ing such a type will always trigger a compilation
446 * error.
447 */
448template <typename T>
449class DefaultDelete {
450 public:
451 constexpr DefaultDelete() = default;
452
453 template <typename U>
454 MOZ_IMPLICIT DefaultDelete(
455 const DefaultDelete<U>& aOther,
456 std::enable_if_t<std::is_convertible_v<U*, T*>, int> aDummy = 0) {}
457
458 void operator()(T* aPtr) const {
459 static_assert(sizeof(T) > 0, "T must be complete");
460 delete aPtr;
461 }
462};
463
464/** A default deletion policy using operator delete[]. */
465template <typename T>
466class DefaultDelete<T[]> {
467 public:
468 constexpr DefaultDelete() = default;
469
470 void operator()(T* aPtr) const {
471 static_assert(sizeof(T) > 0, "T must be complete");
472 delete[] aPtr;
8
Memory is released
9
Calling 'operator delete[]'
473 }
474
475 template <typename U>
476 void operator()(U* aPtr) const = delete;
477};
478
479template <typename T, class D, typename U, class E>
480bool operator==(const UniquePtr<T, D>& aX, const UniquePtr<U, E>& aY) {
481 return aX.get() == aY.get();
482}
483
484template <typename T, class D, typename U, class E>
485bool operator!=(const UniquePtr<T, D>& aX, const UniquePtr<U, E>& aY) {
486 return aX.get() != aY.get();
487}
488
489template <typename T, class D>
490bool operator==(const UniquePtr<T, D>& aX, const T* aY) {
491 return aX.get() == aY;
492}
493
494template <typename T, class D>
495bool operator==(const T* aY, const UniquePtr<T, D>& aX) {
496 return aY == aX.get();
497}
498
499template <typename T, class D>
500bool operator!=(const UniquePtr<T, D>& aX, const T* aY) {
501 return aX.get() != aY;
502}
503
504template <typename T, class D>
505bool operator!=(const T* aY, const UniquePtr<T, D>& aX) {
506 return aY != aX.get();
507}
508
509template <typename T, class D>
510bool operator==(const UniquePtr<T, D>& aX, decltype(nullptr)) {
511 return !aX;
512}
513
514template <typename T, class D>
515bool operator==(decltype(nullptr), const UniquePtr<T, D>& aX) {
516 return !aX;
517}
518
519template <typename T, class D>
520bool operator!=(const UniquePtr<T, D>& aX, decltype(nullptr)) {
521 return bool(aX);
522}
523
524template <typename T, class D>
525bool operator!=(decltype(nullptr), const UniquePtr<T, D>& aX) {
526 return bool(aX);
527}
528
529// No operator<, operator>, operator<=, operator>= for now because simplicity.
530
531namespace detail {
532
533template <typename T>
534struct UniqueSelector {
535 typedef UniquePtr<T> SingleObject;
536};
537
538template <typename T>
539struct UniqueSelector<T[]> {
540 typedef UniquePtr<T[]> UnknownBound;
541};
542
543template <typename T, decltype(sizeof(int)) N>
544struct UniqueSelector<T[N]> {
545 typedef UniquePtr<T[N]> KnownBound;
546};
547
548} // namespace detail
549
550/**
551 * MakeUnique is a helper function for allocating new'd objects and arrays,
552 * returning a UniquePtr containing the resulting pointer. The semantics of
553 * MakeUnique<Type>(...) are as follows.
554 *
555 * If Type is an array T[n]:
556 * Disallowed, deleted, no overload for you!
557 * If Type is an array T[]:
558 * MakeUnique<T[]>(size_t) is the only valid overload. The pointer returned
559 * is as if by |new T[n]()|, which value-initializes each element. (If T
560 * isn't a class type, this will zero each element. If T is a class type,
561 * then roughly speaking, each element will be constructed using its default
562 * constructor. See C++11 [dcl.init]p7 for the full gory details.)
563 * If Type is non-array T:
564 * The arguments passed to MakeUnique<T>(...) are forwarded into a
565 * |new T(...)| call, initializing the T as would happen if executing
566 * |T(...)|.
567 *
568 * There are various benefits to using MakeUnique instead of |new| expressions.
569 *
570 * First, MakeUnique eliminates use of |new| from code entirely. If objects are
571 * only created through UniquePtr, then (assuming all explicit release() calls
572 * are safe, including transitively, and no type-safety casting funniness)
573 * correctly maintained ownership of the UniquePtr guarantees no leaks are
574 * possible. (This pays off best if a class is only ever created through a
575 * factory method on the class, using a private constructor.)
576 *
577 * Second, initializing a UniquePtr using a |new| expression requires repeating
578 * the name of the new'd type, whereas MakeUnique in concert with the |auto|
579 * keyword names it only once:
580 *
581 * UniquePtr<char> ptr1(new char()); // repetitive
582 * auto ptr2 = MakeUnique<char>(); // shorter
583 *
584 * Of course this assumes the reader understands the operation MakeUnique
585 * performs. In the long run this is probably a reasonable assumption. In the
586 * short run you'll have to use your judgment about what readers can be expected
587 * to know, or to quickly look up.
588 *
589 * Third, a call to MakeUnique can be assigned directly to a UniquePtr. In
590 * contrast you can't assign a pointer into a UniquePtr without using the
591 * cumbersome reset().
592 *
593 * UniquePtr<char> p;
594 * p = new char; // ERROR
595 * p.reset(new char); // works, but fugly
596 * p = MakeUnique<char>(); // preferred
597 *
598 * (And third, although not relevant to Mozilla: MakeUnique is exception-safe.
599 * An exception thrown after |new T| succeeds will leak that memory, unless the
600 * pointer is assigned to an object that will manage its ownership. UniquePtr
601 * ably serves this function.)
602 */
603
604template <typename T, typename... Args>
605typename detail::UniqueSelector<T>::SingleObject MakeUnique(Args&&... aArgs) {
606 return UniquePtr<T>(new T(std::forward<Args>(aArgs)...));
607}
608
609template <typename T>
610typename detail::UniqueSelector<T>::UnknownBound MakeUnique(
611 decltype(sizeof(int)) aN) {
612 using ArrayType = std::remove_extent_t<T>;
613 return UniquePtr<T>(new ArrayType[aN]());
614}
615
616template <typename T, typename... Args>
617typename detail::UniqueSelector<T>::KnownBound MakeUnique(Args&&... aArgs) =
618 delete;
619
620/**
621 * WrapUnique is a helper function to transfer ownership from a raw pointer
622 * into a UniquePtr<T>. It can only be used with a single non-array type.
623 *
624 * It is generally used this way:
625 *
626 * auto p = WrapUnique(new char);
627 *
628 * It can be used when MakeUnique is not usable, for example, when the
629 * constructor you are using is private, or you want to use aggregate
630 * initialization.
631 */
632
633template <typename T>
634typename detail::UniqueSelector<T>::SingleObject WrapUnique(T* aPtr) {
635 return UniquePtr<T>(aPtr);
636}
637
638} // namespace mozilla
639
640namespace std {
641
642template <typename T, class D>
643void swap(mozilla::UniquePtr<T, D>& aX, mozilla::UniquePtr<T, D>& aY) {
644 aX.swap(aY);
645}
646
647} // namespace std
648
649/**
650TempPtrToSetter(UniquePtr<T>*) -> T**-ish
651TempPtrToSetter(std::unique_ptr<T>*) -> T**-ish
652
653Make a temporary class to support assigning to UniquePtr/unique_ptr via passing
654a pointer to the callee.
655
656Often, APIs will be shaped like this trivial example:
657```
658nsresult Foo::NewChildBar(Bar** out) {
659 if (!IsOk()) return NS_ERROR_FAILURE;
660 *out = new Bar(this);
661 return NS_OK;
662}
663```
664
665In order to make this work with unique ptrs, it's often either risky or
666overwrought:
667```
668Bar* bar = nullptr;
669const auto cleanup = MakeScopeExit([&]() {
670 if (bar) {
671 delete bar;
672 }
673});
674if (FAILED(foo->NewChildBar(&bar)) {
675 // handle it
676}
677```
678
679```
680UniquePtr<Bar> bar;
681{
682 Bar* raw = nullptr;
683 const auto res = foo->NewChildBar(&bar);
684 bar.reset(raw);
685 if (FAILED(res) {
686 // handle it
687 }
688}
689```
690TempPtrToSettable is a shorthand for the latter approach, allowing something
691cleaner but also safe:
692
693```
694UniquePtr<Bar> bar;
695if (FAILED(foo->NewChildBar(TempPtrToSetter(&bar))) {
696 // handle it
697}
698```
699*/
700
701namespace mozilla {
702namespace detail {
703
704template <class T, class UniquePtrT>
705class MOZ_TEMPORARY_CLASS TempPtrToSetterT final {
706 private:
707 UniquePtrT* const mDest;
708 T* mNewVal;
709
710 public:
711 explicit TempPtrToSetterT(UniquePtrT* dest)
712 : mDest(dest), mNewVal(mDest->get()) {}
713
714 operator T**() { return &mNewVal; }
715
716 ~TempPtrToSetterT() {
717 if (mDest->get() != mNewVal) {
718 mDest->reset(mNewVal);
719 }
720 }
721};
722
723} // namespace detail
724
725template <class T, class Deleter>
726auto TempPtrToSetter(UniquePtr<T, Deleter>* const p) {
727 return detail::TempPtrToSetterT<T, UniquePtr<T, Deleter>>{p};
728}
729
730template <class T, class Deleter>
731auto TempPtrToSetter(std::unique_ptr<T, Deleter>* const p) {
732 return detail::TempPtrToSetterT<T, std::unique_ptr<T, Deleter>>{p};
733}
734
735} // namespace mozilla
736
737#endif /* mozilla_UniquePtr_h */

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

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#ifndef mozilla_cxxalloc_h
6#define mozilla_cxxalloc_h
7
8/*
9 * We implement the default operators new/delete as part of
10 * libmozalloc, replacing their definitions in libstdc++. The
11 * operator new* definitions in libmozalloc will never return a NULL
12 * pointer.
13 *
14 * Each operator new immediately below returns a pointer to memory
15 * that can be delete'd by any of
16 *
17 * (1) the matching infallible operator delete immediately below
18 * (2) the matching system |operator delete(void*, std::nothrow)|
19 * (3) the matching system |operator delete(void*) noexcept(false)|
20 *
21 * NB: these are declared |noexcept(false)|, though they will never
22 * throw that exception. This declaration is consistent with the rule
23 * that |::operator new() noexcept(false)| will never return NULL.
24 *
25 * NB: mozilla::fallible can be used instead of std::nothrow.
26 */
27
28#ifndef MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline
29# define MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline MFBT_API__attribute__((weak)) __attribute__((visibility("default")))
30#endif
31
32MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new(size_t size) noexcept(false) {
33 return moz_xmalloc(size);
34}
35
36MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new(size_t size,
37 const std::nothrow_t&) noexcept(true) {
38 return malloc_implmalloc(size);
39}
40
41MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new[](size_t size) noexcept(false) {
42 return moz_xmalloc(size);
43}
44
45MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new[](size_t size,
46 const std::nothrow_t&) noexcept(true) {
47 return malloc_implmalloc(size);
48}
49
50MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete(void* ptr) noexcept(true) {
51 return free_implfree(ptr);
52}
53
54MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete(void* ptr,
55 const std::nothrow_t&) noexcept(true) {
56 return free_implfree(ptr);
57}
58
59MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete[](void* ptr) noexcept(true) {
60 return free_implfree(ptr);
10
Attempt to free released memory
61}
62
63MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete[](
64 void* ptr, const std::nothrow_t&) noexcept(true) {
65 return free_implfree(ptr);
66}
67
68#if defined(XP_WIN)
69// We provide the global sized delete overloads unconditionally because the
70// MSVC runtime headers do, despite compiling with /Zc:sizedDealloc-
71MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete(void* ptr,
72 size_t /*size*/) noexcept(true) {
73 return free_implfree(ptr);
74}
75
76MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete[](void* ptr,
77 size_t /*size*/) noexcept(true) {
78 return free_implfree(ptr);
79}
80#endif
81
82#endif /* mozilla_cxxalloc_h */