Bug 1613900 - P3 - ServiceWorker should treat all failures after deserializing as deserialization failures; r=dom-workers-and-storage-reviewers,perry

Differential Revision: https://phabricator.services.mozilla.com/D62881

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tom Tung 2020-02-14 21:23:28 +00:00
parent 0e080c84cd
commit 2577a8c2b7
4 changed files with 18 additions and 17 deletions

View File

@ -687,12 +687,14 @@ void ServiceWorkerContainer::DispatchMessage(RefPtr<ReceivedMessage> aMessage) {
ErrorResult result;
bool deserializationFailed = false;
RootedDictionary<MessageEventInit> init(aCx);
if (!FillInMessageEventInit(aCx, aGlobal, *message, init, result)) {
deserializationFailed = result.ErrorCodeIs(NS_ERROR_DOM_DATA_CLONE_ERR);
auto res = FillInMessageEventInit(aCx, aGlobal, *message, init, result);
if (res.isErr()) {
deserializationFailed = res.unwrapErr();
MOZ_ASSERT_IF(deserializationFailed, init.mData.isNull());
MOZ_ASSERT_IF(deserializationFailed, init.mPorts.IsEmpty());
MOZ_ASSERT_IF(deserializationFailed, !init.mOrigin.IsEmpty());
MOZ_ASSERT_IF(deserializationFailed, !init.mSource.IsNull());
result.SuppressException();
if (!deserializationFailed && result.MaybeSetPendingException(aCx)) {
return;
@ -766,7 +768,7 @@ already_AddRefed<ServiceWorker> GetOrCreateServiceWorkerWithoutWarnings(
} // namespace
bool ServiceWorkerContainer::FillInMessageEventInit(
Result<Ok, bool> ServiceWorkerContainer::FillInMessageEventInit(
JSContext* const aCx, nsIGlobalObject* const aGlobal,
ReceivedMessage& aMessage, MessageEventInit& aInit, ErrorResult& aRv) {
// Determining the source and origin should preceed attempting deserialization
@ -787,23 +789,23 @@ bool ServiceWorkerContainer::FillInMessageEventInit(
const nsresult rv =
FillInOriginNoSuffix(aMessage.mServiceWorker, aInit.mOrigin);
if (NS_FAILED(rv)) {
return false;
return Err(false);
}
JS::Rooted<JS::Value> messageData(aCx);
aMessage.mClonedData.Read(aCx, &messageData, aRv);
if (aRv.Failed()) {
return false;
return Err(true);
}
aInit.mData = messageData;
if (!aMessage.mClonedData.TakeTransferredPortsAsSequence(aInit.mPorts)) {
xpc::Throw(aCx, NS_ERROR_OUT_OF_MEMORY);
return false;
return Err(false);
}
return true;
return Ok();
}
} // namespace dom

View File

@ -139,9 +139,13 @@ class ServiceWorkerContainer final : public DOMEventTargetHelper {
void DispatchMessage(RefPtr<ReceivedMessage> aMessage);
static bool FillInMessageEventInit(JSContext* aCx, nsIGlobalObject* aGlobal,
ReceivedMessage& aMessage,
MessageEventInit& aInit, ErrorResult& aRv);
// When it fails, returning boolean means whether it's because deserailization
// failed or not.
static Result<Ok, bool> FillInMessageEventInit(JSContext* aCx,
nsIGlobalObject* aGlobal,
ReceivedMessage& aMessage,
MessageEventInit& aInit,
ErrorResult& aRv);
RefPtr<Inner> mInner;

View File

@ -954,12 +954,7 @@ class MessageEventOp final : public ExtendableEventOp {
mData->Read(aCx, &messageData, rv);
// If deserialization fails, we will fire a messageerror event
bool deserializationFailed = rv.ErrorCodeIs(NS_ERROR_DOM_DATA_CLONE_ERR);
if (!deserializationFailed && NS_WARN_IF(rv.Failed())) {
RejectAll(rv.StealNSResult());
return true;
}
const bool deserializationFailed = rv.Failed();
Sequence<OwningNonNull<MessagePort>> ports;
if (!mData->TakeTransferredPortsAsSequence(ports)) {

View File

@ -473,7 +473,7 @@ class SendMessageEventRunnable final : public ExtendableEventWorkerRunnable {
mData->Read(aCx, &messageData, rv);
// If deserialization fails, we will fire a messageerror event
bool deserializationFailed = rv.ErrorCodeIs(NS_ERROR_DOM_DATA_CLONE_ERR);
bool deserializationFailed = rv.Failed();
if (!deserializationFailed && NS_WARN_IF(rv.Failed())) {
rv.SuppressException();