Bug 1589545 - Don't pass a CCW to AutoRealm in streams code, when processing pull/cancel functionality. r=arai,jorendorff
authorJeff Walden <jwalden@mit.edu>
Sat, 02 Nov 2019 00:28:49 +0000
changeset 500245 bcec42277f525ea7c05781bd3501a7f6eb47770f
parent 500244 d1efd0d79046c473ffe2d4a78210e51c20beb07f
child 500246 d32c29eed6a51d74b138f532b0a27e483d040aad
push id114164
push useraiakab@mozilla.com
push dateTue, 05 Nov 2019 10:06:15 +0000
treeherdermozilla-inbound@4d585c7edc76 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai, jorendorff
bugs1589545
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1589545 - Don't pass a CCW to AutoRealm in streams code, when processing pull/cancel functionality. r=arai,jorendorff Differential Revision: https://phabricator.services.mozilla.com/D49694
js/src/builtin/streams/ReadableStreamDefaultController.cpp
js/src/builtin/streams/ReadableStreamDefaultControllerOperations.cpp
--- a/js/src/builtin/streams/ReadableStreamDefaultController.cpp
+++ b/js/src/builtin/streams/ReadableStreamDefaultController.cpp
@@ -332,18 +332,18 @@ MOZ_MUST_USE JSObject* js::ReadableStrea
         return nullptr;
       }
 
       // Step b: Set firstDescriptor.[[bytesFilled]] to 0.
       unwrappedDescriptor->setBytesFilled(0);
     }
   }
 
-  Rooted<Value> unwrappedUnderlyingSource(cx);
-  unwrappedUnderlyingSource = unwrappedController->underlyingSource();
+  Rooted<Value> unwrappedUnderlyingSource(
+      cx, unwrappedController->underlyingSource());
 
   // Step 1 of 3.9.5.1, step 2 of 3.11.5.1: Perform ! ResetQueue(this).
   if (!ResetQueue(cx, unwrappedController)) {
     return nullptr;
   }
 
   // Step 2 of 3.9.5.1, step 3 of 3.11.5.1: Let result be the result of
   //     performing this.[[cancelAlgorithm]], passing reason.
@@ -392,30 +392,32 @@ MOZ_MUST_USE JSObject* js::ReadableStrea
     Rooted<Value> unwrappedCancelMethod(cx,
                                         unwrappedController->cancelMethod());
     if (unwrappedCancelMethod.isUndefined()) {
       // CreateAlgorithmFromUnderlyingMethod step 7.
       result = PromiseObject::unforgeableResolve(cx, UndefinedHandleValue);
     } else {
       // CreateAlgorithmFromUnderlyingMethod steps 6.c.i-ii.
       {
-        AutoRealm ar(cx, &unwrappedCancelMethod.toObject());
-        Rooted<Value> underlyingSource(cx, unwrappedUnderlyingSource);
-        if (!cx->compartment()->wrap(cx, &underlyingSource)) {
-          return nullptr;
-        }
+        AutoRealm ar(cx, unwrappedController);
+
+        // |unwrappedCancelMethod| and |unwrappedUnderlyingSource| come directly
+        // from |unwrappedController| slots so must be same-compartment with it.
+        cx->check(unwrappedCancelMethod);
+        cx->check(unwrappedUnderlyingSource);
+
         Rooted<Value> wrappedReason(cx, reason);
         if (!cx->compartment()->wrap(cx, &wrappedReason)) {
           return nullptr;
         }
 
         // If PromiseCall fails, don't bail out until after the
         // ReadableStreamControllerClearAlgorithms call below.
-        result = PromiseCall(cx, unwrappedCancelMethod, underlyingSource,
-                             wrappedReason);
+        result = PromiseCall(cx, unwrappedCancelMethod,
+                             unwrappedUnderlyingSource, wrappedReason);
       }
       if (!cx->compartment()->wrap(cx, &result)) {
         result = nullptr;
       }
     }
   }
 
   // Step 3 (or 4): Perform
--- a/js/src/builtin/streams/ReadableStreamDefaultControllerOperations.cpp
+++ b/js/src/builtin/streams/ReadableStreamDefaultControllerOperations.cpp
@@ -194,27 +194,28 @@ MOZ_MUST_USE bool js::ReadableStreamCont
     // SetUpReadableStreamDefaultControllerFromUnderlyingSource step 4.
     Rooted<Value> unwrappedPullMethod(cx, unwrappedController->pullMethod());
     if (unwrappedPullMethod.isUndefined()) {
       // CreateAlgorithmFromUnderlyingMethod step 7.
       pullPromise = PromiseObject::unforgeableResolve(cx, UndefinedHandleValue);
     } else {
       // CreateAlgorithmFromUnderlyingMethod step 6.b.i.
       {
-        AutoRealm ar(cx, &unwrappedPullMethod.toObject());
-        Rooted<Value> underlyingSource(cx, unwrappedUnderlyingSource);
-        if (!cx->compartment()->wrap(cx, &underlyingSource)) {
-          return false;
-        }
+        AutoRealm ar(cx, unwrappedController);
+
+        // |unwrappedPullMethod| and |unwrappedUnderlyingSource| come directly
+        // from |unwrappedController| slots so must be same-compartment with it.
+        cx->check(unwrappedPullMethod);
+        cx->check(unwrappedUnderlyingSource);
+
         Rooted<Value> controller(cx, ObjectValue(*unwrappedController));
-        if (!cx->compartment()->wrap(cx, &controller)) {
-          return false;
-        }
-        pullPromise =
-            PromiseCall(cx, unwrappedPullMethod, underlyingSource, controller);
+        cx->check(controller);
+
+        pullPromise = PromiseCall(cx, unwrappedPullMethod,
+                                  unwrappedUnderlyingSource, controller);
         if (!pullPromise) {
           return false;
         }
       }
       if (!cx->compartment()->wrap(cx, &pullPromise)) {
         return false;
       }
     }