Bug Summary

File:root/firefox-clang/caps/ExpandedPrincipal.cpp
Warning:line 208, column 12
Value stored to 'rv' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_caps0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/caps -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/caps -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/caps -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/caps -I /root/firefox-clang/docshell/base -I /root/firefox-clang/dom/base -I /root/firefox-clang/js/xpconnect/src -I /root/firefox-clang/netwerk/base -I /root/firefox-clang/netwerk/cookie -I /root/firefox-clang/toolkit/components/jsoncpp/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-27-100320-3286336-1 -x c++ Unified_cpp_caps0.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 "ExpandedPrincipal.h"
8#include "nsIClassInfoImpl.h"
9#include "nsIObjectInputStream.h"
10#include "nsReadableUtils.h"
11#include "mozilla/Base64.h"
12#include "mozilla/extensions/WebExtensionPolicy.h"
13#include "mozilla/JSONWriter.h"
14
15#include "js/JSON.h"
16#include "ExpandedPrincipalJSONHandler.h"
17#include "SubsumedPrincipalJSONHandler.h"
18
19using namespace mozilla;
20
21NS_IMPL_CLASSINFO(ExpandedPrincipal, nullptr, 0, NS_EXPANDEDPRINCIPAL_CID)extern nsresult ExpandedPrincipal_GetInterfacesHelper(nsTArray
<nsIID> & array); static const GenericClassInfo::ClassInfoData
kExpandedPrincipalClassInfoData = { ExpandedPrincipal_GetInterfacesHelper
, nullptr, 0 | nsIClassInfo::SINGLETON_CLASSINFO, {0xe8ee88b0
, 0x5571, 0x4086, {0xa4, 0x5b, 0x39, 0xa7, 0x16, 0x90, 0x6b, 0xdb
}}, }; mozilla::AlignedStorage2<GenericClassInfo> kExpandedPrincipalClassInfoDataPlace
; nsIClassInfo* gExpandedPrincipal_classInfoGlobal = nullptr;
22NS_IMPL_QUERY_INTERFACE_CI(ExpandedPrincipal, nsIPrincipal,static_assert(2 > 0, "Need more arguments to NS_IMPL_QUERY_INTERFACE_CI"
); nsresult ExpandedPrincipal::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 23); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIPrincipal>)) foundInterface = static_cast
<nsIPrincipal*>(this); else if (aIID.Equals(mozilla::detail
::kImplementedIID<std::remove_reference_t<decltype(*this
)>, nsIExpandedPrincipal>)) foundInterface = static_cast
<nsIExpandedPrincipal*>(this); else if (aIID.Equals(mozilla
::detail::kImplementedIID<std::remove_reference_t<decltype
(*this)>, nsISupports>)) foundInterface = static_cast<
nsISupports*>(static_cast<nsIPrincipal*>(this)); else
if (aIID.Equals((nsIClassInfo::kIID))) { if (!gExpandedPrincipal_classInfoGlobal
) gExpandedPrincipal_classInfoGlobal = new (kExpandedPrincipalClassInfoDataPlace
.addr()) GenericClassInfo(&kExpandedPrincipalClassInfoData
); foundInterface = gExpandedPrincipal_classInfoGlobal; } else
foundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 23); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 23); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
23 nsIExpandedPrincipal)static_assert(2 > 0, "Need more arguments to NS_IMPL_QUERY_INTERFACE_CI"
); nsresult ExpandedPrincipal::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 23); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIPrincipal>)) foundInterface = static_cast
<nsIPrincipal*>(this); else if (aIID.Equals(mozilla::detail
::kImplementedIID<std::remove_reference_t<decltype(*this
)>, nsIExpandedPrincipal>)) foundInterface = static_cast
<nsIExpandedPrincipal*>(this); else if (aIID.Equals(mozilla
::detail::kImplementedIID<std::remove_reference_t<decltype
(*this)>, nsISupports>)) foundInterface = static_cast<
nsISupports*>(static_cast<nsIPrincipal*>(this)); else
if (aIID.Equals((nsIClassInfo::kIID))) { if (!gExpandedPrincipal_classInfoGlobal
) gExpandedPrincipal_classInfoGlobal = new (kExpandedPrincipalClassInfoDataPlace
.addr()) GenericClassInfo(&kExpandedPrincipalClassInfoData
); foundInterface = gExpandedPrincipal_classInfoGlobal; } else
foundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 23); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 23); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
24NS_IMPL_CI_INTERFACE_GETTER(ExpandedPrincipal, nsIPrincipal,static_assert(2 > 0, "Need more arguments to NS_IMPL_CI_INTERFACE_GETTER"
); nsresult ExpandedPrincipal_GetInterfacesHelper(nsTArray<
nsIID> & array) { array.Clear(); array.SetCapacity(2);
array.AppendElement((nsIPrincipal::kIID)); array.AppendElement
((nsIExpandedPrincipal::kIID)); return NS_OK; }
25 nsIExpandedPrincipal)static_assert(2 > 0, "Need more arguments to NS_IMPL_CI_INTERFACE_GETTER"
); nsresult ExpandedPrincipal_GetInterfacesHelper(nsTArray<
nsIID> & array) { array.Clear(); array.SetCapacity(2);
array.AppendElement((nsIPrincipal::kIID)); array.AppendElement
((nsIExpandedPrincipal::kIID)); return NS_OK; }
26
27ExpandedPrincipal::ExpandedPrincipal(
28 nsTArray<nsCOMPtr<nsIPrincipal>>&& aPrincipals,
29 const nsACString& aOriginNoSuffix, const OriginAttributes& aAttrs)
30 : BasePrincipal(eExpandedPrincipal, aOriginNoSuffix, aAttrs),
31 mPrincipals(std::move(aPrincipals)) {}
32
33ExpandedPrincipal::~ExpandedPrincipal() = default;
34
35already_AddRefed<ExpandedPrincipal> ExpandedPrincipal::Create(
36 const nsTArray<nsCOMPtr<nsIPrincipal>>& aAllowList,
37 const OriginAttributes& aAttrs) {
38 nsTArray<nsCOMPtr<nsIPrincipal>> principals;
39 for (size_t i = 0; i < aAllowList.Length(); ++i) {
40 principals.AppendElement(aAllowList[i]);
41 }
42
43 nsAutoCString origin;
44 origin.AssignLiteral("[Expanded Principal [");
45 StringJoinAppend(
46 origin, ", "_ns, principals,
47 [](nsACString& dest, const nsCOMPtr<nsIPrincipal>& principal) {
48 nsAutoCString subOrigin;
49 DebugOnly<nsresult> rv = principal->GetOrigin(subOrigin);
50 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 50); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 50); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
51 dest.Append(subOrigin);
52 });
53 origin.AppendLiteral("]]");
54
55 RefPtr<ExpandedPrincipal> ep =
56 new ExpandedPrincipal(std::move(principals), origin, aAttrs);
57 return ep.forget();
58}
59
60NS_IMETHODIMPnsresult
61ExpandedPrincipal::GetDomain(nsIURI** aDomain) {
62 *aDomain = nullptr;
63 return NS_OK;
64}
65
66NS_IMETHODIMPnsresult
67ExpandedPrincipal::SetDomain(nsIURI* aDomain) { return NS_OK; }
68
69bool ExpandedPrincipal::SubsumesInternal(
70 nsIPrincipal* aOther,
71 BasePrincipal::DocumentDomainConsideration aConsideration) {
72 // If aOther is an ExpandedPrincipal too, we break it down into its component
73 // nsIPrincipals, and check subsumes on each one.
74 if (Cast(aOther)->Is<ExpandedPrincipal>()) {
75 auto* expanded = Cast(aOther)->As<ExpandedPrincipal>();
76
77 for (auto& other : expanded->AllowList()) {
78 // Use SubsumesInternal rather than Subsumes here, since OriginAttribute
79 // checks are only done between non-expanded sub-principals, and we don't
80 // need to incur the extra virtual call overhead.
81 if (!SubsumesInternal(other, aConsideration)) {
82 return false;
83 }
84 }
85 return true;
86 }
87
88 // We're dealing with a regular principal. One of our principals must subsume
89 // it.
90 for (uint32_t i = 0; i < mPrincipals.Length(); ++i) {
91 if (Cast(mPrincipals[i])->Subsumes(aOther, aConsideration)) {
92 return true;
93 }
94 }
95
96 return false;
97}
98
99bool ExpandedPrincipal::MayLoadInternal(nsIURI* uri) {
100 for (uint32_t i = 0; i < mPrincipals.Length(); ++i) {
101 if (BasePrincipal::Cast(mPrincipals[i])->MayLoadInternal(uri)) {
102 return true;
103 }
104 }
105
106 return false;
107}
108
109NS_IMETHODIMPnsresult
110ExpandedPrincipal::GetURI(nsIURI** aURI) {
111 *aURI = nullptr;
112 return NS_OK;
113}
114
115const nsTArray<nsCOMPtr<nsIPrincipal>>& ExpandedPrincipal::AllowList() {
116 return mPrincipals;
117}
118
119NS_IMETHODIMPnsresult
120ExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain) {
121 return NS_ERROR_NOT_AVAILABLE;
122}
123
124NS_IMETHODIMPnsresult
125ExpandedPrincipal::GetAddonId(nsAString& aAddonId) {
126 aAddonId.Truncate();
127 return NS_OK;
128};
129
130bool ExpandedPrincipal::AddonHasPermission(const nsAtom* aPerm) {
131 for (size_t i = 0; i < mPrincipals.Length(); ++i) {
132 if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {
133 return true;
134 }
135 }
136 return false;
137}
138
139bool ExpandedPrincipal::AddonAllowsLoad(nsIURI* aURI,
140 bool aExplicit /* = false */) {
141 for (const auto& principal : mPrincipals) {
142 if (Cast(principal)->AddonAllowsLoad(aURI, aExplicit)) {
143 return true;
144 }
145 }
146 return false;
147}
148
149void ExpandedPrincipal::SetCsp(nsIContentSecurityPolicy* aCSP) {
150 AssertIsOnMainThread();
151 mCSP = new nsMainThreadPtrHolder<nsIContentSecurityPolicy>(
152 "ExpandedPrincipal::mCSP", aCSP);
153}
154
155NS_IMETHODIMPnsresult
156ExpandedPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) {
157 AssertIsOnMainThread();
158 NS_IF_ADDREF(*aCsp = mCSP)ns_if_addref(*aCsp = mCSP);
159 return NS_OK;
160}
161
162nsIPrincipal* ExpandedPrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
163 if (aRequestedURI) {
164 // If a given sub-principal subsumes the given URI, use that principal for
165 // inheritance. In general, this only happens with certain CORS modes, loads
166 // with forced principal inheritance, and creation of XML documents from
167 // XMLHttpRequests or fetch requests. For URIs that normally inherit a
168 // principal (such as data: URIs), we fall back to the last principal in the
169 // allowlist.
170 for (const auto& principal : mPrincipals) {
171 if (Cast(principal)->MayLoadInternal(aRequestedURI)) {
172 return principal;
173 }
174 }
175 }
176 return mPrincipals.LastElement();
177}
178
179nsresult ExpandedPrincipal::GetScriptLocation(nsACString& aStr) {
180 aStr.AssignLiteral("[Expanded Principal [");
181 for (size_t i = 0; i < mPrincipals.Length(); ++i) {
182 if (i != 0) {
183 aStr.AppendLiteral(", ");
184 }
185
186 nsAutoCString spec;
187 nsresult rv =
188 nsJSPrincipals::get(mPrincipals.ElementAt(i))->GetScriptLocation(spec);
189 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, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 189); return rv; } } while (false)
;
190
191 aStr.Append(spec);
192 }
193 aStr.AppendLiteral("]]");
194 return NS_OK;
195}
196
197//////////////////////////////////////////
198// Methods implementing nsISerializable //
199//////////////////////////////////////////
200
201// We've had way too many issues with unversioned serializations, so
202// explicitly version this one.
203static const uint32_t kSerializationVersion = 1;
204
205NS_IMETHODIMPnsresult
206ExpandedPrincipal::Deserializer::Read(nsIObjectInputStream* aStream) {
207 uint32_t version;
208 nsresult rv = aStream->Read32(&version);
Value stored to 'rv' during its initialization is never read
209 if (version != kSerializationVersion) {
210 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" " (" "We really need to add handling of the old(?) version here"
")", "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 211);
AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "We really need to add handling of the old(?) version here"
")"); do { MOZ_CrashSequence(__null, 211); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
211 "We really need to add handling of the old(?) version here")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "We really need to add handling of the old(?) version here"
")", "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 211);
AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "We really need to add handling of the old(?) version here"
")"); do { MOZ_CrashSequence(__null, 211); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
212 return NS_ERROR_UNEXPECTED;
213 }
214
215 uint32_t count;
216 rv = aStream->Read32(&count);
217 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
218 return rv;
219 }
220
221 nsTArray<nsCOMPtr<nsIPrincipal>> principals;
222 if (!principals.SetCapacity(count, fallible)) {
223 return NS_ERROR_OUT_OF_MEMORY;
224 }
225
226 for (uint32_t i = 0; i < count; ++i) {
227 nsCOMPtr<nsISupports> read;
228 rv = aStream->ReadObject(true, getter_AddRefs(read));
229 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
230 return rv;
231 }
232
233 nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(read);
234 if (!principal) {
235 return NS_ERROR_UNEXPECTED;
236 }
237
238 principals.AppendElement(std::move(principal));
239 }
240
241 mPrincipal = ExpandedPrincipal::Create(principals, OriginAttributes());
242 return NS_OK;
243}
244
245nsresult ExpandedPrincipal::GetSiteIdentifier(SiteIdentifier& aSite) {
246 // Call GetSiteIdentifier on each of our principals and return a new
247 // ExpandedPrincipal.
248
249 nsTArray<nsCOMPtr<nsIPrincipal>> allowlist;
250 for (const auto& principal : mPrincipals) {
251 SiteIdentifier site;
252 nsresult rv = Cast(principal)->GetSiteIdentifier(site);
253 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, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 253); return rv; } } while (false)
;
254 allowlist.AppendElement(site.GetPrincipal());
255 }
256
257 RefPtr<ExpandedPrincipal> expandedPrincipal =
258 ExpandedPrincipal::Create(allowlist, OriginAttributesRef());
259 MOZ_ASSERT(expandedPrincipal, "ExpandedPrincipal::Create returned nullptr?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(expandedPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(expandedPrincipal))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("expandedPrincipal"
" (" "ExpandedPrincipal::Create returned nullptr?" ")", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 259); AnnotateMozCrashReason("MOZ_ASSERT" "(" "expandedPrincipal"
") (" "ExpandedPrincipal::Create returned nullptr?" ")"); do
{ MOZ_CrashSequence(__null, 259); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
260
261 aSite.Init(expandedPrincipal);
262 return NS_OK;
263}
264
265nsresult ExpandedPrincipal::WriteJSONInnerProperties(JSONWriter& aWriter) {
266 aWriter.StartArrayProperty(JSONEnumKeyString<eSpecs>(),
267 JSONWriter::CollectionStyle::SingleLineStyle);
268
269 for (const auto& principal : mPrincipals) {
270 aWriter.StartObjectElement(JSONWriter::CollectionStyle::SingleLineStyle);
271
272 nsresult rv = BasePrincipal::Cast(principal)->WriteJSONProperties(aWriter);
273 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, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 273); return rv; } } while (false)
;
274
275 aWriter.EndObject();
276 }
277
278 aWriter.EndArray();
279
280 nsAutoCString suffix;
281 OriginAttributesRef().CreateSuffix(suffix);
282 if (suffix.Length() > 0) {
283 WriteJSONProperty<eSuffix>(aWriter, suffix);
284 }
285
286 return NS_OK;
287}
288
289bool ExpandedPrincipalJSONHandler::ProcessSubsumedResult(bool aResult) {
290 if (!aResult) {
291 NS_WARNING("Failed to parse subsumed principal")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to parse subsumed principal"
, nullptr, "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 291
)
;
292 mState = State::Error;
293 return false;
294 }
295 return true;
296}
297
298bool ExpandedPrincipalJSONHandler::startObject() {
299 if (mSubsumedHandler.isSome()) {
300 return ProcessSubsumedResult(mSubsumedHandler->startObject());
301 }
302
303 switch (mState) {
304 case State::Init:
305 mState = State::StartObject;
306 break;
307 case State::StartArray:
308 mState = State::SubsumedPrincipal;
309 [[fallthrough]];
310 case State::SubsumedPrincipal:
311 mSubsumedHandler.emplace();
312
313 return ProcessSubsumedResult(mSubsumedHandler->startObject());
314 default:
315 NS_WARNING("Unexpected object value")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected object value", nullptr
, "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 315)
;
316 mState = State::Error;
317 return false;
318 }
319
320 return true;
321}
322
323bool ExpandedPrincipalJSONHandler::propertyName(const JS::Latin1Char* name,
324 size_t length) {
325 if (mSubsumedHandler.isSome()) {
326 return ProcessSubsumedResult(mSubsumedHandler->propertyName(name, length));
327 }
328
329 switch (mState) {
330 case State::StartObject:
331 case State::AfterPropertyValue: {
332 if (length != 1) {
333 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name length: %zu"
, length) .get(), nullptr, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 335)
334 nsPrintfCString("Unexpected property name length: %zu", length)NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name length: %zu"
, length) .get(), nullptr, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 335)
335 .get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name length: %zu"
, length) .get(), nullptr, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 335)
;
336 mState = State::Error;
337 return false;
338 }
339
340 char key = char(name[0]);
341 switch (key) {
342 case ExpandedPrincipal::SpecsKey:
343 mState = State::SpecsKey;
344 break;
345 case ExpandedPrincipal::SuffixKey:
346 mState = State::SuffixKey;
347 break;
348 default:
349 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name: '%c'"
, key).get(), nullptr, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 350)
350 nsPrintfCString("Unexpected property name: '%c'", key).get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Unexpected property name: '%c'"
, key).get(), nullptr, "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 350)
;
351 mState = State::Error;
352 return false;
353 }
354 break;
355 }
356 default:
357 NS_WARNING("Unexpected property name")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected property name", nullptr
, "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 357)
;
358 mState = State::Error;
359 return false;
360 }
361
362 return true;
363}
364
365bool ExpandedPrincipalJSONHandler::endObject() {
366 if (mSubsumedHandler.isSome()) {
367 if (!ProcessSubsumedResult(mSubsumedHandler->endObject())) {
368 return false;
369 }
370 if (mSubsumedHandler->HasAccepted()) {
371 nsCOMPtr<nsIPrincipal> principal = mSubsumedHandler->mPrincipal.forget();
372 mSubsumedHandler.reset();
373 mAllowList.AppendElement(principal);
374 }
375 return true;
376 }
377
378 switch (mState) {
379 case State::AfterPropertyValue:
380 mPrincipal = ExpandedPrincipal::Create(mAllowList, mAttrs);
381 MOZ_ASSERT(mPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPrincipal))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("mPrincipal", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPrincipal" ")"
); do { MOZ_CrashSequence(__null, 381); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
382
383 mState = State::EndObject;
384 break;
385 default:
386 NS_WARNING("Unexpected end of object")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected end of object", nullptr
, "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 386)
;
387 mState = State::Error;
388 return false;
389 }
390
391 return true;
392}
393
394bool ExpandedPrincipalJSONHandler::startArray() {
395 switch (mState) {
396 case State::SpecsKey:
397 mState = State::StartArray;
398 break;
399 default:
400 NS_WARNING("Unexpected array value")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected array value", nullptr
, "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 400)
;
401 mState = State::Error;
402 return false;
403 }
404
405 return true;
406}
407
408bool ExpandedPrincipalJSONHandler::endArray() {
409 switch (mState) {
410 case State::SubsumedPrincipal: {
411 mState = State::AfterPropertyValue;
412 break;
413 }
414 default:
415 NS_WARNING("Unexpected end of array")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected end of array", nullptr
, "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 415)
;
416 mState = State::Error;
417 return false;
418 }
419
420 return true;
421}
422
423bool ExpandedPrincipalJSONHandler::stringValue(const JS::Latin1Char* str,
424 size_t length) {
425 if (mSubsumedHandler.isSome()) {
426 return ProcessSubsumedResult(mSubsumedHandler->stringValue(str, length));
427 }
428
429 switch (mState) {
430 case State::SpecsKey: {
431 nsDependentCSubstring specs(reinterpret_cast<const char*>(str), length);
432
433 for (const nsACString& each : specs.Split(',')) {
434 nsAutoCString result;
435 nsresult rv = Base64Decode(each, result);
436 MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to decode")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))" " ("
"failed to decode" ")", "/root/firefox-clang/caps/ExpandedPrincipal.cpp"
, 436); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
") (" "failed to decode" ")"); do { MOZ_CrashSequence(__null
, 436); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
437 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
438 mState = State::Error;
439 return false;
440 }
441
442 nsCOMPtr<nsIPrincipal> principal = BasePrincipal::FromJSON(result);
443 if (!principal) {
444 mState = State::Error;
445 return false;
446 }
447 mAllowList.AppendElement(principal);
448 }
449
450 mState = State::AfterPropertyValue;
451 break;
452 }
453 case State::SuffixKey: {
454 nsDependentCSubstring attrs(reinterpret_cast<const char*>(str), length);
455 if (!mAttrs.PopulateFromSuffix(attrs)) {
456 mState = State::Error;
457 return false;
458 }
459
460 mState = State::AfterPropertyValue;
461 break;
462 }
463 default:
464 NS_WARNING("Unexpected string value")NS_DebugBreak(NS_DEBUG_WARNING, "Unexpected string value", nullptr
, "/root/firefox-clang/caps/ExpandedPrincipal.cpp", 464)
;
465 mState = State::Error;
466 return false;
467 }
468
469 return true;
470}
471
472NS_IMETHODIMPnsresult
473ExpandedPrincipal::IsThirdPartyURI(nsIURI* aURI, bool* aRes) {
474 // ExpandedPrincipal for extension content scripts consist of two principals,
475 // the document's principal and the extension's principal.
476 // To make sure that the third-party check behaves like the web page on which
477 // the content script is running, ignore the extension's principal.
478
479 for (const auto& principal : mPrincipals) {
480 if (!Cast(principal)->AddonPolicyCore()) {
481 return Cast(principal)->IsThirdPartyURI(aURI, aRes);
482 }
483 }
484
485 if (mPrincipals.IsEmpty()) {
486 *aRes = true;
487 return NS_OK;
488 }
489
490 return Cast(mPrincipals[0])->IsThirdPartyURI(aURI, aRes);
491}