Bug 1503399 - Weaken assertion to allow for stream.[[reader]] being a dead object. r=jwalden
authorJason Orendorff <jorendorff@mozilla.com>
Thu, 22 Nov 2018 17:35:12 +0000
changeset 504212 c4de0c7b78ed1740c8072e7509230b4bd5352261
parent 504211 c042ee04a7abf3a57b5a557b19829b43df3163c9
child 504213 e838d2083baf3ce8143cc89046aa9c4cbbf72d42
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1503399
milestone65.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 1503399 - Weaken assertion to allow for stream.[[reader]] being a dead object. r=jwalden Differential Revision: https://phabricator.services.mozilla.com/D11930
js/src/builtin/Stream.cpp
js/src/jit-test/tests/stream/bug-1503399-1.js
js/src/jit-test/tests/stream/bug-1503399-2.js
--- a/js/src/builtin/Stream.cpp
+++ b/js/src/builtin/Stream.cpp
@@ -2126,17 +2126,21 @@ ReadableStreamReaderGenericRelease(JSCon
 {
     // Step 1: Assert: reader.[[ownerReadableStream]] is not undefined.
     Rooted<ReadableStream*> unwrappedStream(cx, UnwrapStreamFromReader(cx, unwrappedReader));
     if (!unwrappedStream) {
         return false;
     }
 
     // Step 2: Assert: reader.[[ownerReadableStream]].[[reader]] is reader.
-    MOZ_ASSERT(UnwrapReaderFromStreamNoThrow(unwrappedStream) == unwrappedReader);
+#ifdef DEBUG
+    // The assertion is weakened a bit to allow for nuked wrappers.
+    ReadableStreamReader* unwrappedReader2 = UnwrapReaderFromStreamNoThrow(unwrappedStream);
+    MOZ_ASSERT_IF(unwrappedReader2, unwrappedReader2 == unwrappedReader);
+#endif
 
     // Create an exception to reject promises with below. We don't have a
     // clean way to do this, unfortunately.
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_READABLESTREAMREADER_RELEASED);
     RootedValue exn(cx);
     if (!cx->isExceptionPending() || !GetAndClearException(cx, &exn)) {
         // Uncatchable error. Die immediately without resolving
         // reader.[[closedPromise]].
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1503399-1.js
@@ -0,0 +1,16 @@
+// Don't assert if the wrapper that's the value of stream.[[reader]] gets nuked.
+
+load(libdir + "asserts.js");
+
+let g = newGlobal();
+let stream = new ReadableStream({
+    start(controller) {
+        controller.enqueue("ponies");
+        controller.close();
+    }
+});
+g.stream = stream;
+g.eval("var reader = ReadableStream.prototype.getReader.call(stream);");
+nukeCCW(g.reader);
+assertErrorMessage(() => g.eval("reader.read()"), g.TypeError, "can't access dead object");
+g.eval("reader.releaseLock();");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1503399-2.js
@@ -0,0 +1,11 @@
+// Don't assert if the wrapper that's the value of reader.[[stream]] gets nuked.
+
+load(libdir + "asserts.js");
+
+let g = newGlobal();
+let stream = new g.ReadableStream({});
+let reader = ReadableStream.prototype.getReader.call(stream);
+nukeCCW(stream);
+
+assertErrorMessage(() => reader.read(), TypeError, "can't access dead object");
+assertErrorMessage(() => reader.releaseLock(), TypeError, "can't access dead object");