зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1472303 - Block self-update from top level scripts. r=asuth
Differential Revision: https://phabricator.services.mozilla.com/D3221 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6ff3b886ac
Коммит
1f4f71fbc2
|
@ -222,6 +222,17 @@ ServiceWorkerRegistration::Update(ErrorResult& aRv)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (RefPtr<ServiceWorkerGlobalScope> serviceWorkerGlobal =
|
||||
do_QueryObject(global)) {
|
||||
WorkerPrivate* wp;
|
||||
if (serviceWorkerGlobal->Registration() == this &&
|
||||
(wp = GetCurrentThreadWorkerPrivate()) &&
|
||||
wp->IsLoadingWorkerScript()) {
|
||||
outer->MaybeResolve(*this);
|
||||
return outer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerRegistration> self = this;
|
||||
|
||||
mPendingUpdatePromises += 1;
|
||||
|
|
|
@ -826,13 +826,8 @@ ServiceWorkerRegistrationWorkerThread::Update(ServiceWorkerRegistrationCallback&
|
|||
return;
|
||||
}
|
||||
|
||||
// Avoid infinite update loops by ignoring update() calls during top
|
||||
// level script evaluation. See:
|
||||
// https://github.com/slightlyoff/ServiceWorker/issues/800
|
||||
if (workerRef->Private()->IsLoadingWorkerScript()) {
|
||||
aSuccessCB(mDescriptor);
|
||||
return;
|
||||
}
|
||||
// This is ensured by the binding layer.
|
||||
MOZ_ASSERT(!workerRef->Private()->IsLoadingWorkerScript());
|
||||
|
||||
auto promise = MakeRefPtr<ServiceWorkerRegistrationPromise::Private>(__func__);
|
||||
auto holder =
|
||||
|
|
|
@ -677,6 +677,7 @@ SharedWorkerGlobalScope::Close()
|
|||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope,
|
||||
mClients, mRegistration)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerGlobalScope)
|
||||
NS_INTERFACE_MAP_ENTRY_CONCRETE(ServiceWorkerGlobalScope)
|
||||
NS_INTERFACE_MAP_END_INHERITING(WorkerGlobalScope)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope)
|
||||
|
|
|
@ -302,6 +302,9 @@ public:
|
|||
IMPL_EVENT_HANDLER(connect)
|
||||
};
|
||||
|
||||
#define NS_DOM_SERVICEWORKERGLOBALSCOPE_IID \
|
||||
{0x552bfa7e, 0x0dd5, 0x4e94, {0xa0, 0x43, 0xff, 0x34, 0x6b, 0x6e, 0x04, 0x46}}
|
||||
|
||||
class ServiceWorkerGlobalScope final : public WorkerGlobalScope
|
||||
{
|
||||
const nsString mScope;
|
||||
|
@ -311,6 +314,7 @@ class ServiceWorkerGlobalScope final : public WorkerGlobalScope
|
|||
~ServiceWorkerGlobalScope();
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKERGLOBALSCOPE_IID)
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
|
||||
WorkerGlobalScope)
|
||||
|
@ -355,6 +359,8 @@ public:
|
|||
void EventListenerAdded(nsAtom* aType) override;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorkerGlobalScope, NS_DOM_SERVICEWORKERGLOBALSCOPE_IID)
|
||||
|
||||
class WorkerDebuggerGlobalScope final : public DOMEventTargetHelper,
|
||||
public nsIGlobalObject
|
||||
{
|
||||
|
|
|
@ -300159,6 +300159,11 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"service-workers/service-worker/resources/update-top-level-worker.py": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"service-workers/service-worker/resources/update-worker.py": [
|
||||
[
|
||||
{}
|
||||
|
@ -390350,6 +390355,12 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"service-workers/service-worker/update-top-level.https.html": [
|
||||
[
|
||||
"/service-workers/service-worker/update-top-level.https.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"service-workers/service-worker/update.https.html": [
|
||||
[
|
||||
"/service-workers/service-worker/update.https.html",
|
||||
|
@ -632137,6 +632148,10 @@
|
|||
"8aaa5ca934457714ee0e529ad4b2b1740d9758dd",
|
||||
"support"
|
||||
],
|
||||
"service-workers/service-worker/resources/update-top-level-worker.py": [
|
||||
"f77ef284ac0745bd6d31e642742438766f14e32e",
|
||||
"support"
|
||||
],
|
||||
"service-workers/service-worker/resources/update-worker.py": [
|
||||
"bc9b32ad3e68870d9f540524e70cd7947346e5c8",
|
||||
"support"
|
||||
|
@ -632317,6 +632332,10 @@
|
|||
"d8ed94f776650c8a40ba82df9ca5e909b460bb79",
|
||||
"testharness"
|
||||
],
|
||||
"service-workers/service-worker/update-top-level.https.html": [
|
||||
"1f0bdff65597832c7e3ba27c37681b760decf456",
|
||||
"testharness"
|
||||
],
|
||||
"service-workers/service-worker/update.https.html": [
|
||||
"6717d4d7ac289c8a18b1500e21795fd16c5321e7",
|
||||
"testharness"
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import time
|
||||
|
||||
def main(request, response):
|
||||
# no-cache itself to ensure the user agent finds a new version for each update.
|
||||
headers = [('Cache-Control', 'no-cache, must-revalidate'),
|
||||
('Pragma', 'no-cache')]
|
||||
content_type = 'application/javascript'
|
||||
|
||||
headers.append(('Content-Type', content_type))
|
||||
|
||||
body = '''
|
||||
let promise = self.registration.update()
|
||||
onmessage = (evt) => {
|
||||
promise.then(r => {
|
||||
evt.source.postMessage(self.registration === r ? 'PASS' : 'FAIL');
|
||||
});
|
||||
};'''
|
||||
return headers, '/* %s %s */ %s' % (time.time(), time.clock(), body)
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Registration update()</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
function wait_for_message() {
|
||||
return new Promise(resolve => {
|
||||
navigator.serviceWorker.addEventListener("message",
|
||||
e => {
|
||||
resolve(e.data);
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
const script = './resources/update-top-level-worker.py';
|
||||
const scope = './resources/empty.html?update-result';
|
||||
|
||||
let reg = await navigator.serviceWorker.register(script, { scope });
|
||||
t.add_cleanup(async _ => await reg.unregister());
|
||||
await wait_for_state(t, reg.installing, 'activated');
|
||||
|
||||
reg.addEventListener("updatefound",
|
||||
() => assert_unreached("shouldn't find an update"));
|
||||
|
||||
reg.active.postMessage("ping");
|
||||
assert_equals(await wait_for_message(), 'PASS', 'did not hang');
|
||||
}, 'A serviceworker with a top-level update should not hang');
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче