Bug 1197977: [webm]. Ensure resource length calculation never underflows. r=kinetik a=ritu
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sun, 23 Aug 2015 21:35:58 +1000
changeset 289192 2aab115ee83f7c1a4c3bcee2771a1fce2b4cf8c6
parent 289191 eb3b3640b6bcced99487f8f0b13cc957faa31ea5
child 289193 495cdcba0ad4a5c6cbfc703a5e34fc7ed3bd9da8
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik, ritu
bugs1197977
milestone42.0a2
Bug 1197977: [webm]. Ensure resource length calculation never underflows. r=kinetik a=ritu
dom/media/webm/WebMDemuxer.cpp
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -39,19 +39,29 @@ extern PRLogModuleInfo* gNesteggLog;
 static int webmdemux_read(void* aBuffer, size_t aLength, void* aUserData)
 {
   MOZ_ASSERT(aUserData);
   MOZ_ASSERT(aLength < UINT32_MAX);
   WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
   int64_t length = demuxer->GetEndDataOffset();
   uint32_t count = aLength;
   int64_t position = demuxer->GetResource()->Tell();
+  if (position >= length) {
+    // GetLastBlockOffset was calculated after we had read past it.
+    // This condition can only occurs with plain webm, as with MSE,
+    // EnsureUpdateIndex would have been called first.
+    // Continue reading to the end instead.
+    length = demuxer->GetResource()->GetLength();
+  }
+  MOZ_ASSERT(position <= demuxer->GetResource()->GetLength());
+  MOZ_ASSERT(position <= length);
   if (length >= 0 && count + position > length) {
     count = length - position;
   }
+  MOZ_ASSERT(count <= aLength);
 
   uint32_t bytes = 0;
   nsresult rv =
     demuxer->GetResource()->Read(static_cast<char*>(aBuffer), count, &bytes);
   bool eof = bytes < aLength;
   return NS_FAILED(rv) ? -1 : eof ? 0 : 1;
 }
 
@@ -427,16 +437,17 @@ WebMDemuxer::EnsureUpToDateIndex()
     return;
   }
   mBufferedState->UpdateIndex(byteRanges, resource);
   if (!mInitData && mBufferedState->GetInitEndOffset() != -1) {
     mInitData = mResource.MediaReadAt(0, mBufferedState->GetInitEndOffset());
   }
   mLastWebMBlockOffset = mBufferedState->GetLastBlockOffset();
   mIsExpectingMoreData = mResource.GetResource()->IsExpectingMoreData();
+  MOZ_ASSERT(mLastWebMBlockOffset <= mResource.GetLength());
   mNeedReIndex = false;
 }
 
 void
 WebMDemuxer::NotifyDataArrived(uint32_t aLength, int64_t aOffset)
 {
   WEBM_DEBUG("length: %ld offset: %ld", aLength, aOffset);
   mNeedReIndex = true;