Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/mozilla/net/OpaqueResponseUtils.h
Warning:line 173, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_dom_fetch0.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/dom/fetch -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/fetch -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/fetch -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/fetch -I /root/firefox-clang/dom/base -I /root/firefox-clang/netwerk/base -I /root/firefox-clang/netwerk/protocol/data -I /root/firefox-clang/netwerk/protocol/http -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/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/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_dom_fetch0.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#ifndef mozilla_net_OpaqueResponseUtils_h
6#define mozilla_net_OpaqueResponseUtils_h
7
8#include "ipc/EnumSerializer.h"
9#include "mozilla/Logging.h"
10#include "mozilla/TimeStamp.h"
11#include "mozilla/glean/NetwerkProtocolHttpMetrics.h"
12#include "nsCOMPtr.h"
13#include "nsIContentPolicy.h"
14#include "nsIEncodedChannel.h"
15#include "nsIHttpChannel.h"
16#include "nsIStreamListener.h"
17#include "nsMimeTypes.h"
18#include "nsString.h"
19#include "nsTArray.h"
20#include "nsUnknownDecoder.h"
21
22class nsIContentSniffer;
23
24namespace mozilla::dom {
25class JSValidatorParent;
26}
27
28namespace mozilla::ipc {
29class Shmem;
30}
31
32namespace mozilla::net {
33
34class HttpBaseChannel;
35class nsHttpResponseHead;
36
37enum class OpaqueResponseBlockedReason : uint32_t {
38 ALLOWED_SAFE_LISTED,
39 ALLOWED_SAFE_LISTED_SPEC_BREAKING,
40 BLOCKED_BLOCKLISTED_NEVER_SNIFFED,
41 BLOCKED_206_AND_BLOCKLISTED,
42 BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN,
43 BLOCKED_SHOULD_SNIFF
44};
45
46using OpaqueResponseBlockedTelemetryReason = glean::orb::BlockReasonLabel;
47
48enum class OpaqueResponse { Block, Allow, SniffCompressed, Sniff };
49
50OpaqueResponseBlockedReason GetOpaqueResponseBlockedReason(
51 const nsACString& aContentType, uint16_t aStatus, bool aNoSniff);
52
53OpaqueResponseBlockedReason GetOpaqueResponseBlockedReason(
54 nsHttpResponseHead& aResponseHead);
55
56// Returns a tuple of (rangeStart, rangeEnd, rangeTotal) from the input range
57// header string if succeed.
58Result<std::tuple<int64_t, int64_t, int64_t>, nsresult>
59ParseContentRangeHeaderString(const nsAutoCString& aRangeStr);
60
61bool IsFirstPartialResponse(nsHttpResponseHead& aResponseHead);
62
63LogModule* GetORBLog();
64
65// Helper class to filter data for opaque responses destined for `Window.fetch`.
66// See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque.
67class OpaqueResponseFilter final : public nsIStreamListener {
68 public:
69 NS_DECL_THREADSAFE_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; nsAutoOwningThread
_mOwningThread; public:
70 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
71 NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream
*aInputStream, uint64_t aOffset, uint32_t aCount) override;
;
72
73 explicit OpaqueResponseFilter(nsIStreamListener* aNext);
74
75 private:
76 virtual ~OpaqueResponseFilter() = default;
77
78 nsCOMPtr<nsIStreamListener> mNext;
79};
80
81class OpaqueResponseBlocker final : public nsIStreamListener {
82 enum class State { Sniffing, Allowed, Blocked };
83
84 public:
85 NS_DECL_THREADSAFE_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; nsAutoOwningThread
_mOwningThread; public:
86 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
87 NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream
*aInputStream, uint64_t aOffset, uint32_t aCount) override;
;
88
89 OpaqueResponseBlocker(nsIStreamListener* aNext, HttpBaseChannel* aChannel,
90 const nsCString& aContentType, bool aNoSniff);
91
92 bool IsSniffing() const;
93 void AllowResponse();
94 void BlockResponse(HttpBaseChannel* aChannel, nsresult aStatus);
95 void FilterResponse();
96
97 nsresult EnsureOpaqueResponseIsAllowedAfterSniff(nsIRequest* aRequest);
98
99 OpaqueResponse EnsureOpaqueResponseIsAllowedAfterJavaScriptValidation(
100 HttpBaseChannel* aChannel, bool aAllow);
101
102 // The four possible results for validation. `JavaScript` and `JSON` are
103 // self-explanatory. `JavaScript` is the only successful result, in the sense
104 // that it will allow the opaque response, whereas `JSON` will block. `Other`
105 // is the case where validation fails, because the response is neither
106 // `JavaScript` nor `JSON`, but the framework itself works as intended.
107 // `Failure` implies that something has gone wrong, such as allocation, etc.
108 enum class ValidatorResult : uint32_t { JavaScript, JSON, Other, Failure };
109
110 private:
111 virtual ~OpaqueResponseBlocker() = default;
112
113 nsresult ValidateJavaScript(HttpBaseChannel* aChannel, nsIURI* aURI,
114 nsILoadInfo* aLoadInfo);
115
116 void ResolveAndProcessData(HttpBaseChannel* aChannel, bool aAllowed,
117 Maybe<mozilla::ipc::Shmem>& aSharedData);
118
119 void MaybeRunOnStopRequest(HttpBaseChannel* aChannel);
120
121 nsCOMPtr<nsIStreamListener> mNext;
122
123 const nsCString mContentType;
124 const bool mNoSniff;
125 bool mShouldFilter = false;
126
127 State mState = State::Sniffing;
128 nsresult mStatus = NS_OK;
129
130 TimeStamp mStartOfJavaScriptValidation;
131
132 RefPtr<dom::JSValidatorParent> mJSValidator;
133
134 Maybe<nsresult> mPendingOnStopRequestStatus{Nothing()};
135};
136
137class nsCompressedAudioVideoImageDetector : public nsUnknownDecoder {
138 const std::function<void(void*, const uint8_t*, uint32_t)> mCallback;
139
140 public:
141 nsCompressedAudioVideoImageDetector(
142 nsIStreamListener* aListener,
143 std::function<void(void*, const uint8_t*, uint32_t)>&& aCallback)
144 : nsUnknownDecoder(aListener), mCallback(aCallback) {}
145
146 protected:
147 virtual void DetermineContentType(nsIRequest* aRequest) override {
148 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
149 if (!httpChannel) {
150 return;
151 }
152
153 const char* testData = mBuffer;
154 uint32_t testDataLen = mBufferLen;
155 // Check if data are compressed.
156 nsAutoCString decodedData;
157
158 // ConvertEncodedData is always called only on a single thread for each
159 // instance of an object.
160 nsresult rv = ConvertEncodedData(aRequest, mBuffer, mBufferLen);
161 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
162 MutexAutoLock lock(mMutex);
163 decodedData = mDecodedData;
164 }
165 if (!decodedData.IsEmpty()) {
166 testData = decodedData.get();
167 testDataLen = std::min<uint32_t>(decodedData.Length(), 512u);
168 }
169
170 mCallback(httpChannel, (const uint8_t*)testData, testDataLen);
171
172 nsAutoCString contentType;
173 rv = httpChannel->GetContentType(contentType);
Value stored to 'rv' is never read
174
175 MutexAutoLock lock(mMutex);
176 if (!contentType.IsEmpty()) {
177 mContentType = contentType;
178 } else {
179 mContentType = UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type";
180 }
181
182 nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(httpChannel);
183 if (encodedChannel) {
184 encodedChannel->SetHasContentDecompressed(true);
185 }
186 }
187};
188} // namespace mozilla::net
189
190namespace IPC {
191template <>
192struct ParamTraits<mozilla::net::OpaqueResponseBlocker::ValidatorResult>
193 : public ContiguousEnumSerializerInclusive<
194 mozilla::net::OpaqueResponseBlocker::ValidatorResult,
195 mozilla::net::OpaqueResponseBlocker::ValidatorResult::JavaScript,
196 mozilla::net::OpaqueResponseBlocker::ValidatorResult::Failure> {};
197} // namespace IPC
198
199#endif // mozilla_net_OpaqueResponseUtils_h