Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/net/OpaqueResponseUtils.h
Warning:line 190, 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 -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=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/fetch -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/fetch -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/fetch -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/fetch -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/data -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http -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_fetch0.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set sw=2 ts=8 et tw=80 : */
3
4/* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8#ifndef mozilla_net_OpaqueResponseUtils_h
9#define mozilla_net_OpaqueResponseUtils_h
10
11#include "ipc/EnumSerializer.h"
12#include "mozilla/TimeStamp.h"
13#include "nsIContentPolicy.h"
14#include "nsIEncodedChannel.h"
15#include "nsIStreamListener.h"
16#include "nsUnknownDecoder.h"
17#include "nsMimeTypes.h"
18#include "nsIHttpChannel.h"
19
20#include "mozilla/Variant.h"
21#include "mozilla/Logging.h"
22
23#include "nsCOMPtr.h"
24#include "nsString.h"
25#include "nsTArray.h"
26
27class nsIContentSniffer;
28
29namespace mozilla::dom {
30class JSValidatorParent;
31}
32
33namespace mozilla::ipc {
34class Shmem;
35}
36
37namespace mozilla::net {
38
39class HttpBaseChannel;
40class nsHttpResponseHead;
41
42enum class OpaqueResponseBlockedReason : uint32_t {
43 ALLOWED_SAFE_LISTED,
44 ALLOWED_SAFE_LISTED_SPEC_BREAKING,
45 BLOCKED_BLOCKLISTED_NEVER_SNIFFED,
46 BLOCKED_206_AND_BLOCKLISTED,
47 BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN,
48 BLOCKED_SHOULD_SNIFF
49};
50
51enum class OpaqueResponseBlockedTelemetryReason : uint32_t {
52 MIME_NEVER_SNIFFED,
53 RESP_206_BLCLISTED,
54 NOSNIFF_BLC_OR_TEXTP,
55 RESP_206_NO_FIRST,
56 AFTER_SNIFF_MEDIA,
57 AFTER_SNIFF_NOSNIFF,
58 AFTER_SNIFF_STA_CODE,
59 AFTER_SNIFF_CT_FAIL,
60 MEDIA_NOT_INITIAL,
61 MEDIA_INCORRECT_RESP,
62 JS_VALIDATION_FAILED
63};
64
65enum class OpaqueResponse { Block, Allow, SniffCompressed, Sniff };
66
67OpaqueResponseBlockedReason GetOpaqueResponseBlockedReason(
68 const nsACString& aContentType, uint16_t aStatus, bool aNoSniff);
69
70OpaqueResponseBlockedReason GetOpaqueResponseBlockedReason(
71 nsHttpResponseHead& aResponseHead);
72
73// Returns a tuple of (rangeStart, rangeEnd, rangeTotal) from the input range
74// header string if succeed.
75Result<std::tuple<int64_t, int64_t, int64_t>, nsresult>
76ParseContentRangeHeaderString(const nsAutoCString& aRangeStr);
77
78bool IsFirstPartialResponse(nsHttpResponseHead& aResponseHead);
79
80LogModule* GetORBLog();
81
82// Helper class to filter data for opaque responses destined for `Window.fetch`.
83// See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque.
84class OpaqueResponseFilter final : public nsIStreamListener {
85 public:
86 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:
87 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
88 NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream
*aInputStream, uint64_t aOffset, uint32_t aCount) override;
;
89
90 explicit OpaqueResponseFilter(nsIStreamListener* aNext);
91
92 private:
93 virtual ~OpaqueResponseFilter() = default;
94
95 nsCOMPtr<nsIStreamListener> mNext;
96};
97
98class OpaqueResponseBlocker final : public nsIStreamListener {
99 enum class State { Sniffing, Allowed, Blocked };
100
101 public:
102 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:
103 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
104 NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream
*aInputStream, uint64_t aOffset, uint32_t aCount) override;
;
105
106 OpaqueResponseBlocker(nsIStreamListener* aNext, HttpBaseChannel* aChannel,
107 const nsCString& aContentType, bool aNoSniff);
108
109 bool IsSniffing() const;
110 void AllowResponse();
111 void BlockResponse(HttpBaseChannel* aChannel, nsresult aStatus);
112 void FilterResponse();
113
114 nsresult EnsureOpaqueResponseIsAllowedAfterSniff(nsIRequest* aRequest);
115
116 OpaqueResponse EnsureOpaqueResponseIsAllowedAfterJavaScriptValidation(
117 HttpBaseChannel* aChannel, bool aAllow);
118
119 // The four possible results for validation. `JavaScript` and `JSON` are
120 // self-explanatory. `JavaScript` is the only successful result, in the sense
121 // that it will allow the opaque response, whereas `JSON` will block. `Other`
122 // is the case where validation fails, because the response is neither
123 // `JavaScript` nor `JSON`, but the framework itself works as intended.
124 // `Failure` implies that something has gone wrong, such as allocation, etc.
125 enum class ValidatorResult : uint32_t { JavaScript, JSON, Other, Failure };
126
127 private:
128 virtual ~OpaqueResponseBlocker() = default;
129
130 nsresult ValidateJavaScript(HttpBaseChannel* aChannel, nsIURI* aURI,
131 nsILoadInfo* aLoadInfo);
132
133 void ResolveAndProcessData(HttpBaseChannel* aChannel, bool aAllowed,
134 Maybe<ipc::Shmem>& aSharedData);
135
136 void MaybeRunOnStopRequest(HttpBaseChannel* aChannel);
137
138 nsCOMPtr<nsIStreamListener> mNext;
139
140 const nsCString mContentType;
141 const bool mNoSniff;
142 bool mShouldFilter = false;
143
144 State mState = State::Sniffing;
145 nsresult mStatus = NS_OK;
146
147 TimeStamp mStartOfJavaScriptValidation;
148
149 RefPtr<dom::JSValidatorParent> mJSValidator;
150
151 Maybe<nsresult> mPendingOnStopRequestStatus{Nothing()};
152};
153
154class nsCompressedAudioVideoImageDetector : public nsUnknownDecoder {
155 const std::function<void(void*, const uint8_t*, uint32_t)> mCallback;
156
157 public:
158 nsCompressedAudioVideoImageDetector(
159 nsIStreamListener* aListener,
160 std::function<void(void*, const uint8_t*, uint32_t)>&& aCallback)
161 : nsUnknownDecoder(aListener), mCallback(aCallback) {}
162
163 protected:
164 virtual void DetermineContentType(nsIRequest* aRequest) override {
165 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
166 if (!httpChannel) {
167 return;
168 }
169
170 const char* testData = mBuffer;
171 uint32_t testDataLen = mBufferLen;
172 // Check if data are compressed.
173 nsAutoCString decodedData;
174
175 // ConvertEncodedData is always called only on a single thread for each
176 // instance of an object.
177 nsresult rv = ConvertEncodedData(aRequest, mBuffer, mBufferLen);
178 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
179 MutexAutoLock lock(mMutex);
180 decodedData = mDecodedData;
181 }
182 if (!decodedData.IsEmpty()) {
183 testData = decodedData.get();
184 testDataLen = std::min<uint32_t>(decodedData.Length(), 512u);
185 }
186
187 mCallback(httpChannel, (const uint8_t*)testData, testDataLen);
188
189 nsAutoCString contentType;
190 rv = httpChannel->GetContentType(contentType);
Value stored to 'rv' is never read
191
192 MutexAutoLock lock(mMutex);
193 if (!contentType.IsEmpty()) {
194 mContentType = contentType;
195 } else {
196 mContentType = UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type";
197 }
198
199 nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(httpChannel);
200 if (encodedChannel) {
201 encodedChannel->SetHasContentDecompressed(true);
202 }
203 }
204};
205} // namespace mozilla::net
206
207namespace IPC {
208template <>
209struct ParamTraits<mozilla::net::OpaqueResponseBlocker::ValidatorResult>
210 : public ContiguousEnumSerializerInclusive<
211 mozilla::net::OpaqueResponseBlocker::ValidatorResult,
212 mozilla::net::OpaqueResponseBlocker::ValidatorResult::JavaScript,
213 mozilla::net::OpaqueResponseBlocker::ValidatorResult::Failure> {};
214} // namespace IPC
215
216#endif // mozilla_net_OpaqueResponseUtils_h