# HG changeset patch # User Randy Lin # Date 1375691921 -28800 # Node ID f51b87bd52d01e84e959fe6c206b2d4bb2cec0ba # Parent ff1477ebf69e4a46bc02372e447cf20d5b31257f Bug 897776 - MediaRecorder infinite recursion with requestData() calls in dataavailable event diff --git a/content/media/MediaRecorder.cpp b/content/media/MediaRecorder.cpp --- a/content/media/MediaRecorder.cpp +++ b/content/media/MediaRecorder.cpp @@ -125,16 +125,17 @@ MediaRecorder::Init(JSContext* aCx, nsPI { MOZ_ASSERT(aOwnerWindow); MOZ_ASSERT(aOwnerWindow->IsInnerWindow()); BindToOwner(aOwnerWindow); } MediaRecorder::MediaRecorder(DOMMediaStream& aStream) : mTimeSlice(0), + mAllowedZeroBlobs(0), mState(RecordingState::Inactive) { mStream = &aStream; SetIsDOMBinding(); } void MediaRecorder::ExtractEncodedData() @@ -251,16 +252,21 @@ MediaRecorder::Resume(ErrorResult& aResu void MediaRecorder::RequestData(ErrorResult& aResult) { if (mState != RecordingState::Recording) { aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } + if (mAllowedZeroBlobs > MAX_ALLOW_CONTINUOUS_ZERO_BLOBS) { + NS_WARNING("Too many requestData function call in a short time!!"); + aResult.Throw(NS_ERROR_ABORT); + return; + } nsresult rv = CreateAndDispatchBlobEvent(); if (NS_FAILED(rv)) { aResult.Throw(rv); return; } } JSObject* @@ -298,16 +304,20 @@ MediaRecorder::CreateAndDispatchBlobEven if (!CheckPrincipal()) { // Media is not same-origin, don't allow the data out. return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr blob; blob = mEncodedBufferCache->ExtractBlob(mMimeType); + uint64_t blobsize; + blob->GetSize(&blobsize); + blobsize > 0 ? mAllowedZeroBlobs = 0 : mAllowedZeroBlobs ++; + // create an event that uses the MessageEvent interface, // which does not bubble, is not cancelable, and has no default action nsCOMPtr event; nsresult rv = NS_NewDOMBlobEvent(getter_AddRefs(event), this, nullptr, nullptr); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr blobEvent = do_QueryInterface(event); rv = blobEvent->InitBlobEvent(NS_LITERAL_STRING("dataavailable"), diff --git a/content/media/MediaRecorder.h b/content/media/MediaRecorder.h --- a/content/media/MediaRecorder.h +++ b/content/media/MediaRecorder.h @@ -11,16 +11,19 @@ #include "MediaEncoder.h" #include "mozilla/dom/MediaRecorderBinding.h" #include "nsDOMEventTargetHelper.h" #include "EncodedBufferCache.h" #include "TrackUnionStream.h" // Max size for allowing queue encoded data in memory #define MAX_ALLOW_MEMORY_BUFFER 1024000 +// Maximal allowed continuous zero Blob +#define MAX_ALLOW_CONTINUOUS_ZERO_BLOBS 12 + namespace mozilla { class ErrorResult; namespace dom { /** * Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html @@ -112,16 +115,18 @@ protected: nsRefPtr mTrackUnionStream; // This object creates on start() and destroys in ~MediaRecorder. nsAutoPtr 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; + // Count of continues of zero size Blob, avoid the UA call of requestData method crazily. + int32_t mAllowedZeroBlobs; // The current state of the MediaRecorder object. RecordingState mState; }; } } #endif diff --git a/content/media/test/Makefile.in b/content/media/test/Makefile.in --- 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_avoid_recursive.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 \ diff --git a/content/media/test/test_mediarecorder_avoid_recursive.html b/content/media/test/test_mediarecorder_avoid_recursive.html new file mode 100644 --- /dev/null +++ b/content/media/test/test_mediarecorder_avoid_recursive.html @@ -0,0 +1,41 @@ + + + + Test MediaRecorder can't record the stopped media stream + + + + + +
+
+
+ +