/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WorkerCSPEventListener.h" #include "WorkerRef.h" #include "WorkerRunnable.h" #include "WorkerScope.h" #include "mozilla/dom/SecurityPolicyViolationEvent.h" #include "mozilla/dom/SecurityPolicyViolationEventBinding.h" #include "mozilla/dom/WorkerRunnable.h" using namespace mozilla::dom; namespace { class WorkerCSPEventRunnable final : public MainThreadWorkerRunnable { public: WorkerCSPEventRunnable(WorkerPrivate* aWorkerPrivate, const nsAString& aJSON) : MainThreadWorkerRunnable(aWorkerPrivate), mJSON(aJSON) {} private: bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { SecurityPolicyViolationEventInit violationEventInit; if (NS_WARN_IF(!violationEventInit.Init(mJSON))) { return true; } RefPtr event = mozilla::dom::SecurityPolicyViolationEvent::Constructor( aWorkerPrivate->GlobalScope(), u"securitypolicyviolation"_ns, violationEventInit); event->SetTrusted(true); aWorkerPrivate->GlobalScope()->DispatchEvent(*event); return true; } const nsString mJSON; }; } // namespace NS_IMPL_ISUPPORTS(WorkerCSPEventListener, nsICSPEventListener) /* static */ already_AddRefed WorkerCSPEventListener::Create( WorkerPrivate* aWorkerPrivate) { MOZ_ASSERT(aWorkerPrivate); aWorkerPrivate->AssertIsOnWorkerThread(); RefPtr listener = new WorkerCSPEventListener(); MutexAutoLock lock(listener->mMutex); listener->mWorkerRef = WeakWorkerRef::Create(aWorkerPrivate, [listener]() { MutexAutoLock lock(listener->mMutex); listener->mWorkerRef = nullptr; }); if (NS_WARN_IF(!listener->mWorkerRef)) { return nullptr; } return listener.forget(); } WorkerCSPEventListener::WorkerCSPEventListener() : mMutex("WorkerCSPEventListener::mMutex") {} NS_IMETHODIMP WorkerCSPEventListener::OnCSPViolationEvent(const nsAString& aJSON) { MutexAutoLock lock(mMutex); if (!mWorkerRef) { return NS_OK; } WorkerPrivate* workerPrivate = mWorkerRef->GetUnsafePrivate(); MOZ_ASSERT(workerPrivate); if (NS_IsMainThread()) { RefPtr runnable = new WorkerCSPEventRunnable(workerPrivate, aJSON); runnable->Dispatch(); return NS_OK; } SecurityPolicyViolationEventInit violationEventInit; if (NS_WARN_IF(!violationEventInit.Init(aJSON))) { return NS_ERROR_UNEXPECTED; } RefPtr event = mozilla::dom::SecurityPolicyViolationEvent::Constructor( workerPrivate->GlobalScope(), u"securitypolicyviolation"_ns, violationEventInit); event->SetTrusted(true); workerPrivate->GlobalScope()->DispatchEvent(*event); return NS_OK; }