Bug 894348 - MediaRecorder use-after-free crash [@mozilla::MediaStream::GraphImpl]. Fix the wrong pointer type of ProcessedMediaStream. r=roc
authorRandy Lin <rlin@mozilla.com>
Sun, 21 Jul 2013 22:33:01 +0800
changeset 151818 2e6ca2dc655e4a92f455ae076a3870f282afd07d
parent 151817 2e57ec157214a1a6f24224e97a2c109f2b3226b6
child 151819 d33324fd225144cc30aef26857e7d4ff03ce1776
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs894348
milestone25.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 894348 - MediaRecorder use-after-free crash [@mozilla::MediaStream::GraphImpl]. Fix the wrong pointer type of ProcessedMediaStream. r=roc
content/media/MediaRecorder.cpp
content/media/MediaRecorder.h
content/media/test/Makefile.in
content/media/test/test_mediarecorder_reload_crash.html
--- a/content/media/MediaRecorder.cpp
+++ b/content/media/MediaRecorder.cpp
@@ -110,16 +110,19 @@ public:
 
 private:
   nsRefPtr<MediaRecorder> mRecorder;
   nsRefPtr<MediaEncoder>  mEncoder;
 };
 
 MediaRecorder::~MediaRecorder()
 {
+  if (mTrackUnionStream) {
+    mTrackUnionStream->Destroy();
+  }
 }
 
 void
 MediaRecorder::Init(JSContext* aCx, nsPIDOMWindow* aOwnerWindow)
 {
   MOZ_ASSERT(aOwnerWindow);
   MOZ_ASSERT(aOwnerWindow->IsInnerWindow());
   BindToOwner(aOwnerWindow);
--- a/content/media/MediaRecorder.h
+++ b/content/media/MediaRecorder.h
@@ -104,17 +104,17 @@ protected:
 
   // Runnable thread for read data from mediaEncoder. It starts at MediaRecorder::Start() and stops at MediaRecorder::Stop().
   nsCOMPtr<nsIThread> mReadThread;
   // The MediaEncoder object initializes on start() and destroys in ~MediaRecorder.
   nsRefPtr<MediaEncoder> mEncoder;
   // MediaStream passed from js context
   nsRefPtr<DOMMediaStream> mStream;
   // This media stream is used for notifying raw data to encoder and can be blocked.
-  nsAutoPtr<ProcessedMediaStream> mTrackUnionStream;
+  nsRefPtr<ProcessedMediaStream> mTrackUnionStream;
   // This object creates on start() and destroys in ~MediaRecorder.
   nsAutoPtr<EncodedBufferCache> mEncodedBufferCache;
   // It specifies the container format as well as the audio and video capture formats.
   nsString mMimeType;
   // The interval of timer passed from Start(). On every mTimeSlice milliseconds, if there are buffers store in the EncodedBufferCache,
   // a dataavailable event will be fired.
   int32_t mTimeSlice;
   // The current state of the MediaRecorder object.
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -117,16 +117,17 @@ MOCHITEST_FILES = \
 		test_audiowrite.html \
 		test_mediarecorder_creation.html \
 		test_mozHasAudio.html \
 		test_source_media.html \
 		test_autoplay_contentEditable.html \
 		test_bug448534.html \
 		test_bug463162.xhtml \
 		test_decoder_disable.html \
+		test_mediarecorder_reload_crash.html \
 		test_media_selection.html \
 		test_playback.html \
 		test_seekLies.html \
 		test_media_sniffer.html \
 		contentType.sjs \
 		test_streams_srcObject.html \
 		test_reset_src.html \
 		test_streams_autoplay.html \
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_mediarecorder_reload_crash.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test that reloading media recorder object</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=894348">Mozill
+a Bug 894348</a>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+  for (i = 0; i< 5; i++) {
+    try { o0 = document.createElement('audio') } catch(e) { }
+    try { o0.src = "sound.ogg" } catch(e) { }
+    try { (document.body || document.documentElement).appendChild(o0) } catch(e) { }
+    try { o1 = o0.mozCaptureStreamUntilEnded(); } catch(e) { }
+    try { o2 = new MediaRecorder(o1) } catch(e) { }
+    try { o2.start(0) } catch(e) { }
+    SpecialPowers.gc();
+  }
+  ok(true, "pass the crash test");
+</script>
+</pre>
+</body>
+</html>