Skip to content

Commit

Permalink
Bug 1453339 - Make it harder to mess up Promise::All. r=peterv, a=RyanVM
Browse files Browse the repository at this point in the history
MozReview-Commit-ID: UO4wssYHj7
  • Loading branch information
bzbarsky authored and wolfbeast committed Apr 19, 2018
1 parent ddbe089 commit 3b4a815
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 35 deletions.
2 changes: 1 addition & 1 deletion dom/cache/Cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ Cache::AddAll(const GlobalObject& aGlobal,
new FetchHandler(mActor->GetWorkerHolder(), this,
Move(aRequestList), promise);

RefPtr<Promise> fetchPromise = Promise::All(aGlobal, fetchList, aRv);
RefPtr<Promise> fetchPromise = Promise::All(aGlobal.Context(), fetchList, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
Expand Down
27 changes: 15 additions & 12 deletions dom/promise/Promise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,37 +561,40 @@ Promise::Reject(nsIGlobalObject* aGlobal, JSContext* aCx,

// static
already_AddRefed<Promise>
Promise::All(const GlobalObject& aGlobal,
Promise::All(JSContext* aCx,
const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global;
global = do_QueryInterface(aGlobal.GetAsSupports());
if (!global) {
JS::Rooted<JSObject*> globalObj(aCx, JS::CurrentGlobalOrNull(aCx));
if (!globalObj) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}

JSContext* cx = aGlobal.Context();
nsCOMPtr<nsIGlobalObject> global = xpc::NativeGlobal(globalObj);
if (!global) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}

JS::AutoObjectVector promises(cx);
JS::AutoObjectVector promises(aCx);
if (!promises.reserve(aPromiseList.Length())) {
aRv.NoteJSContextException(cx);
aRv.NoteJSContextException(aCx);
return nullptr;
}

for (auto& promise : aPromiseList) {
JS::Rooted<JSObject*> promiseObj(cx, promise->PromiseObj());
JS::Rooted<JSObject*> promiseObj(aCx, promise->PromiseObj());
// Just in case, make sure these are all in the context compartment.
if (!JS_WrapObject(cx, &promiseObj)) {
aRv.NoteJSContextException(cx);
if (!JS_WrapObject(aCx, &promiseObj)) {
aRv.NoteJSContextException(aCx);
return nullptr;
}
promises.infallibleAppend(promiseObj);
}

JS::Rooted<JSObject*> result(cx, JS::GetWaitForAllPromise(cx, promises));
JS::Rooted<JSObject*> result(aCx, JS::GetWaitForAllPromise(aCx, promises));
if (!result) {
aRv.NoteJSContextException(cx);
aRv.NoteJSContextException(aCx);
return nullptr;
}

Expand Down
19 changes: 11 additions & 8 deletions dom/promise/Promise.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,23 +188,26 @@ class Promise : public nsISupports,
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aWrapper);

// Do the equivalent of Promise.resolve in the current compartment of aCx.
// Errorrs are reported on the ErrorResult; if aRv comes back !Failed(), this
// function MUST return a non-null value.
// Do the equivalent of Promise.resolve in the compartment of aGlobal. The
// compartment of aCx is ignored. Errors are reported on the ErrorResult; if
// aRv comes back !Failed(), this function MUST return a non-null value.
static already_AddRefed<Promise>
Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);

// Do the equivalent of Promise.reject in the current compartment of aCx.
// Errorrs are reported on the ErrorResult; if aRv comes back !Failed(), this
// function MUST return a non-null value.
// Do the equivalent of Promise.reject in the compartment of aGlobal. The
// compartment of aCx is ignored. Errors are reported on the ErrorResult; if
// aRv comes back !Failed(), this function MUST return a non-null value.
static already_AddRefed<Promise>
Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);

// Do the equivalent of Promise.all in the current compartment of aCx. Errors
// are reported on the ErrorResult; if aRv comes back !Failed(), this function
// MUST return a non-null value.
static already_AddRefed<Promise>
All(const GlobalObject& aGlobal,
const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv);
All(JSContext* aCx, const nsTArray<RefPtr<Promise>>& aPromiseList,
ErrorResult& aRv);

void
Then(JSContext* aCx,
Expand Down
4 changes: 1 addition & 3 deletions dom/workers/ServiceWorkerEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,10 +948,8 @@ ExtendableEvent::GetPromise()
}
JSContext* cx = jsapi.cx();

GlobalObject global(cx, globalObj->GetGlobalJSObject());

ErrorResult result;
RefPtr<Promise> p = Promise::All(global, Move(mPromises), result);
RefPtr<Promise> p = Promise::All(cx, Move(mPromises), result);
if (NS_WARN_IF(result.MaybeSetPendingException(cx))) {
return nullptr;
}
Expand Down
12 changes: 1 addition & 11 deletions layout/style/FontFaceSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,17 +343,7 @@ FontFaceSet::Load(JSContext* aCx,
}
}

nsIGlobalObject* globalObject = GetParentObject();
if (!globalObject) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}

JS::Rooted<JSObject*> jsGlobal(aCx, globalObject->GetGlobalJSObject());
GlobalObject global(aCx, jsGlobal);

RefPtr<Promise> result = Promise::All(global, promises, aRv);
return result.forget();
return Promise::All(aCx, promises, aRv);
}

bool
Expand Down

0 comments on commit 3b4a815

Please sign in to comment.