Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/serviceworkers/./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp
Warning:line 1024, column 14
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 -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_dom_serviceworkers2.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/serviceworkers -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/serviceworkers -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/serviceworkers -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/serviceworkers -I /root/firefox-clang/netwerk/base -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_serviceworkers2.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#include "ServiceWorkerScriptCache.h"
6
7#include "ServiceWorkerManager.h"
8#include "js/Array.h" // JS::GetArrayLength
9#include "js/PropertyAndElement.h" // JS_GetElement
10#include "js/Utility.h" // JS::FreePolicy
11#include "mozilla/ScopeExit.h"
12#include "mozilla/StaticPrefs_extensions.h"
13#include "mozilla/TaskQueue.h"
14#include "mozilla/UniquePtr.h"
15#include "mozilla/dom/CacheBinding.h"
16#include "mozilla/dom/Promise.h"
17#include "mozilla/dom/PromiseWorkerProxy.h"
18#include "mozilla/dom/ScriptLoader.h"
19#include "mozilla/dom/WorkerCommon.h"
20#include "mozilla/dom/cache/Cache.h"
21#include "mozilla/dom/cache/CacheStorage.h"
22#include "mozilla/ipc/BackgroundUtils.h"
23#include "mozilla/ipc/PBackgroundSharedTypes.h"
24#include "mozilla/net/CookieJarSettings.h"
25#include "nsContentUtils.h"
26#include "nsICacheInfoChannel.h"
27#include "nsIHttpChannel.h"
28#include "nsIInputStreamPump.h"
29#include "nsIPrincipal.h"
30#include "nsIScriptSecurityManager.h"
31#include "nsIStreamLoader.h"
32#include "nsIThreadRetargetableRequest.h"
33#include "nsIUUIDGenerator.h"
34#include "nsIXPConnect.h"
35#include "nsNetUtil.h"
36#include "nsReadableUtils.h"
37#include "nsStringStream.h"
38
39using mozilla::dom::cache::Cache;
40using mozilla::dom::cache::CacheStorage;
41using mozilla::ipc::PrincipalInfo;
42
43namespace mozilla::dom::serviceWorkerScriptCache {
44
45namespace {
46
47already_AddRefed<CacheStorage> CreateCacheStorage(JSContext* aCx,
48 nsIPrincipal* aPrincipal,
49 ErrorResult& aRv) {
50 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 50); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 50); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
51 MOZ_ASSERT(aPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPrincipal))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aPrincipal", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 51); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPrincipal" ")"
); do { MOZ_CrashSequence(__null, 51); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
52
53 nsIXPConnect* xpc = nsContentUtils::XPConnect();
54 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!"
")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 54); AnnotateMozCrashReason("MOZ_ASSERT" "(" "xpc" ") (" "This should never be null!"
")"); do { MOZ_CrashSequence(__null, 54); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
55 JS::Rooted<JSObject*> sandbox(aCx);
56 aRv = xpc->CreateSandbox(aCx, aPrincipal, sandbox.address());
57 if (NS_WARN_IF(aRv.Failed())NS_warn_if_impl(aRv.Failed(), "aRv.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 57)
) {
58 return nullptr;
59 }
60
61 // This is called when the JSContext is not in a realm, so CreateSandbox
62 // returned an unwrapped global.
63 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)"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 63); AnnotateMozCrashReason("MOZ_ASSERT" "(" "JS_IsGlobalObject(sandbox)"
")"); do { MOZ_CrashSequence(__null, 63); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
64
65 nsCOMPtr<nsIGlobalObject> sandboxGlobalObject = xpc::NativeGlobal(sandbox);
66 if (!sandboxGlobalObject) {
67 aRv.Throw(NS_ERROR_FAILURE);
68 return nullptr;
69 }
70
71 // We assume private browsing is not enabled here. The ScriptLoader
72 // explicitly fails for private browsing so there should never be
73 // a service worker running in private browsing mode. Therefore if
74 // we are purging scripts or running a comparison algorithm we cannot
75 // be in private browsing.
76 //
77 // Also, bypass the CacheStorage trusted origin checks. The ServiceWorker
78 // has validated the origin prior to this point. All the information
79 // to revalidate is not available now.
80 return CacheStorage::CreateOnMainThread(cache::CHROME_ONLY_NAMESPACE,
81 sandboxGlobalObject, aPrincipal,
82 true /* force trusted origin */, aRv);
83}
84
85class CompareManager;
86class CompareCache;
87
88// This class downloads a URL from the network, compare the downloaded script
89// with an existing cache if provided, and report to CompareManager via calling
90// ComparisonFinished().
91class CompareNetwork final : public nsIStreamLoaderObserver,
92 public nsIRequestObserver {
93 public:
94 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:
95 NS_DECL_NSISTREAMLOADEROBSERVERvirtual nsresult OnStreamComplete(nsIStreamLoader *loader, nsISupports
*ctxt, nsresult status, uint32_t resultLength, const uint8_t
*result) override;
96 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
97
98 CompareNetwork(CompareManager* aManager,
99 ServiceWorkerRegistrationInfo* aRegistration,
100 bool aIsMainScript)
101 : mManager(aManager),
102 mRegistration(aRegistration),
103 mInternalHeaders(new InternalHeaders()),
104 mLoadFlags(nsIChannel::LOAD_BYPASS_SERVICE_WORKER),
105 mState(WaitingForInitialization),
106 mNetworkResult(NS_OK),
107 mCacheResult(NS_OK),
108 mIsMainScript(aIsMainScript),
109 mIsFromCache(false) {
110 MOZ_ASSERT(aManager)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aManager)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aManager))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aManager", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 110); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aManager" ")"
); do { MOZ_CrashSequence(__null, 110); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
111 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 111); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 111); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
112 }
113
114 nsresult Initialize(nsIPrincipal* aPrincipal, const nsACString& aURL,
115 Cache* const aCache);
116
117 void Abort();
118
119 void NetworkFinish(nsresult aRv);
120
121 void CacheFinish(nsresult aRv);
122
123 const nsCString& URL() const {
124 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 124); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 124); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
125 return mURL;
126 }
127
128 const nsString& Buffer() const {
129 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 129); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
130 return mBuffer;
131 }
132
133 const ChannelInfo& GetChannelInfo() const { return mChannelInfo; }
134
135 already_AddRefed<InternalHeaders> GetInternalHeaders() const {
136 RefPtr<InternalHeaders> internalHeaders = mInternalHeaders;
137 return internalHeaders.forget();
138 }
139
140 UniquePtr<PrincipalInfo> TakePrincipalInfo() {
141 return std::move(mPrincipalInfo);
142 }
143
144 bool Succeeded() const { return NS_SUCCEEDED(mNetworkResult)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mNetworkResult)),
1)))
; }
145
146 const nsTArray<NotNull<RefPtr<nsIURI>>>& URLList() const { return mURLList; }
147
148 private:
149 ~CompareNetwork() {
150 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 150); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
151 MOZ_ASSERT(!mCC)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCC)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(!mCC))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!mCC", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 151); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCC" ")"); do
{ MOZ_CrashSequence(__null, 151); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
152 }
153
154 void Finish();
155
156 nsresult SetPrincipalInfo(nsIChannel* aChannel);
157
158 RefPtr<CompareManager> mManager;
159 RefPtr<CompareCache> mCC;
160 RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
161
162 nsCOMPtr<nsIChannel> mChannel;
163 nsString mBuffer;
164 nsCString mURL;
165 ChannelInfo mChannelInfo;
166 RefPtr<InternalHeaders> mInternalHeaders;
167 UniquePtr<PrincipalInfo> mPrincipalInfo;
168 nsTArray<NotNull<RefPtr<nsIURI>>> mURLList;
169
170 nsCString mMaxScope;
171 nsLoadFlags mLoadFlags;
172
173 enum {
174 WaitingForInitialization,
175 WaitingForBothFinished,
176 WaitingForNetworkFinished,
177 WaitingForCacheFinished,
178 Finished
179 } mState;
180
181 nsresult mNetworkResult;
182 nsresult mCacheResult;
183
184 const bool mIsMainScript;
185 bool mIsFromCache;
186};
187
188NS_IMPL_ISUPPORTS(CompareNetwork, nsIStreamLoaderObserver, nsIRequestObserver)MozExternalRefCountType CompareNetwork::AddRef(void) { static_assert
(!std::is_destructible_v<CompareNetwork>, "Reference-counted class "
"CompareNetwork" " 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" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 188
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CompareNetwork" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("CompareNetwork" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"CompareNetwork\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CompareNetwork\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 188); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("CompareNetwork" " not thread-safe"); nsrefcnt count = ++mRefCnt
; NS_LogAddRef((this), (count), ("CompareNetwork"), (uint32_t
)(sizeof(*this))); return count; } MozExternalRefCountType CompareNetwork
::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" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 188
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CompareNetwork" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("CompareNetwork" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"CompareNetwork\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CompareNetwork\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 188); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("CompareNetwork" " not thread-safe"); const char* const nametmp
= "CompareNetwork"; nsrefcnt count = --mRefCnt; NS_LogRelease
((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete
(this); return 0; } return count; } nsresult CompareNetwork::
QueryInterface(const nsIID& aIID, void** aInstancePtr) { do
{ if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 188); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<CompareNetwork, nsIStreamLoaderObserver>
, int32_t( reinterpret_cast<char*>(static_cast<nsIStreamLoaderObserver
*>((CompareNetwork*)0x1000)) - reinterpret_cast<char*>
((CompareNetwork*)0x1000))}, {&mozilla::detail::kImplementedIID
<CompareNetwork, nsIRequestObserver>, int32_t( reinterpret_cast
<char*>(static_cast<nsIRequestObserver*>((CompareNetwork
*)0x1000)) - reinterpret_cast<char*>((CompareNetwork*)0x1000
))}, {&mozilla::detail::kImplementedIID<CompareNetwork
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIStreamLoaderObserver*
>((CompareNetwork*)0x1000))) - reinterpret_cast<char*>
((CompareNetwork*)0x1000))}, { nullptr, 0 } } ; static_assert
(std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
189
190// This class gets a cached Response from the CacheStorage and then it calls
191// CacheFinish() in the CompareNetwork.
192class CompareCache final : public PromiseNativeHandler,
193 public nsIStreamLoaderObserver {
194 public:
195 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:
196 NS_DECL_NSISTREAMLOADEROBSERVERvirtual nsresult OnStreamComplete(nsIStreamLoader *loader, nsISupports
*ctxt, nsresult status, uint32_t resultLength, const uint8_t
*result) override;
197
198 explicit CompareCache(CompareNetwork* aCN)
199 : mCN(aCN), mState(WaitingForInitialization), mInCache(false) {
200 MOZ_ASSERT(aCN)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCN)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aCN))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aCN", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 200); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCN" ")"); do
{ MOZ_CrashSequence(__null, 200); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
201 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 201); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
202 }
203
204 nsresult Initialize(Cache* const aCache, const nsACString& aURL);
205
206 void Finish(nsresult aStatus, bool aInCache);
207
208 void Abort();
209
210 virtual void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
211 ErrorResult& aRv) override;
212
213 virtual void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
214 ErrorResult& aRv) override;
215
216 const nsString& Buffer() const {
217 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 217); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 217); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
218 return mBuffer;
219 }
220
221 bool InCache() { return mInCache; }
222
223 private:
224 ~CompareCache() { 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 224); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 224); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; }
225
226 void ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue);
227
228 RefPtr<CompareNetwork> mCN;
229 nsCOMPtr<nsIInputStreamPump> mPump;
230
231 nsCString mURL;
232 nsString mBuffer;
233
234 enum {
235 WaitingForInitialization,
236 WaitingForScript,
237 Finished,
238 } mState;
239
240 bool mInCache;
241};
242
243NS_IMPL_ISUPPORTS(CompareCache, nsIStreamLoaderObserver)MozExternalRefCountType CompareCache::AddRef(void) { static_assert
(!std::is_destructible_v<CompareCache>, "Reference-counted class "
"CompareCache" " 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" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 243
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CompareCache" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("CompareCache" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"CompareCache\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CompareCache\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 243); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("CompareCache" " not thread-safe"); nsrefcnt count = ++mRefCnt
; NS_LogAddRef((this), (count), ("CompareCache"), (uint32_t)(
sizeof(*this))); return count; } MozExternalRefCountType CompareCache
::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" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 243
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CompareCache" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("CompareCache" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"CompareCache\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CompareCache\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 243); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("CompareCache" " not thread-safe"); const char* const nametmp
= "CompareCache"; nsrefcnt count = --mRefCnt; NS_LogRelease(
(this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete
(this); return 0; } return count; } nsresult CompareCache::QueryInterface
(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 243); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<CompareCache, nsIStreamLoaderObserver>
, int32_t( reinterpret_cast<char*>(static_cast<nsIStreamLoaderObserver
*>((CompareCache*)0x1000)) - reinterpret_cast<char*>
((CompareCache*)0x1000))}, {&mozilla::detail::kImplementedIID
<CompareCache, nsISupports>, int32_t(reinterpret_cast<
char*>(static_cast<nsISupports*>( static_cast<nsIStreamLoaderObserver
*>((CompareCache*)0x1000))) - reinterpret_cast<char*>
((CompareCache*)0x1000))}, { nullptr, 0 } } ; static_assert(std
::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
244
245class CompareManager final : public PromiseNativeHandler {
246 public:
247 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:
248
249 explicit CompareManager(ServiceWorkerRegistrationInfo* aRegistration,
250 CompareCallback* aCallback)
251 : mRegistration(aRegistration),
252 mCallback(aCallback),
253 mLoadFlags(nsIChannel::LOAD_BYPASS_SERVICE_WORKER),
254 mState(WaitingForInitialization),
255 mPendingCount(0),
256 mOnFailure(OnFailure::DoNothing),
257 mAreScriptsEqual(true) {
258 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 258); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 258); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
259 MOZ_ASSERT(aRegistration)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRegistration)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRegistration))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRegistration",
"./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 259); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRegistration"
")"); do { MOZ_CrashSequence(__null, 259); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
260 }
261
262 nsresult Initialize(nsIPrincipal* aPrincipal, const nsACString& aURL,
263 const nsAString& aCacheName);
264
265 void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
266 ErrorResult& aRv) override;
267
268 void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
269 ErrorResult& aRv) override;
270
271 CacheStorage* CacheStorage_() {
272 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 272); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 272); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
273 MOZ_ASSERT(mCacheStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCacheStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCacheStorage))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mCacheStorage",
"./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 273); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheStorage"
")"); do { MOZ_CrashSequence(__null, 273); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
274 return mCacheStorage;
275 }
276
277 void ComparisonFinished(nsresult aStatus, bool aIsMainScript, bool aIsEqual,
278 const nsACString& aMaxScope, nsLoadFlags aLoadFlags) {
279 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 279); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 279); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
280 if (mState == Finished) {
281 return;
282 }
283
284 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForScriptOrComparisonResult)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForScriptOrComparisonResult)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mState == WaitingForScriptOrComparisonResult))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mState == WaitingForScriptOrComparisonResult"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 284); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForScriptOrComparisonResult"
")"); do { MOZ_CrashSequence(__null, 284); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
285
286 if (NS_WARN_IF(NS_FAILED(aStatus))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus
)), 0))), "NS_FAILED(aStatus)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 286)
) {
287 Fail(aStatus);
288 return;
289 }
290
291 mAreScriptsEqual = mAreScriptsEqual && aIsEqual;
292
293 if (aIsMainScript) {
294 mMaxScope = aMaxScope;
295 mLoadFlags = aLoadFlags;
296 }
297
298 // Check whether all CompareNetworks finished their jobs.
299 MOZ_DIAGNOSTIC_ASSERT(mPendingCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPendingCount > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPendingCount > 0))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mPendingCount > 0"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 299); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mPendingCount > 0"
")"); do { MOZ_CrashSequence(__null, 299); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
300 if (--mPendingCount) {
301 return;
302 }
303
304 if (mAreScriptsEqual) {
305 MOZ_ASSERT(mCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCallback", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 305); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCallback" ")"
); do { MOZ_CrashSequence(__null, 305); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
306 mCallback->ComparisonResult(aStatus, true /* aSameScripts */, mOnFailure,
307 u""_ns, mMaxScope, mLoadFlags);
308 Cleanup();
309 return;
310 }
311
312 // Write to Cache so ScriptLoader reads succeed.
313 WriteNetworkBufferToNewCache();
314 }
315
316 private:
317 ~CompareManager() {
318 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 318); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 318); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
319 MOZ_ASSERT(mCNList.Length() == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCNList.Length() == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCNList.Length() == 0))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("mCNList.Length() == 0"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 319); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCNList.Length() == 0"
")"); do { MOZ_CrashSequence(__null, 319); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
320 }
321
322 void Fail(nsresult aStatus);
323
324 void Cleanup();
325
326 nsresult FetchScript(const nsACString& aURL, bool aIsMainScript,
327 Cache* const aCache = nullptr) {
328 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 328); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 328); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
329
330 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForInitialization ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 331); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult"
")"); do { MOZ_CrashSequence(__null, 331); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
331 mState == WaitingForScriptOrComparisonResult)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 331); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForInitialization || mState == WaitingForScriptOrComparisonResult"
")"); do { MOZ_CrashSequence(__null, 331); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
332
333 RefPtr<CompareNetwork> cn =
334 new CompareNetwork(this, mRegistration, aIsMainScript);
335 mCNList.AppendElement(cn);
336 mPendingCount += 1;
337
338 nsresult rv = cn->Initialize(mPrincipal, aURL, aCache);
339 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 339)
) {
340 return rv;
341 }
342
343 return NS_OK;
344 }
345
346 void ManageOldCache(JSContext* aCx, JS::Handle<JS::Value> aValue) {
347 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForExistingOpen)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForExistingOpen)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == WaitingForExistingOpen
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForExistingOpen", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 347); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForExistingOpen"
")"); do { MOZ_CrashSequence(__null, 347); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
348
349 // RAII Cleanup when fails.
350 nsresult rv = NS_ERROR_FAILURE;
351 auto guard = MakeScopeExit([&] { Fail(rv); });
352
353 if (NS_WARN_IF(!aValue.isObject())NS_warn_if_impl(!aValue.isObject(), "!aValue.isObject()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 353)
) {
354 return;
355 }
356
357 MOZ_ASSERT(!mOldCache)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mOldCache)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mOldCache))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mOldCache", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 357); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mOldCache" ")"
); do { MOZ_CrashSequence(__null, 357); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
358 JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
359 if (NS_WARN_IF(!obj)NS_warn_if_impl(!obj, "!obj", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 359)
||
360 NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Cache, obj, mOldCache)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(mozilla
::dom::binding_detail::UnwrapObjectWithCrossOriginAsserts<
mozilla::dom::prototypes::id::Cache, mozilla::dom::Cache_Binding
::NativeType>(obj, mOldCache))), 0))), "NS_FAILED(UNWRAP_OBJECT(Cache, obj, mOldCache))"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 360)
) {
361 return;
362 }
363
364 Optional<RequestOrUTF8String> request;
365 CacheQueryOptions options;
366 ErrorResult error;
367 RefPtr<Promise> promise = mOldCache->Keys(aCx, request, options, error);
368 if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 368)
) {
369 // No exception here because there are no ReadableStreams involved here.
370 MOZ_ASSERT(!error.IsJSException())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!error.IsJSException())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!error.IsJSException()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!error.IsJSException()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 370); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!error.IsJSException()"
")"); do { MOZ_CrashSequence(__null, 370); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
371 rv = error.StealNSResult();
372 return;
373 }
374
375 mState = WaitingForExistingKeys;
376 promise->AppendNativeHandler(this);
377 guard.release();
378 }
379
380 void ManageOldKeys(JSContext* aCx, JS::Handle<JS::Value> aValue) {
381 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForExistingKeys)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForExistingKeys)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == WaitingForExistingKeys
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForExistingKeys", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 381); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForExistingKeys"
")"); do { MOZ_CrashSequence(__null, 381); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
382
383 // RAII Cleanup when fails.
384 nsresult rv = NS_ERROR_FAILURE;
385 auto guard = MakeScopeExit([&] { Fail(rv); });
386
387 if (NS_WARN_IF(!aValue.isObject())NS_warn_if_impl(!aValue.isObject(), "!aValue.isObject()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 387)
) {
388 return;
389 }
390
391 JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
392 if (NS_WARN_IF(!obj)NS_warn_if_impl(!obj, "!obj", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 392)
) {
393 return;
394 }
395
396 uint32_t len = 0;
397 if (!JS::GetArrayLength(aCx, obj, &len)) {
398 return;
399 }
400
401 // Fetch and compare the source scripts.
402 MOZ_ASSERT(mPendingCount == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPendingCount == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPendingCount == 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mPendingCount == 0"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 402); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPendingCount == 0"
")"); do { MOZ_CrashSequence(__null, 402); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
403
404 mState = WaitingForScriptOrComparisonResult;
405
406 bool hasMainScript = false;
407 AutoTArray<nsCString, 8> urlList;
408
409 // Extract the list of URLs in the old cache.
410 for (uint32_t i = 0; i < len; ++i) {
411 JS::Rooted<JS::Value> val(aCx);
412 if (NS_WARN_IF(!JS_GetElement(aCx, obj, i, &val))NS_warn_if_impl(!JS_GetElement(aCx, obj, i, &val), "!JS_GetElement(aCx, obj, i, &val)"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 412)
||
413 NS_WARN_IF(!val.isObject())NS_warn_if_impl(!val.isObject(), "!val.isObject()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 413)
) {
414 return;
415 }
416
417 Request* request;
418 JS::Rooted<JSObject*> requestObj(aCx, &val.toObject());
419 if (NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Request, &requestObj, request)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(mozilla
::dom::binding_detail::UnwrapObjectWithCrossOriginAsserts<
mozilla::dom::prototypes::id::Request, mozilla::dom::Request_Binding
::NativeType>(&requestObj, request))), 0))), "NS_FAILED(UNWRAP_OBJECT(Request, &requestObj, request))"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 419)
) {
420 return;
421 };
422
423 nsCString url;
424 request->GetUrl(url);
425
426 if (!hasMainScript && url == mURL) {
427 hasMainScript = true;
428 }
429
430 urlList.AppendElement(std::move(url));
431 }
432
433 // If the main script is missing, then something has gone wrong. We
434 // will try to continue with the update process to trigger a new
435 // installation. If that fails, however, then uninstall the registration
436 // because it is broken in a way that cannot be fixed.
437 if (!hasMainScript) {
438 mOnFailure = OnFailure::Uninstall;
439 }
440
441 // Always make sure to fetch the main script. If the old cache has
442 // no entries or the main script entry is missing, then the loop below
443 // may not trigger it. This should not really happen, but we handle it
444 // gracefully if it does occur. Its possible the bad cache state is due
445 // to a crash or shutdown during an update, etc.
446 rv = FetchScript(mURL, true /* aIsMainScript */, mOldCache);
447 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 447)
) {
448 return;
449 }
450
451 for (const auto& url : urlList) {
452 // We explicitly start the fetch for the main script above.
453 if (mURL == url) {
454 continue;
455 }
456
457 rv = FetchScript(url, false /* aIsMainScript */, mOldCache);
458 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 458)
) {
459 return;
460 }
461 }
462
463 guard.release();
464 }
465
466 void ManageNewCache(JSContext* aCx, JS::Handle<JS::Value> aValue) {
467 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForOpen)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForOpen)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == WaitingForOpen))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mState == WaitingForOpen"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 467); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForOpen"
")"); do { MOZ_CrashSequence(__null, 467); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
468
469 // RAII Cleanup when fails.
470 nsresult rv = NS_ERROR_FAILURE;
471 auto guard = MakeScopeExit([&] { Fail(rv); });
472
473 if (NS_WARN_IF(!aValue.isObject())NS_warn_if_impl(!aValue.isObject(), "!aValue.isObject()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 473)
) {
474 return;
475 }
476
477 JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
478 if (NS_WARN_IF(!obj)NS_warn_if_impl(!obj, "!obj", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 478)
) {
479 return;
480 }
481
482 Cache* cache = nullptr;
483 rv = UNWRAP_OBJECT(Cache, &obj, cache)mozilla::dom::binding_detail::UnwrapObjectWithCrossOriginAsserts
< mozilla::dom::prototypes::id::Cache, mozilla::dom::Cache_Binding
::NativeType>(&obj, cache)
;
484 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 484)
) {
485 return;
486 }
487
488 // Just to be safe.
489 RefPtr<Cache> kungfuDeathGrip = cache;
490
491 MOZ_ASSERT(mPendingCount == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPendingCount == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPendingCount == 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mPendingCount == 0"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPendingCount == 0"
")"); do { MOZ_CrashSequence(__null, 491); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
492 for (uint32_t i = 0; i < mCNList.Length(); ++i) {
493 // We bail out immediately when something goes wrong.
494 rv = WriteToCache(aCx, cache, mCNList[i]);
495 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 495)
) {
496 return;
497 }
498 }
499
500 mState = WaitingForPut;
501 guard.release();
502 }
503
504 void WriteNetworkBufferToNewCache() {
505 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 505); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 505); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
506 MOZ_ASSERT(mCNList.Length() != 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCNList.Length() != 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCNList.Length() != 0))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("mCNList.Length() != 0"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 506); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCNList.Length() != 0"
")"); do { MOZ_CrashSequence(__null, 506); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
507 MOZ_ASSERT(mCacheStorage)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCacheStorage)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCacheStorage))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mCacheStorage",
"./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 507); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheStorage"
")"); do { MOZ_CrashSequence(__null, 507); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
508 MOZ_ASSERT(mNewCacheName.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mNewCacheName.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mNewCacheName.IsEmpty()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("mNewCacheName.IsEmpty()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 508); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mNewCacheName.IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 508); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
509
510 ErrorResult result;
511 result = serviceWorkerScriptCache::GenerateCacheName(mNewCacheName);
512 if (NS_WARN_IF(result.Failed())NS_warn_if_impl(result.Failed(), "result.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 512)
) {
513 MOZ_ASSERT(!result.IsErrorWithMessage())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!result.IsErrorWithMessage())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!result.IsErrorWithMessage()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!result.IsErrorWithMessage()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 513); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!result.IsErrorWithMessage()"
")"); do { MOZ_CrashSequence(__null, 513); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
514 Fail(result.StealNSResult());
515 return;
516 }
517
518 RefPtr<Promise> cacheOpenPromise =
519 mCacheStorage->Open(mNewCacheName, result);
520 if (NS_WARN_IF(result.Failed())NS_warn_if_impl(result.Failed(), "result.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 520)
) {
521 MOZ_ASSERT(!result.IsErrorWithMessage())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!result.IsErrorWithMessage())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!result.IsErrorWithMessage()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!result.IsErrorWithMessage()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 521); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!result.IsErrorWithMessage()"
")"); do { MOZ_CrashSequence(__null, 521); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
522 Fail(result.StealNSResult());
523 return;
524 }
525
526 mState = WaitingForOpen;
527 cacheOpenPromise->AppendNativeHandler(this);
528 }
529
530 nsresult WriteToCache(JSContext* aCx, Cache* aCache, CompareNetwork* aCN) {
531 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 531); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 531); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
532 MOZ_ASSERT(aCache)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCache)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aCache))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aCache", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 532); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCache" ")")
; do { MOZ_CrashSequence(__null, 532); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
533 MOZ_ASSERT(aCN)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCN)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aCN))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aCN", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 533); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCN" ")"); do
{ MOZ_CrashSequence(__null, 533); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
534 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForOpen)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForOpen)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == WaitingForOpen))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mState == WaitingForOpen"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 534); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForOpen"
")"); do { MOZ_CrashSequence(__null, 534); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
535
536 // We don't have to save any information from a failed CompareNetwork.
537 if (!aCN->Succeeded()) {
538 return NS_OK;
539 }
540
541 // Scripts can be several megabytes, so the UTF-16 to UTF-8 conversion is
542 // done fallibly here. Failing the update is much better than aborting the
543 // parent process with an OOM crash.
544 nsCString converted;
545 if (NS_WARN_IF(!CopyUTF16toUTF8(aCN->Buffer(), converted, fallible))NS_warn_if_impl(!CopyUTF16toUTF8(aCN->Buffer(), converted,
fallible), "!CopyUTF16toUTF8(aCN->Buffer(), converted, fallible)"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 545)
) {
546 return NS_ERROR_OUT_OF_MEMORY;
547 }
548
549 // Note that this is the length of the UTF-8 body we just produced, not the
550 // length of the UTF-16 buffer it was converted from.
551 const int64_t bodyLength = converted.Length();
552
553 nsCOMPtr<nsIInputStream> body;
554 nsresult rv =
555 NS_NewCStringInputStream(getter_AddRefs(body), std::move(converted));
556 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 556)
) {
557 return rv;
558 }
559
560 SafeRefPtr<InternalResponse> ir =
561 MakeSafeRefPtr<InternalResponse>(200, "OK"_ns);
562 ir->SetBody(body, bodyLength);
563 ir->SetURLList(aCN->URLList());
564
565 ir->InitChannelInfo(aCN->GetChannelInfo());
566 UniquePtr<PrincipalInfo> principalInfo = aCN->TakePrincipalInfo();
567 if (principalInfo) {
568 ir->SetPrincipalInfo(std::move(principalInfo));
569 }
570
571 RefPtr<InternalHeaders> internalHeaders = aCN->GetInternalHeaders();
572 ir->Headers()->Fill(*(internalHeaders.get()), IgnoreErrors());
573
574 RefPtr<Response> response =
575 new Response(aCache->GetGlobalObject(), std::move(ir), nullptr);
576
577 RequestOrUTF8String request;
578 request.SetAsUTF8String() = aCN->URL();
579
580 // For now we have to wait until the Put Promise is fulfilled before we can
581 // continue since Cache does not yet support starting a read that is being
582 // written to.
583 ErrorResult result;
584 RefPtr<Promise> cachePromise = aCache->Put(aCx, request, *response, result);
585 result.WouldReportJSException();
586 if (NS_WARN_IF(result.Failed())NS_warn_if_impl(result.Failed(), "result.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 586)
) {
587 // No exception here because there are no ReadableStreams involved here.
588 MOZ_ASSERT(!result.IsJSException())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!result.IsJSException())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!result.IsJSException()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!result.IsJSException()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 588); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!result.IsJSException()"
")"); do { MOZ_CrashSequence(__null, 588); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
589 MOZ_ASSERT(!result.IsErrorWithMessage())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!result.IsErrorWithMessage())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!result.IsErrorWithMessage()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!result.IsErrorWithMessage()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 589); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!result.IsErrorWithMessage()"
")"); do { MOZ_CrashSequence(__null, 589); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
590 return result.StealNSResult();
591 }
592
593 mPendingCount += 1;
594 cachePromise->AppendNativeHandler(this);
595 return NS_OK;
596 }
597
598 RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
599 RefPtr<CompareCallback> mCallback;
600 RefPtr<CacheStorage> mCacheStorage;
601
602 nsTArray<RefPtr<CompareNetwork>> mCNList;
603
604 nsCString mURL;
605 RefPtr<nsIPrincipal> mPrincipal;
606
607 // Used for the old cache where saves the old source scripts.
608 RefPtr<Cache> mOldCache;
609
610 // Only used if the network script has changed and needs to be cached.
611 nsString mNewCacheName;
612
613 nsCString mMaxScope;
614 nsLoadFlags mLoadFlags;
615
616 enum {
617 WaitingForInitialization,
618 WaitingForExistingOpen,
619 WaitingForExistingKeys,
620 WaitingForScriptOrComparisonResult,
621 WaitingForOpen,
622 WaitingForPut,
623 Finished
624 } mState;
625
626 uint32_t mPendingCount;
627 OnFailure mOnFailure;
628 bool mAreScriptsEqual;
629};
630
631NS_IMPL_ISUPPORTS0(CompareManager)MozExternalRefCountType CompareManager::AddRef(void) { static_assert
(!std::is_destructible_v<CompareManager>, "Reference-counted class "
"CompareManager" " 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" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 631); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 631
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CompareManager" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("CompareManager" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"CompareManager\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 631); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CompareManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 631); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("CompareManager" " not thread-safe"); nsrefcnt count = ++mRefCnt
; NS_LogAddRef((this), (count), ("CompareManager"), (uint32_t
)(sizeof(*this))); return count; } MozExternalRefCountType CompareManager
::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" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 631); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 631
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CompareManager" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("CompareManager" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"CompareManager\" != nullptr"
" (" "Must specify a name" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 631); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CompareManager\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 631); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("CompareManager" " not thread-safe"); const char* const nametmp
= "CompareManager"; nsrefcnt count = --mRefCnt; NS_LogRelease
((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete
(this); return 0; } return count; } nsresult CompareManager::
QueryInterface(const nsIID& aIID, void** aInstancePtr) { do
{ if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 631); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<CompareManager, nsISupports>, int32_t
( reinterpret_cast<char*>(static_cast<nsISupports*>
((CompareManager*)0x1000)) - reinterpret_cast<char*>((CompareManager
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
632
633nsresult CompareNetwork::Initialize(nsIPrincipal* aPrincipal,
634 const nsACString& aURL,
635 Cache* const aCache) {
636 MOZ_ASSERT(aPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPrincipal))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aPrincipal", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 636); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPrincipal" ")"
); do { MOZ_CrashSequence(__null, 636); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
637 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 637); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 637); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
638
639 nsCOMPtr<nsIURI> uri;
640 nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL);
641 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 641)
) {
642 return rv;
643 }
644
645 mURL = aURL;
646 mURLList.AppendElement(WrapNotNull(uri.get()));
647
648 nsCOMPtr<nsILoadGroup> loadGroup;
649 rv = NS_NewLoadGroup(getter_AddRefs(loadGroup), aPrincipal);
650 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 650)
) {
651 return rv;
652 }
653
654 // Update LoadFlags for propagating to ServiceWorkerInfo.
655 mLoadFlags = nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
656
657 ServiceWorkerUpdateViaCache uvc = mRegistration->GetUpdateViaCache();
658 if (uvc == ServiceWorkerUpdateViaCache::None ||
659 (uvc == ServiceWorkerUpdateViaCache::Imports && mIsMainScript)) {
660 mLoadFlags |= nsIRequest::VALIDATE_ALWAYS;
661 }
662
663 if (mRegistration->IsLastUpdateCheckTimeOverOneDay()) {
664 mLoadFlags |= nsIRequest::LOAD_BYPASS_CACHE;
665 }
666
667 // Different settings are needed for fetching imported scripts, since they
668 // might be cross-origin scripts.
669 uint32_t secFlags =
670 mIsMainScript ? nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED
671 : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT;
672
673 nsContentPolicyType contentPolicyType =
674 mIsMainScript ? nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER
675 : nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS;
676
677 // Create a new cookieJarSettings.
678 nsCOMPtr<nsICookieJarSettings> cookieJarSettings =
679 mozilla::net::CookieJarSettings::Create(aPrincipal);
680
681 // Populate the partitionKey by using the given prinicpal. The ServiceWorkers
682 // are using the foreign partitioned principal, so we can get the partitionKey
683 // from it and the partitionKey will only exist if it's in the third-party
684 // context. In first-party context, we can still use the uri to set the
685 // partitionKey.
686 if (!aPrincipal->OriginAttributesRef().mPartitionKey.IsEmpty()) {
687 net::CookieJarSettings::Cast(cookieJarSettings)
688 ->SetPartitionKey(aPrincipal->OriginAttributesRef().mPartitionKey);
689 } else {
690 net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri);
691 }
692
693 // Note that because there is no "serviceworker" RequestContext type, we can
694 // use the TYPE_INTERNAL_SCRIPT content policy types when loading a service
695 // worker.
696 rv = NS_NewChannel(getter_AddRefs(mChannel), uri, aPrincipal, secFlags,
697 contentPolicyType, cookieJarSettings,
698 nullptr /* aPerformanceStorage */, loadGroup,
699 nullptr /* aCallbacks */, mLoadFlags);
700 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 700)
) {
701 return rv;
702 }
703
704 // Set the IsInThirdPartyContext for the channel's loadInfo according to the
705 // partitionKey of the principal. The worker is foreign if it's using
706 // partitioned principal, i.e. the partitionKey is not empty. In this case,
707 // we need to set the bit to the channel's loadInfo.
708 if (!aPrincipal->OriginAttributesRef().mPartitionKey.IsEmpty()) {
709 nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
710 rv = loadInfo->SetIsInThirdPartyContext(true);
711 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)))", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 711); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 711); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
712 }
713
714 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
715 if (httpChannel) {
716 // Spec says no redirects allowed for top-level SW scripts.
717 if (mIsMainScript) {
718 rv = httpChannel->SetRedirectionLimit(0);
719 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)))", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 719); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 719); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
720 }
721
722 rv = httpChannel->SetRequestHeader("Service-Worker"_ns, "script"_ns,
723 /* merge */ false);
724 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)))", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 724); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 724); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
725 }
726
727 nsCOMPtr<nsIStreamLoader> loader;
728 rv = NS_NewStreamLoader(getter_AddRefs(loader), this, this);
729 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 729)
) {
730 return rv;
731 }
732
733 rv = mChannel->AsyncOpen(loader);
734 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 734)
) {
735 return rv;
736 }
737
738 // If we do have an existing cache to compare with.
739 if (aCache) {
740 mCC = new CompareCache(this);
741 rv = mCC->Initialize(aCache, aURL);
742 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 742)
) {
743 Abort();
744 return rv;
745 }
746
747 mState = WaitingForBothFinished;
748 return NS_OK;
749 }
750
751 mState = WaitingForNetworkFinished;
752 return NS_OK;
753}
754
755void CompareNetwork::Finish() {
756 if (mState == Finished) {
757 return;
758 }
759
760 bool same = true;
761 nsresult rv = NS_OK;
762
763 // mNetworkResult is prior to mCacheResult, since it's needed for reporting
764 // various errors to web content.
765 if (NS_FAILED(mNetworkResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(mNetworkResult)), 0
)))
) {
766 // An imported script could become offline, since it might no longer be
767 // needed by the new importing script. In that case, the importing script
768 // must be different, and thus, it's okay to report same script found here.
769 rv = mIsMainScript ? mNetworkResult : NS_OK;
770 same = true;
771 } else if (mCC && NS_FAILED(mCacheResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(mCacheResult)), 0)
))
) {
772 rv = mCacheResult;
773 } else { // Both passed.
774 same = mCC && mCC->InCache() && mCC->Buffer().Equals(mBuffer);
775 }
776
777 mManager->ComparisonFinished(rv, mIsMainScript, same, mMaxScope, mLoadFlags);
778
779 // We have done with the CompareCache.
780 mCC = nullptr;
781}
782
783void CompareNetwork::NetworkFinish(nsresult aRv) {
784 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForBothFinished ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForBothFinished || mState == WaitingForNetworkFinished
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mState == WaitingForBothFinished || mState == WaitingForNetworkFinished
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForBothFinished || mState == WaitingForNetworkFinished"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 785); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForBothFinished || mState == WaitingForNetworkFinished"
")"); do { MOZ_CrashSequence(__null, 785); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
785 mState == WaitingForNetworkFinished)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForBothFinished || mState == WaitingForNetworkFinished
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mState == WaitingForBothFinished || mState == WaitingForNetworkFinished
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForBothFinished || mState == WaitingForNetworkFinished"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 785); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForBothFinished || mState == WaitingForNetworkFinished"
")"); do { MOZ_CrashSequence(__null, 785); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
786
787 mNetworkResult = aRv;
788
789 if (mState == WaitingForBothFinished) {
790 mState = WaitingForCacheFinished;
791 return;
792 }
793
794 if (mState == WaitingForNetworkFinished) {
795 Finish();
796 return;
797 }
798}
799
800void CompareNetwork::CacheFinish(nsresult aRv) {
801 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForBothFinished ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForBothFinished || mState == WaitingForCacheFinished
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mState == WaitingForBothFinished || mState == WaitingForCacheFinished
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForBothFinished || mState == WaitingForCacheFinished"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 802); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForBothFinished || mState == WaitingForCacheFinished"
")"); do { MOZ_CrashSequence(__null, 802); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
802 mState == WaitingForCacheFinished)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForBothFinished || mState == WaitingForCacheFinished
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mState == WaitingForBothFinished || mState == WaitingForCacheFinished
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForBothFinished || mState == WaitingForCacheFinished"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 802); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForBothFinished || mState == WaitingForCacheFinished"
")"); do { MOZ_CrashSequence(__null, 802); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
803
804 mCacheResult = aRv;
805
806 if (mState == WaitingForBothFinished) {
807 mState = WaitingForNetworkFinished;
808 return;
809 }
810
811 if (mState == WaitingForCacheFinished) {
812 Finish();
813 return;
814 }
815}
816
817void CompareNetwork::Abort() {
818 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 818); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
819
820 if (mState != Finished) {
821 mState = Finished;
822
823 MOZ_ASSERT(mChannel)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mChannel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mChannel))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mChannel", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 823); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mChannel" ")"
); do { MOZ_CrashSequence(__null, 823); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
824 mChannel->CancelWithReason(NS_BINDING_ABORTED, "CompareNetwork::Abort"_ns);
825 mChannel = nullptr;
826
827 if (mCC) {
828 mCC->Abort();
829 mCC = nullptr;
830 }
831 }
832}
833
834NS_IMETHODIMPnsresult
835CompareNetwork::OnStartRequest(nsIRequest* aRequest) {
836 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 836); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 836); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
837
838 if (mState == Finished) {
839 return NS_OK;
840 }
841
842 nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
843 MOZ_ASSERT_IF(mIsMainScript, channel == mChannel)do { if (mIsMainScript) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(channel == mChannel)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(channel == mChannel))), 0))) { do { } while (false);
MOZ_ReportAssertionFailure("channel == mChannel", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 843); AnnotateMozCrashReason("MOZ_ASSERT" "(" "channel == mChannel"
")"); do { MOZ_CrashSequence(__null, 843); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
844 mChannel = channel;
845
846 MOZ_ASSERT(!mChannelInfo.IsInitialized())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mChannelInfo.IsInitialized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mChannelInfo.IsInitialized(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!mChannelInfo.IsInitialized()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 846); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mChannelInfo.IsInitialized()"
")"); do { MOZ_CrashSequence(__null, 846); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
847 mChannelInfo.InitFromChannel(mChannel);
848
849 nsresult rv = SetPrincipalInfo(mChannel);
850 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 850)
) {
851 return rv;
852 }
853
854 mInternalHeaders->FillResponseHeaders(mChannel);
855
856 nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(channel));
857 if (cacheChannel) {
858 cacheChannel->IsFromCache(&mIsFromCache);
859 }
860
861 return NS_OK;
862}
863
864nsresult CompareNetwork::SetPrincipalInfo(nsIChannel* aChannel) {
865 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
866 if (!ssm) {
867 return NS_ERROR_FAILURE;
868 }
869
870 nsCOMPtr<nsIPrincipal> channelPrincipal;
871 nsresult rv = ssm->GetChannelResultPrincipal(
872 aChannel, getter_AddRefs(channelPrincipal));
873 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 873)
) {
874 return rv;
875 }
876
877 UniquePtr<PrincipalInfo> principalInfo = MakeUnique<PrincipalInfo>();
878 rv = PrincipalToPrincipalInfo(channelPrincipal, principalInfo.get());
879
880 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 880)
) {
881 return rv;
882 }
883
884 mPrincipalInfo = std::move(principalInfo);
885 return NS_OK;
886}
887
888NS_IMETHODIMPnsresult
889CompareNetwork::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
890 // Nothing to do here!
891 return NS_OK;
892}
893
894NS_IMETHODIMPnsresult
895CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader,
896 nsISupports* aContext, nsresult aStatus,
897 uint32_t aLen, const uint8_t* aString) {
898 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 898); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 898); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
899
900 if (mState == Finished) {
901 return NS_OK;
902 }
903
904 nsresult rv = NS_ERROR_FAILURE;
905 auto guard = MakeScopeExit([&] { NetworkFinish(rv); });
906
907 if (aLen > GetWorkerScriptMaxSizeInBytes()) {
908 rv = NS_ERROR_DOM_ABORT_ERR; // This will make sure an exception gets
909 // thrown to the global.
910 return NS_OK;
911 }
912
913 if (NS_WARN_IF(NS_FAILED(aStatus))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus
)), 0))), "NS_FAILED(aStatus)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 913)
) {
914 rv = (aStatus == NS_ERROR_REDIRECT_LOOP) ? NS_ERROR_DOM_SECURITY_ERR
915 : aStatus;
916 return NS_OK;
917 }
918
919 nsCOMPtr<nsIRequest> request;
920 rv = aLoader->GetRequest(getter_AddRefs(request));
921 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 921)
) {
922 return NS_OK;
923 }
924
925 nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
926 MOZ_ASSERT(channel, "How come we don't have any channel?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(channel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(channel))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("channel" " (" "How come we don't have any channel?"
")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 926); AnnotateMozCrashReason("MOZ_ASSERT" "(" "channel" ") ("
"How come we don't have any channel?" ")"); do { MOZ_CrashSequence
(__null, 926); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
927
928 nsCOMPtr<nsIURI> uri;
929 channel->GetOriginalURI(getter_AddRefs(uri));
930 bool isExtension = uri->SchemeIs("moz-extension");
931
932 if (isExtension &&
933 !StaticPrefs::extensions_backgroundServiceWorker_enabled_AtStartup()) {
934 // Return earlier with error is the worker script is a moz-extension url
935 // but the feature isn't enabled by prefs.
936 return NS_ERROR_FAILURE;
937 }
938
939 if (isExtension) {
940 // NOTE: trying to register any moz-extension use that doesn't ends
941 // with .js//.mjs seems to be already completing with an error
942 // in aStatus and they never reach this point.
943
944 // TODO: look into avoid duplicated parts that could be shared with the HTTP
945 // channel scenario.
946 nsCOMPtr<nsIURI> channelURL;
947 rv = channel->GetURI(getter_AddRefs(channelURL));
948 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 948)
) {
949 return rv;
950 }
951
952 // Append the final URL (which for an extension worker script is going to
953 // be a file or jar url).
954 MOZ_DIAGNOSTIC_ASSERT(!mURLList.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mURLList.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mURLList.IsEmpty()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mURLList.IsEmpty()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 954); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mURLList.IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 954); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
955
956 bool equals = false;
957 if (NS_FAILED(channelURL->Equals(mURLList[0], &equals))((bool)(__builtin_expect(!!(NS_FAILED_impl(channelURL->Equals
(mURLList[0], &equals))), 0)))
|| !equals) {
958 mURLList.AppendElement(WrapNotNull(channelURL.get()));
959 }
960
961 UniquePtr<char16_t[], JS::FreePolicy> buffer;
962 size_t len = 0;
963
964 rv = ScriptLoader::ConvertToUTF16(channel, aString, aLen, u"UTF-8"_ns,
965 nullptr, buffer, len);
966 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 966)
) {
967 return rv;
968 }
969
970 mBuffer.Adopt(buffer.release(), len);
971
972 rv = NS_OK;
973 return NS_OK;
974 }
975
976 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
977
978 // Main scripts cannot be redirected successfully, however extensions
979 // may successfuly redirect imported scripts to a moz-extension url
980 // (if listed in the web_accessible_resources manifest property).
981 //
982 // When the service worker is initially registered the imported scripts
983 // will be loaded from the child process (see dom/workers/ScriptLoader.cpp)
984 // and in that case this method will only be called for the main script.
985 //
986 // When a registered worker is loaded again (e.g. when the webpage calls
987 // the ServiceWorkerRegistration's update method):
988 //
989 // - both the main and imported scripts are loaded by the
990 // CompareManager::FetchScript
991 // - the update requests for the imported scripts will also be calling this
992 // method and we should expect scripts redirected to an extension script
993 // to have a null httpChannel.
994 //
995 // The request that triggers this method is:
996 //
997 // - the one that is coming from the network (which may be intercepted by
998 // WebRequest listeners in extensions and redirected to a web_accessible
999 // moz-extension url)
1000 // - it will then be compared with a previous response that we may have
1001 // in the cache
1002 //
1003 // When the next service worker update occurs, if the request (for an imported
1004 // script) is not redirected by an extension the cache entry is invalidated
1005 // and a network request is triggered for the import.
1006 if (!httpChannel) {
1007 // Redirecting a service worker main script should fail before reaching this
1008 // method.
1009 // If a main script is somehow redirected, the diagnostic assert will crash
1010 // in non-release builds. Release builds will return an explicit error.
1011 MOZ_DIAGNOSTIC_ASSERT(!mIsMainScript,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIsMainScript)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIsMainScript))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mIsMainScript"
" (" "Unexpected ServiceWorker main script redirected" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1012); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mIsMainScript"
") (" "Unexpected ServiceWorker main script redirected" ")")
; do { MOZ_CrashSequence(__null, 1012); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1012 "Unexpected ServiceWorker main script redirected")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mIsMainScript)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mIsMainScript))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mIsMainScript"
" (" "Unexpected ServiceWorker main script redirected" ")", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1012); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mIsMainScript"
") (" "Unexpected ServiceWorker main script redirected" ")")
; do { MOZ_CrashSequence(__null, 1012); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1013 if (mIsMainScript) {
1014 return NS_ERROR_UNEXPECTED;
1015 }
1016
1017 nsCOMPtr<nsIPrincipal> channelPrincipal;
1018
1019 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1020 if (!ssm) {
1021 return NS_ERROR_UNEXPECTED;
1022 }
1023
1024 nsresult rv = ssm->GetChannelResultPrincipal(
Value stored to 'rv' during its initialization is never read
1025 channel, getter_AddRefs(channelPrincipal));
1026
1027 // An extension did redirect a non-MainScript request to a moz-extension url
1028 // (in that case the originalURL is the resolved jar URI and so we have to
1029 // look to the channel principal instead).
1030 if (channelPrincipal->SchemeIs("moz-extension")) {
1031 UniquePtr<char16_t[], JS::FreePolicy> buffer;
1032 size_t len = 0;
1033
1034 rv = ScriptLoader::ConvertToUTF16(channel, aString, aLen, u"UTF-8"_ns,
1035 nullptr, buffer, len);
1036 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1036)
) {
1037 return rv;
1038 }
1039
1040 mBuffer.Adopt(buffer.release(), len);
1041
1042 return NS_OK;
1043 }
1044
1045 // Make non-release and debug builds to crash if this happens and fail
1046 // explicitly on release builds.
1047 MOZ_DIAGNOSTIC_CRASH(do { do { } while (false); MOZ_ReportCrash("" "ServiceWorker imported script redirected to an url "
"with an unexpected scheme", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1049); AnnotateMozCrashReason("MOZ_CRASH(" "ServiceWorker imported script redirected to an url "
"with an unexpected scheme" ")"); do { MOZ_CrashSequence(__null
, 1049); __attribute__((nomerge)) ::abort(); } while (false);
} while (false)
1048 "ServiceWorker imported script redirected to an url "do { do { } while (false); MOZ_ReportCrash("" "ServiceWorker imported script redirected to an url "
"with an unexpected scheme", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1049); AnnotateMozCrashReason("MOZ_CRASH(" "ServiceWorker imported script redirected to an url "
"with an unexpected scheme" ")"); do { MOZ_CrashSequence(__null
, 1049); __attribute__((nomerge)) ::abort(); } while (false);
} while (false)
1049 "with an unexpected scheme")do { do { } while (false); MOZ_ReportCrash("" "ServiceWorker imported script redirected to an url "
"with an unexpected scheme", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1049); AnnotateMozCrashReason("MOZ_CRASH(" "ServiceWorker imported script redirected to an url "
"with an unexpected scheme" ")"); do { MOZ_CrashSequence(__null
, 1049); __attribute__((nomerge)) ::abort(); } while (false);
} while (false)
;
1050 return NS_ERROR_UNEXPECTED;
1051 }
1052
1053 bool requestSucceeded;
1054 rv = httpChannel->GetRequestSucceeded(&requestSucceeded);
1055 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1055)
) {
1056 return NS_OK;
1057 }
1058
1059 if (NS_WARN_IF(!requestSucceeded)NS_warn_if_impl(!requestSucceeded, "!requestSucceeded", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1059)
) {
1060 // Get the stringified numeric status code, not statusText which could be
1061 // something misleading like OK for a 404.
1062 uint32_t status = 0;
1063 (void)httpChannel->GetResponseStatus(
1064 &status); // don't care if this fails, use 0.
1065 nsAutoString statusAsText;
1066 statusAsText.AppendInt(status);
1067
1068 ServiceWorkerManager::LocalizeAndReportToAllClients(
1069 mRegistration->Scope(), "ServiceWorkerRegisterNetworkError",
1070 nsTArray<nsString>{NS_ConvertUTF8toUTF16(mRegistration->Scope()),
1071 std::move(statusAsText),
1072 NS_ConvertUTF8toUTF16(mURL)});
1073
1074 rv = NS_ERROR_FAILURE;
1075 return NS_OK;
1076 }
1077
1078 // Note: we explicitly don't check for the return value here, because the
1079 // absence of the header is not an error condition.
1080 (void)httpChannel->GetResponseHeader("Service-Worker-Allowed"_ns, mMaxScope);
1081
1082 // [9.2 Update]4.13, If response's cache state is not "local",
1083 // set registration's last update check time to the current time
1084 if (!mIsFromCache) {
1085 mRegistration->RefreshLastUpdateCheckTime();
1086 }
1087
1088 nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
1089 if (!JS::Prefs::experimental_import_text() ||
1090 (loadInfo->GetExternalContentPolicyType() !=
1091 ExtContentPolicyType::TYPE_TEXT)) {
1092 nsAutoCString mimeType;
1093 rv = httpChannel->GetContentType(mimeType);
1094 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1094)
) {
1095 // We should only end up here if !mResponseHead in the channel. If
1096 // headers were received but no content type was specified, we'll be given
1097 // UNKNOWN_CONTENT_TYPE "application/x-unknown-content-type" and so fall
1098 // into the next case with its better error message.
1099 rv = NS_ERROR_DOM_SECURITY_ERR;
1100 return rv;
1101 }
1102
1103 auto mimeTypeUTF16 = NS_ConvertUTF8toUTF16(mimeType);
1104 // The top-level service worker script must be served with a JavaScript
1105 // MIME type. JSON is only permitted for non-top-level (imported) modules,
1106 // such as `import data from "./x.json" with { type: "json" }`.
1107 if (mimeTypeUTF16.IsEmpty() ||
1108 !(nsContentUtils::IsJavascriptMIMEType(mimeTypeUTF16) ||
1109 (!mIsMainScript && nsContentUtils::IsJsonMimeType(mimeTypeUTF16)))) {
1110 ServiceWorkerManager::LocalizeAndReportToAllClients(
1111 mRegistration->Scope(), "ServiceWorkerRegisterMimeTypeError2",
1112 nsTArray<nsString>{NS_ConvertUTF8toUTF16(mRegistration->Scope()),
1113 std::move(mimeTypeUTF16),
1114 NS_ConvertUTF8toUTF16(mURL)});
1115 rv = NS_ERROR_DOM_SECURITY_ERR;
1116 return rv;
1117 }
1118 }
1119
1120 nsCOMPtr<nsIURI> channelURL;
1121 rv = httpChannel->GetURI(getter_AddRefs(channelURL));
1122 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1122)
) {
1123 return rv;
1124 }
1125
1126 // Append the final URL if its different from the original
1127 // request URL. This lets us note that a redirect occurred
1128 // even though we don't track every redirect URL here.
1129 MOZ_DIAGNOSTIC_ASSERT(!mURLList.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mURLList.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mURLList.IsEmpty()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mURLList.IsEmpty()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1129); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mURLList.IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 1129); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1130
1131 bool equals = false;
1132 if (NS_FAILED(channelURL->Equals(mURLList[0], &equals))((bool)(__builtin_expect(!!(NS_FAILED_impl(channelURL->Equals
(mURLList[0], &equals))), 0)))
|| !equals) {
1133 mURLList.AppendElement(WrapNotNull(channelURL.get()));
1134 }
1135
1136 UniquePtr<char16_t[], JS::FreePolicy> buffer;
1137 size_t len = 0;
1138
1139 rv = ScriptLoader::ConvertToUTF16(httpChannel, aString, aLen, u"UTF-8"_ns,
1140 nullptr, buffer, len);
1141 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1141)
) {
1142 return rv;
1143 }
1144
1145 mBuffer.Adopt(buffer.release(), len);
1146
1147 rv = NS_OK;
1148 return NS_OK;
1149}
1150
1151nsresult CompareCache::Initialize(Cache* const aCache, const nsACString& aURL) {
1152 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1152); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1153 MOZ_ASSERT(aCache)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCache)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aCache))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aCache", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1153); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCache" ")"
); do { MOZ_CrashSequence(__null, 1153); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1154 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForInitialization)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForInitialization)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == WaitingForInitialization
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForInitialization", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1154); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForInitialization"
")"); do { MOZ_CrashSequence(__null, 1154); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1155
1156 // This JSContext will not end up executing JS code because here there are
1157 // no ReadableStreams involved.
1158 AutoJSAPI jsapi;
1159 jsapi.Init();
1160
1161 RequestOrUTF8String request;
1162 request.SetAsUTF8String() = aURL;
1163 ErrorResult error;
1164 CacheQueryOptions params;
1165 RefPtr<Promise> promise = aCache->Match(jsapi.cx(), request, params, error);
1166 if (NS_WARN_IF(error.Failed())NS_warn_if_impl(error.Failed(), "error.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1166)
) {
1167 // No exception here because there are no ReadableStreams involved here.
1168 MOZ_ASSERT(!error.IsJSException())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!error.IsJSException())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!error.IsJSException()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!error.IsJSException()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1168); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!error.IsJSException()"
")"); do { MOZ_CrashSequence(__null, 1168); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1169 mState = Finished;
1170 return error.StealNSResult();
1171 }
1172
1173 // Retrieve the script from aCache.
1174 mState = WaitingForScript;
1175 promise->AppendNativeHandler(this);
1176 return NS_OK;
1177}
1178
1179void CompareCache::Finish(nsresult aStatus, bool aInCache) {
1180 if (mState != Finished) {
1181 mState = Finished;
1182 mInCache = aInCache;
1183 mCN->CacheFinish(aStatus);
1184 }
1185}
1186
1187void CompareCache::Abort() {
1188 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1188); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1189
1190 if (mState != Finished) {
1191 mState = Finished;
1192
1193 if (mPump) {
1194 mPump->CancelWithReason(NS_BINDING_ABORTED, "CompareCache::Abort"_ns);
1195 mPump = nullptr;
1196 }
1197 }
1198}
1199
1200NS_IMETHODIMPnsresult
1201CompareCache::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
1202 nsresult aStatus, uint32_t aLen,
1203 const uint8_t* aString) {
1204 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1204); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1204); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1205
1206 if (mState == Finished) {
1207 return aStatus;
1208 }
1209
1210 if (NS_WARN_IF(NS_FAILED(aStatus))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus
)), 0))), "NS_FAILED(aStatus)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1210)
) {
1211 Finish(aStatus, false);
1212 return aStatus;
1213 }
1214
1215 UniquePtr<char16_t[], JS::FreePolicy> buffer;
1216 size_t len = 0;
1217
1218 nsresult rv = ScriptLoader::ConvertToUTF16(nullptr, aString, aLen,
1219 u"UTF-8"_ns, nullptr, buffer, len);
1220 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1220)
) {
1221 Finish(rv, false);
1222 return rv;
1223 }
1224
1225 mBuffer.Adopt(buffer.release(), len);
1226
1227 Finish(NS_OK, true);
1228 return NS_OK;
1229}
1230
1231void CompareCache::ResolvedCallback(JSContext* aCx,
1232 JS::Handle<JS::Value> aValue,
1233 ErrorResult& aRv) {
1234 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1234); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1234); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1235
1236 switch (mState) {
1237 case Finished:
1238 return;
1239 case WaitingForScript:
1240 ManageValueResult(aCx, aValue);
1241 return;
1242 default:
1243 MOZ_CRASH("Unacceptable state.")do { do { } while (false); MOZ_ReportCrash("" "Unacceptable state."
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1243); AnnotateMozCrashReason("MOZ_CRASH(" "Unacceptable state."
")"); do { MOZ_CrashSequence(__null, 1243); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1244 }
1245}
1246
1247void CompareCache::RejectedCallback(JSContext* aCx,
1248 JS::Handle<JS::Value> aValue,
1249 ErrorResult& aRv) {
1250 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1250); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1251
1252 if (mState != Finished) {
1253 Finish(NS_ERROR_FAILURE, false);
1254 return;
1255 }
1256}
1257
1258void CompareCache::ManageValueResult(JSContext* aCx,
1259 JS::Handle<JS::Value> aValue) {
1260 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1260); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1260); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1261
1262 // The cache returns undefined if the object is not stored.
1263 if (aValue.isUndefined()) {
1264 Finish(NS_OK, false);
1265 return;
1266 }
1267
1268 MOZ_ASSERT(aValue.isObject())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aValue.isObject())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aValue.isObject()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("aValue.isObject()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1268); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aValue.isObject()"
")"); do { MOZ_CrashSequence(__null, 1268); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1269
1270 JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
1271 if (NS_WARN_IF(!obj)NS_warn_if_impl(!obj, "!obj", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1271)
) {
1272 Finish(NS_ERROR_FAILURE, false);
1273 return;
1274 }
1275
1276 Response* response = nullptr;
1277 nsresult rv = UNWRAP_OBJECT(Response, &obj, response)mozilla::dom::binding_detail::UnwrapObjectWithCrossOriginAsserts
< mozilla::dom::prototypes::id::Response, mozilla::dom::Response_Binding
::NativeType>(&obj, response)
;
1278 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1278)
) {
1279 Finish(rv, false);
1280 return;
1281 }
1282
1283 MOZ_ASSERT(response->Ok())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(response->Ok())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(response->Ok()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("response->Ok()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1283); AnnotateMozCrashReason("MOZ_ASSERT" "(" "response->Ok()"
")"); do { MOZ_CrashSequence(__null, 1283); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1284
1285 nsCOMPtr<nsIInputStream> inputStream;
1286 response->GetBody(getter_AddRefs(inputStream));
1287 MOZ_ASSERT(inputStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(inputStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(inputStream))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("inputStream", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1287); AnnotateMozCrashReason("MOZ_ASSERT" "(" "inputStream"
")"); do { MOZ_CrashSequence(__null, 1287); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1288
1289 MOZ_ASSERT(!mPump)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPump)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(!mPump))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mPump", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1289); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPump" ")"
); do { MOZ_CrashSequence(__null, 1289); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1290 rv = NS_NewInputStreamPump(getter_AddRefs(mPump), inputStream.forget(),
1291 0, /* default segsize */
1292 0, /* default segcount */
1293 false, /* default closeWhenDone */
1294 GetMainThreadSerialEventTarget());
1295 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1295)
) {
1296 Finish(rv, false);
1297 return;
1298 }
1299
1300 nsCOMPtr<nsIStreamLoader> loader;
1301 rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
1302 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1302)
) {
1303 Finish(rv, false);
1304 return;
1305 }
1306
1307 rv = mPump->AsyncRead(loader);
1308 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1308)
) {
1309 mPump = nullptr;
1310 Finish(rv, false);
1311 return;
1312 }
1313
1314 nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(mPump);
1315 if (rr) {
1316 nsCOMPtr<nsIEventTarget> sts =
1317 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
1318 RefPtr<TaskQueue> queue =
1319 TaskQueue::Create(sts.forget(), "CompareCache STS Delivery Queue");
1320 rv = rr->RetargetDeliveryTo(queue);
1321 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1321)
) {
1322 mPump = nullptr;
1323 Finish(rv, false);
1324 return;
1325 }
1326 }
1327}
1328
1329nsresult CompareManager::Initialize(nsIPrincipal* aPrincipal,
1330 const nsACString& aURL,
1331 const nsAString& aCacheName) {
1332 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1332); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1332); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1333 MOZ_ASSERT(aPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPrincipal))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aPrincipal", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPrincipal"
")"); do { MOZ_CrashSequence(__null, 1333); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1334 MOZ_ASSERT(mPendingCount == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPendingCount == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPendingCount == 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mPendingCount == 0"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1334); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPendingCount == 0"
")"); do { MOZ_CrashSequence(__null, 1334); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1335 MOZ_DIAGNOSTIC_ASSERT(mState == WaitingForInitialization)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mState == WaitingForInitialization)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mState == WaitingForInitialization
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mState == WaitingForInitialization", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1335); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mState == WaitingForInitialization"
")"); do { MOZ_CrashSequence(__null, 1335); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1336
1337 // RAII Cleanup when fails.
1338 auto guard = MakeScopeExit([&] { Cleanup(); });
1339
1340 mURL = aURL;
1341 mPrincipal = aPrincipal;
1342
1343 // Always create a CacheStorage since we want to write the network entry to
1344 // the cache even if there isn't an existing one.
1345 AutoJSAPI jsapi;
1346 jsapi.Init();
1347 ErrorResult result;
1348 mCacheStorage = CreateCacheStorage(jsapi.cx(), aPrincipal, result);
1349 if (NS_WARN_IF(result.Failed())NS_warn_if_impl(result.Failed(), "result.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1349)
) {
1350 MOZ_ASSERT(!result.IsErrorWithMessage())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!result.IsErrorWithMessage())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!result.IsErrorWithMessage()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!result.IsErrorWithMessage()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!result.IsErrorWithMessage()"
")"); do { MOZ_CrashSequence(__null, 1350); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1351 return result.StealNSResult();
1352 }
1353
1354 // If there is no existing cache, proceed to fetch the script directly.
1355 if (aCacheName.IsEmpty()) {
1356 mState = WaitingForScriptOrComparisonResult;
1357 nsresult rv = FetchScript(aURL, true /* aIsMainScript */);
1358 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1358)
) {
1359 return rv;
1360 }
1361
1362 guard.release();
1363 return NS_OK;
1364 }
1365
1366 // Open the cache saving the old source scripts.
1367 RefPtr<Promise> promise = mCacheStorage->Open(aCacheName, result);
1368 if (NS_WARN_IF(result.Failed())NS_warn_if_impl(result.Failed(), "result.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1368)
) {
1369 MOZ_ASSERT(!result.IsErrorWithMessage())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!result.IsErrorWithMessage())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!result.IsErrorWithMessage()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!result.IsErrorWithMessage()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1369); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!result.IsErrorWithMessage()"
")"); do { MOZ_CrashSequence(__null, 1369); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1370 return result.StealNSResult();
1371 }
1372
1373 mState = WaitingForExistingOpen;
1374 promise->AppendNativeHandler(this);
1375
1376 guard.release();
1377 return NS_OK;
1378}
1379
1380// This class manages 4 promises if needed:
1381// 1. Retrieve the Cache object by a given CacheName of OldCache.
1382// 2. Retrieve the URLs saved in OldCache.
1383// 3. Retrieve the Cache object of the NewCache for the newly created SW.
1384// 4. Put the value in the cache.
1385// For this reason we have mState to know what callback we are handling.
1386void CompareManager::ResolvedCallback(JSContext* aCx,
1387 JS::Handle<JS::Value> aValue,
1388 ErrorResult& aRv) {
1389 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1389); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1389); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1390 MOZ_ASSERT(mCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCallback", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1390); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCallback" ")"
); do { MOZ_CrashSequence(__null, 1390); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1391
1392 switch (mState) {
1393 case Finished:
1394 return;
1395 case WaitingForExistingOpen:
1396 ManageOldCache(aCx, aValue);
1397 return;
1398 case WaitingForExistingKeys:
1399 ManageOldKeys(aCx, aValue);
1400 return;
1401 case WaitingForOpen:
1402 ManageNewCache(aCx, aValue);
1403 return;
1404 case WaitingForPut:
1405 MOZ_DIAGNOSTIC_ASSERT(mPendingCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPendingCount > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPendingCount > 0))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mPendingCount > 0"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1405); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mPendingCount > 0"
")"); do { MOZ_CrashSequence(__null, 1405); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1406 if (--mPendingCount == 0) {
1407 mCallback->ComparisonResult(NS_OK, false /* aIsEqual */, mOnFailure,
1408 mNewCacheName, mMaxScope, mLoadFlags);
1409 Cleanup();
1410 }
1411 return;
1412 default:
1413 MOZ_DIAGNOSTIC_CRASH("Missing case in CompareManager::ResolvedCallback")do { do { } while (false); MOZ_ReportCrash("" "Missing case in CompareManager::ResolvedCallback"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1413); AnnotateMozCrashReason("MOZ_CRASH(" "Missing case in CompareManager::ResolvedCallback"
")"); do { MOZ_CrashSequence(__null, 1413); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1414 }
1415}
1416
1417void CompareManager::RejectedCallback(JSContext* aCx,
1418 JS::Handle<JS::Value> aValue,
1419 ErrorResult& aRv) {
1420 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1420); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1420); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1421 switch (mState) {
1422 case Finished:
1423 return;
1424 case WaitingForExistingOpen:
1425 NS_WARNING("Could not open the existing cache.")NS_DebugBreak(NS_DEBUG_WARNING, "Could not open the existing cache."
, nullptr, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1425)
;
1426 break;
1427 case WaitingForExistingKeys:
1428 NS_WARNING("Could not get the existing URLs.")NS_DebugBreak(NS_DEBUG_WARNING, "Could not get the existing URLs."
, nullptr, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1428)
;
1429 break;
1430 case WaitingForOpen:
1431 NS_WARNING("Could not open cache.")NS_DebugBreak(NS_DEBUG_WARNING, "Could not open cache.", nullptr
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1431)
;
1432 break;
1433 case WaitingForPut:
1434 NS_WARNING("Could not write to cache.")NS_DebugBreak(NS_DEBUG_WARNING, "Could not write to cache.", nullptr
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1434)
;
1435 break;
1436 default:
1437 MOZ_DIAGNOSTIC_CRASH("Missing case in CompareManager::RejectedCallback")do { do { } while (false); MOZ_ReportCrash("" "Missing case in CompareManager::RejectedCallback"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1437); AnnotateMozCrashReason("MOZ_CRASH(" "Missing case in CompareManager::RejectedCallback"
")"); do { MOZ_CrashSequence(__null, 1437); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1438 }
1439
1440 Fail(NS_ERROR_FAILURE);
1441}
1442
1443void CompareManager::Fail(nsresult aStatus) {
1444 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1444); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1444); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1445 mCallback->ComparisonResult(aStatus, false /* aIsEqual */, mOnFailure, u""_ns,
1446 ""_ns, mLoadFlags);
1447 Cleanup();
1448}
1449
1450void CompareManager::Cleanup() {
1451 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1451); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1451); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1452
1453 if (mState != Finished) {
1454 mState = Finished;
1455
1456 MOZ_ASSERT(mCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCallback", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1456); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCallback" ")"
); do { MOZ_CrashSequence(__null, 1456); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1457 mCallback = nullptr;
1458
1459 // Abort and release CompareNetworks.
1460 for (uint32_t i = 0; i < mCNList.Length(); ++i) {
1461 mCNList[i]->Abort();
1462 }
1463 mCNList.Clear();
1464 }
1465}
1466
1467} // namespace
1468
1469nsresult PurgeCache(nsIPrincipal* aPrincipal, const nsAString& aCacheName) {
1470 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1470); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1470); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1471 MOZ_ASSERT(aPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPrincipal))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aPrincipal", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1471); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPrincipal"
")"); do { MOZ_CrashSequence(__null, 1471); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1472
1473 if (aCacheName.IsEmpty()) {
1474 return NS_OK;
1475 }
1476
1477 AutoJSAPI jsapi;
1478 jsapi.Init();
1479 ErrorResult rv;
1480 RefPtr<CacheStorage> cacheStorage =
1481 CreateCacheStorage(jsapi.cx(), aPrincipal, rv);
1482 if (NS_WARN_IF(rv.Failed())NS_warn_if_impl(rv.Failed(), "rv.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1482)
) {
1483 return rv.StealNSResult();
1484 }
1485
1486 // We use the ServiceWorker scope as key for the cacheStorage.
1487 RefPtr<Promise> promise = cacheStorage->Delete(aCacheName, rv);
1488 if (NS_WARN_IF(rv.Failed())NS_warn_if_impl(rv.Failed(), "rv.Failed()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1488)
) {
1489 return rv.StealNSResult();
1490 }
1491
1492 // Set [[PromiseIsHandled]] to ensure that if this promise gets rejected,
1493 // we don't end up reporting a rejected promise to the console.
1494 MOZ_ALWAYS_TRUE(promise->SetAnyPromiseIsHandled())do { if ((__builtin_expect(!!(promise->SetAnyPromiseIsHandled
()), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "promise->SetAnyPromiseIsHandled()", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1494); AnnotateMozCrashReason("MOZ_CRASH(" "promise->SetAnyPromiseIsHandled()"
")"); do { MOZ_CrashSequence(__null, 1494); __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1495
1496 // We don't actually care about the result of the delete operation.
1497 return NS_OK;
1498}
1499
1500nsresult GenerateCacheName(nsAString& aName) {
1501 nsresult rv;
1502 nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
1503 do_GetService("@mozilla.org/uuid-generator;1", &rv);
1504 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1504)
) {
1505 return rv;
1506 }
1507
1508 nsID id;
1509 rv = uuidGenerator->GenerateUUIDInPlace(&id);
1510 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1510)
) {
1511 return rv;
1512 }
1513
1514 char chars[NSID_LENGTH39];
1515 id.ToProvidedString(chars);
1516
1517 // NSID_LENGTH counts the null terminator.
1518 aName.AssignASCII(chars, NSID_LENGTH39 - 1);
1519
1520 return NS_OK;
1521}
1522
1523nsresult Compare(ServiceWorkerRegistrationInfo* aRegistration,
1524 nsIPrincipal* aPrincipal, const nsAString& aCacheName,
1525 const nsACString& aURL, CompareCallback* aCallback) {
1526 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()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1526); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { MOZ_CrashSequence(__null, 1526); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1527 MOZ_ASSERT(aRegistration)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRegistration)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRegistration))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRegistration",
"./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1527); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRegistration"
")"); do { MOZ_CrashSequence(__null, 1527); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1528 MOZ_ASSERT(aPrincipal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPrincipal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPrincipal))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aPrincipal", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1528); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPrincipal"
")"); do { MOZ_CrashSequence(__null, 1528); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1529 MOZ_ASSERT(!aURL.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aURL.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aURL.IsEmpty()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!aURL.IsEmpty()"
, "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1529); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aURL.IsEmpty()"
")"); do { MOZ_CrashSequence(__null, 1529); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1530 MOZ_ASSERT(aCallback)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCallback)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aCallback))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aCallback", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1530); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCallback" ")"
); do { MOZ_CrashSequence(__null, 1530); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1531
1532 RefPtr<CompareManager> cm = new CompareManager(aRegistration, aCallback);
1533
1534 nsresult rv = cm->Initialize(aPrincipal, aURL, aCacheName);
1535 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../dom/serviceworkers/ServiceWorkerScriptCache.cpp"
, 1535)
) {
1536 return rv;
1537 }
1538
1539 return NS_OK;
1540}
1541
1542} // namespace mozilla::dom::serviceWorkerScriptCache