Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp
Warning:line 166, 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_dom_reporting0.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/dom/reporting -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/reporting -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/dom/reporting -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/reporting -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++ Unified_cpp_dom_reporting0.cpp
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "mozilla/JSONStringWriteFuncs.h"
8#include "mozilla/StaticPrefs_dom.h"
9#include "mozilla/dom/EndpointForReportChild.h"
10#include "mozilla/dom/Fetch.h"
11#include "mozilla/dom/Navigator.h"
12#include "mozilla/dom/Promise.h"
13#include "mozilla/dom/ReportBody.h"
14#include "mozilla/dom/ReportDeliver.h"
15#include "mozilla/dom/Request.h"
16#include "mozilla/dom/RequestBinding.h"
17#include "mozilla/dom/Response.h"
18#include "mozilla/dom/RootedDictionary.h"
19#include "mozilla/ipc/BackgroundChild.h"
20#include "mozilla/ipc/PBackgroundChild.h"
21#include "mozilla/ipc/PBackgroundSharedTypes.h"
22#include "nsGlobalWindowInner.h"
23#include "nsIGlobalObject.h"
24#include "nsIXPConnect.h"
25#include "nsNetUtil.h"
26#include "nsStringStream.h"
27
28namespace mozilla::dom {
29
30namespace {
31
32StaticRefPtr<ReportDeliver> gReportDeliver;
33
34class ReportFetchHandler final : public PromiseNativeHandler {
35 public:
36 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
37
38 explicit ReportFetchHandler(
39 const nsTArray<ReportDeliver::ReportData>& aReportData)
40 : mReports(aReportData.Clone()) {}
41
42 void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
43 ErrorResult& aRv) override {
44 if (!gReportDeliver) {
45 return;
46 }
47
48 if (NS_WARN_IF(!aValue.isObject())NS_warn_if_impl(!aValue.isObject(), "!aValue.isObject()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 48)
) {
49 return;
50 }
51
52 JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
53 MOZ_ASSERT(obj)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(obj))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("obj", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 53); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj" ")"); do
{ *((volatile int*)__null) = 53; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
54
55 {
56 Response* response = nullptr;
57 if (NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Response, &obj, response)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(mozilla
::dom::binding_detail::UnwrapObjectWithCrossOriginAsserts<
mozilla::dom::prototypes::id::Response, mozilla::dom::Response_Binding
::NativeType>(&obj, response))), 0))), "NS_FAILED(UNWRAP_OBJECT(Response, &obj, response))"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 57)
) {
58 return;
59 }
60
61 if (response->Status() == 410) {
62 mozilla::ipc::PBackgroundChild* actorChild =
63 mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
64
65 for (const auto& report : mReports) {
66 mozilla::ipc::PrincipalInfo principalInfo;
67 nsresult rv =
68 PrincipalToPrincipalInfo(report.mPrincipal, &principalInfo);
69 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/dom/reporting/ReportDeliver.cpp"
, 69)
) {
70 continue;
71 }
72
73 actorChild->SendRemoveEndpoint(report.mGroupName, report.mEndpointURL,
74 principalInfo);
75 }
76 }
77 }
78 }
79
80 void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
81 ErrorResult& aRv) override {
82 if (gReportDeliver) {
83 for (auto& report : mReports) {
84 ++report.mFailures;
85 gReportDeliver->AppendReportData(report);
86 }
87 }
88 }
89
90 private:
91 ~ReportFetchHandler() = default;
92
93 nsTArray<ReportDeliver::ReportData> mReports;
94};
95
96NS_IMPL_ISUPPORTS0(ReportFetchHandler)MozExternalRefCountType ReportFetchHandler::AddRef(void) { static_assert
(!std::is_destructible_v<ReportFetchHandler>, "Reference-counted class "
"ReportFetchHandler" " 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/dom/reporting/ReportDeliver.cpp"
, 96); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
96; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("ReportFetchHandler" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("ReportFetchHandler" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"ReportFetchHandler\" != nullptr" " (" "Must specify a name"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 96); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ReportFetchHandler\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 96; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("ReportFetchHandler" " not thread-safe"); nsrefcnt count = ++
mRefCnt; NS_LogAddRef((this), (count), ("ReportFetchHandler")
, (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
ReportFetchHandler::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/dom/reporting/ReportDeliver.cpp"
, 96); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 96
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("ReportFetchHandler" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("ReportFetchHandler" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"ReportFetchHandler\" != nullptr" " (" "Must specify a name"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 96); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ReportFetchHandler\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 96; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("ReportFetchHandler" " not thread-safe"); const char* const nametmp
= "ReportFetchHandler"; nsrefcnt count = --mRefCnt; NS_LogRelease
((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete
(this); return 0; } return count; } nsresult ReportFetchHandler
::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/dom/reporting/ReportDeliver.cpp"
, 96); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<ReportFetchHandler, nsISupports>, int32_t
( reinterpret_cast<char*>(static_cast<nsISupports*>
((ReportFetchHandler*)0x1000)) - reinterpret_cast<char*>
((ReportFetchHandler*)0x1000))}, { nullptr, 0 } } ; static_assert
((sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
97
98class ReportJSONWriter final : public JSONWriter {
99 public:
100 explicit ReportJSONWriter(JSONStringWriteFunc<nsAutoCString>& aOutput)
101 : JSONWriter(aOutput) {}
102
103 void JSONProperty(const Span<const char>& aProperty,
104 const Span<const char>& aJSON) {
105 Separator();
106 PropertyNameAndColon(aProperty);
107 mWriter.Write(aJSON);
108 }
109};
110
111void SendReports(nsTArray<ReportDeliver::ReportData>& aReports,
112 const nsCString& aEndPointUrl, nsIPrincipal* aPrincipal) {
113 if (NS_WARN_IF(aReports.IsEmpty())NS_warn_if_impl(aReports.IsEmpty(), "aReports.IsEmpty()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 113)
) {
114 return;
115 }
116
117 nsIXPConnect* xpc = nsContentUtils::XPConnect();
118 MOZ_ASSERT(xpc, "This should never be null!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(xpc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(xpc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("xpc" " (" "This should never be null!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 118); AnnotateMozCrashReason("MOZ_ASSERT" "(" "xpc" ") (" "This should never be null!"
")"); do { *((volatile int*)__null) = 118; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
119
120 nsCOMPtr<nsIGlobalObject> globalObject;
121 {
122 AutoJSAPI jsapi;
123 jsapi.Init();
124
125 JSContext* cx = jsapi.cx();
126 JS::Rooted<JSObject*> sandbox(cx);
127 nsresult rv = xpc->CreateSandbox(cx, aPrincipal, sandbox.address());
128 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/dom/reporting/ReportDeliver.cpp"
, 128)
) {
129 return;
130 }
131
132 // The JSContext is not in a realm, so CreateSandbox returned an unwrapped
133 // global.
134 MOZ_ASSERT(JS_IsGlobalObject(sandbox))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(JS_IsGlobalObject(sandbox))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(JS_IsGlobalObject(sandbox)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("JS_IsGlobalObject(sandbox)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 134); AnnotateMozCrashReason("MOZ_ASSERT" "(" "JS_IsGlobalObject(sandbox)"
")"); do { *((volatile int*)__null) = 134; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
135
136 globalObject = xpc::NativeGlobal(sandbox);
137 }
138
139 if (NS_WARN_IF(!globalObject)NS_warn_if_impl(!globalObject, "!globalObject", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 139)
) {
140 return;
141 }
142
143 // The body
144 JSONStringWriteFunc<nsAutoCString> body;
145 ReportJSONWriter w(body);
146
147 w.StartArrayElement();
148 for (const auto& report : aReports) {
149 MOZ_ASSERT(report.mPrincipal == aPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(report.mPrincipal == aPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(report.mPrincipal == aPrincipal
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"report.mPrincipal == aPrincipal", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 149); AnnotateMozCrashReason("MOZ_ASSERT" "(" "report.mPrincipal == aPrincipal"
")"); do { *((volatile int*)__null) = 149; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
150 MOZ_ASSERT(report.mEndpointURL == aEndPointUrl)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(report.mEndpointURL == aEndPointUrl)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(report.mEndpointURL == aEndPointUrl
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"report.mEndpointURL == aEndPointUrl", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "report.mEndpointURL == aEndPointUrl"
")"); do { *((volatile int*)__null) = 150; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
151 w.StartObjectElement();
152 w.IntProperty("age",
153 (TimeStamp::Now() - report.mCreationTime).ToMilliseconds());
154 w.StringProperty("type", NS_ConvertUTF16toUTF8(report.mType));
155 w.StringProperty("url", NS_ConvertUTF16toUTF8(report.mURL));
156 w.StringProperty("user_agent", NS_ConvertUTF16toUTF8(report.mUserAgent));
157 w.JSONProperty(MakeStringSpan("body"),
158 Span<const char>(report.mReportBodyJSON.Data(),
159 report.mReportBodyJSON.Length()));
160 w.EndObject();
161 }
162 w.EndArray();
163
164 // The body as stream
165 nsCOMPtr<nsIInputStream> streamBody;
166 nsresult rv =
Value stored to 'rv' during its initialization is never read
167 NS_NewCStringInputStream(getter_AddRefs(streamBody), body.StringCRef());
168
169 // Headers
170 IgnoredErrorResult error;
171 RefPtr<InternalHeaders> internalHeaders =
172 new InternalHeaders(HeadersGuardEnum::Request);
173 internalHeaders->Set("Content-Type"_ns, "application/reports+json"_ns, error);
174 if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 174)
) {
175 return;
176 }
177
178 // URL and fragments
179 nsCOMPtr<nsIURI> uri;
180 rv = NS_NewURI(getter_AddRefs(uri), aEndPointUrl);
181 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/dom/reporting/ReportDeliver.cpp"
, 181)
) {
182 return;
183 }
184
185 nsCOMPtr<nsIURI> uriClone;
186 rv = NS_GetURIWithoutRef(uri, getter_AddRefs(uriClone));
187 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/dom/reporting/ReportDeliver.cpp"
, 187)
) {
188 return;
189 }
190
191 nsAutoCString uriSpec;
192 rv = uriClone->GetSpec(uriSpec);
193 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/dom/reporting/ReportDeliver.cpp"
, 193)
) {
194 return;
195 }
196
197 nsAutoCString uriFragment;
198 rv = uri->GetRef(uriFragment);
199 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/dom/reporting/ReportDeliver.cpp"
, 199)
) {
200 return;
201 }
202
203 auto internalRequest = MakeSafeRefPtr<InternalRequest>(uriSpec, uriFragment);
204
205 internalRequest->SetMethod("POST"_ns);
206 internalRequest->SetBody(streamBody, body.StringCRef().Length());
207 internalRequest->SetHeaders(internalHeaders);
208 internalRequest->SetSkipServiceWorker();
209 // TODO: internalRequest->SetContentPolicyType(TYPE_REPORT);
210 internalRequest->SetMode(RequestMode::Cors);
211 internalRequest->SetCredentialsMode(RequestCredentials::Include);
212
213 RefPtr<Request> request =
214 new Request(globalObject, std::move(internalRequest), nullptr);
215
216 RequestOrUTF8String fetchInput;
217 fetchInput.SetAsRequest() = request;
218
219 RootedDictionary<RequestInit> requestInit(RootingCx());
220 RefPtr<Promise> promise = FetchRequest(globalObject, fetchInput, requestInit,
221 CallerType::NonSystem, error);
222 if (error.Failed()) {
223 for (auto& report : aReports) {
224 ++report.mFailures;
225 if (gReportDeliver) {
226 gReportDeliver->AppendReportData(report);
227 }
228 }
229 return;
230 }
231
232 RefPtr<ReportFetchHandler> handler = new ReportFetchHandler(aReports);
233 promise->AppendNativeHandler(handler);
234}
235
236} // namespace
237
238/* static */
239void ReportDeliver::Record(nsPIDOMWindowInner* aWindow, const nsAString& aType,
240 const nsAString& aGroupName, const nsAString& aURL,
241 ReportBody* aBody) {
242 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 242); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 242; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
243 MOZ_ASSERT(aWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aWindow", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aWindow" ")"
); do { *((volatile int*)__null) = 243; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
244 MOZ_ASSERT(aBody)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aBody)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(aBody))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("aBody", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 244); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aBody" ")");
do { *((volatile int*)__null) = 244; __attribute__((nomerge)
) ::abort(); } while (false); } } while (false)
;
245
246 JSONStringWriteFunc<nsAutoCString> reportBodyJSON;
247 ReportJSONWriter w(reportBodyJSON);
248
249 w.Start();
250 aBody->ToJSON(w);
251 w.End();
252
253 nsCOMPtr<nsIPrincipal> principal =
254 nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
255 if (NS_WARN_IF(!principal)NS_warn_if_impl(!principal, "!principal", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 255)
) {
256 return;
257 }
258
259 mozilla::ipc::PrincipalInfo principalInfo;
260 nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
261 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/dom/reporting/ReportDeliver.cpp"
, 261)
) {
262 return;
263 }
264
265 mozilla::ipc::PBackgroundChild* actorChild =
266 mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
267
268 PEndpointForReportChild* actor =
269 actorChild->SendPEndpointForReportConstructor(nsString(aGroupName),
270 principalInfo);
271 if (NS_WARN_IF(!actor)NS_warn_if_impl(!actor, "!actor", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 271)
) {
272 return;
273 }
274
275 ReportData data;
276 data.mType = aType;
277 data.mGroupName = aGroupName;
278 data.mURL = aURL;
279 data.mCreationTime = TimeStamp::Now();
280 data.mReportBodyJSON = std::move(reportBodyJSON).StringRRef();
281 data.mPrincipal = principal;
282 data.mFailures = 0;
283
284 Navigator* navigator = aWindow->Navigator();
285 MOZ_ASSERT(navigator)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(navigator)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(navigator))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("navigator", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 285); AnnotateMozCrashReason("MOZ_ASSERT" "(" "navigator" ")"
); do { *((volatile int*)__null) = 285; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
286
287 IgnoredErrorResult error;
288 navigator->GetUserAgent(data.mUserAgent, CallerType::NonSystem, error);
289 if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 289)
) {
290 return;
291 }
292
293 static_cast<EndpointForReportChild*>(actor)->Initialize(data);
294}
295
296/* static */
297void ReportDeliver::Fetch(const ReportData& aReportData) {
298 if (!gReportDeliver) {
299 RefPtr<ReportDeliver> rd = new ReportDeliver();
300
301 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
302 if (NS_WARN_IF(!obs)NS_warn_if_impl(!obs, "!obs", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 302)
) {
303 return;
304 }
305
306 obs->AddObserver(rd, NS_XPCOM_SHUTDOWN_OBSERVER_ID"xpcom-shutdown", false);
307 gReportDeliver = rd;
308 }
309
310 gReportDeliver->AppendReportData(aReportData);
311}
312
313void ReportDeliver::AppendReportData(const ReportData& aReportData) {
314 if (aReportData.mFailures >
315 StaticPrefs::dom_reporting_delivering_maxFailures()) {
316 return;
317 }
318
319 if (NS_WARN_IF(!mReportQueue.AppendElement(aReportData, fallible))NS_warn_if_impl(!mReportQueue.AppendElement(aReportData, fallible
), "!mReportQueue.AppendElement(aReportData, fallible)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 319)
) {
320 return;
321 }
322
323 while (mReportQueue.Length() >
324 StaticPrefs::dom_reporting_delivering_maxReports()) {
325 mReportQueue.RemoveElementAt(0);
326 }
327
328 if (!mTimer) {
329 uint32_t timeout = StaticPrefs::dom_reporting_delivering_timeout() * 1000;
330 nsresult rv = NS_NewTimerWithCallback(getter_AddRefs(mTimer), this, timeout,
331 nsITimer::TYPE_ONE_SHOT);
332 Unused << 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/dom/reporting/ReportDeliver.cpp"
, 332)
;
333 }
334}
335
336NS_IMETHODIMPnsresult
337ReportDeliver::Notify(nsITimer* aTimer) {
338 mTimer = nullptr;
339
340 nsTArray<ReportData> reports = std::move(mReportQueue);
341
342 // group reports by endpoint and nsIPrincipal
343 std::map<std::pair<nsCString, nsCOMPtr<nsIPrincipal>>, nsTArray<ReportData>>
344 reportsByPrincipal;
345 for (ReportData& report : reports) {
346 auto already_seen =
347 reportsByPrincipal.find({report.mEndpointURL, report.mPrincipal});
348 if (already_seen == reportsByPrincipal.end()) {
349 reportsByPrincipal.emplace(
350 std::make_pair(report.mEndpointURL, report.mPrincipal),
351 nsTArray<ReportData>({report}));
352 } else {
353 already_seen->second.AppendElement(report);
354 }
355 }
356
357 for (auto& iter : reportsByPrincipal) {
358 std::pair<nsCString, nsCOMPtr<nsIPrincipal>> key = iter.first;
359 nsTArray<ReportData>& value = iter.second;
360 nsCString url = key.first;
361 nsCOMPtr<nsIPrincipal> principal = key.second;
362 nsAutoCString u(url);
363 SendReports(value, url, principal);
364 }
365
366 return NS_OK;
367}
368
369NS_IMETHODIMPnsresult
370ReportDeliver::GetName(nsACString& aName) {
371 aName.AssignLiteral("ReportDeliver");
372 return NS_OK;
373}
374
375NS_IMETHODIMPnsresult
376ReportDeliver::Observe(nsISupports* aSubject, const char* aTopic,
377 const char16_t* aData) {
378 MOZ_ASSERT(!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!strcmp(aTopic, "xpcom-shutdown"))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!strcmp(aTopic, "xpcom-shutdown"
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!strcmp(aTopic, \"xpcom-shutdown\")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!strcmp(aTopic, \"xpcom-shutdown\")"
")"); do { *((volatile int*)__null) = 378; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
379
380 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
381 if (NS_WARN_IF(!obs)NS_warn_if_impl(!obs, "!obs", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 381)
) {
382 return NS_OK;
383 }
384
385 obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID"xpcom-shutdown");
386
387 if (mTimer) {
388 mTimer->Cancel();
389 mTimer = nullptr;
390 }
391
392 gReportDeliver = nullptr;
393 return NS_OK;
394}
395
396ReportDeliver::ReportDeliver() = default;
397
398ReportDeliver::~ReportDeliver() = default;
399
400NS_INTERFACE_MAP_BEGIN(ReportDeliver)nsresult ReportDeliver::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/dom/reporting/ReportDeliver.cpp"
, 400); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
401 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIObserver*>(this)); else
402 NS_INTERFACE_MAP_ENTRY(nsIObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIObserver>)) foundInterface = static_cast
<nsIObserver*>(this); else
403 NS_INTERFACE_MAP_ENTRY(nsITimerCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITimerCallback>)) foundInterface
= static_cast<nsITimerCallback*>(this); else
404 NS_INTERFACE_MAP_ENTRY(nsINamed)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsINamed>)) foundInterface = static_cast
<nsINamed*>(this); else
405NS_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/dom/reporting/ReportDeliver.cpp"
, 405); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 405; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
406
407NS_IMPL_ADDREF(ReportDeliver)MozExternalRefCountType ReportDeliver::AddRef(void) { static_assert
(!std::is_destructible_v<ReportDeliver>, "Reference-counted class "
"ReportDeliver" " 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/dom/reporting/ReportDeliver.cpp"
, 407); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
407; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("ReportDeliver" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("ReportDeliver" != nullptr))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"ReportDeliver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 407); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ReportDeliver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 407; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("ReportDeliver" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("ReportDeliver"
), (uint32_t)(sizeof(*this))); return count; }
408NS_IMPL_RELEASE(ReportDeliver)MozExternalRefCountType ReportDeliver::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/dom/reporting/ReportDeliver.cpp"
, 408); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 408
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("ReportDeliver" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("ReportDeliver" != nullptr))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"ReportDeliver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/reporting/ReportDeliver.cpp"
, 408); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ReportDeliver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 408; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("ReportDeliver" " not thread-safe"); const char
* const nametmp = "ReportDeliver"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; }
409
410} // namespace mozilla::dom