Bug 1253471 - Remove Metadata hard-coded limit - r?jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Tue, 08 Mar 2016 14:50:43 +1100
changeset 338042 250521f0de54da61925852dfbe2e7d56e16416e9
parent 338041 1f26139396323965b2cd3a3018ff75fc99263a23
child 515704 c9ff012b62b7dbaa0b5cabb32b1d6e1f5805306c
push id12406
push usergsquelart@mozilla.com
push dateTue, 08 Mar 2016 03:51:14 +0000
reviewersjya
bugs1253471
milestone48.0a1
Bug 1253471 - Remove Metadata hard-coded limit - r?jya Instead of relying on some arbitrary limit for ftyp+moov box sizes, we check for overflow and possible type truncations, and then let memory allocation routines (e.g. MediaByteBuffer::SetLength) deal with actual memory limitations. MozReview-Commit-ID: AXXxvdDYnnr
media/libstagefright/binding/MoofParser.cpp
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mp4_demuxer/MoofParser.h"
 #include "mp4_demuxer/Box.h"
 #include "mp4_demuxer/SinfParser.h"
 #include <limits>
 #include "Intervals.h"
 
+#include "mozilla/CheckedInt.h"
 #include "mozilla/Logging.h"
 
 #if defined(MOZ_FMP4)
 extern mozilla::LogModule* GetDemuxerLog();
 
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 #define LOG(name, arg, ...) MOZ_LOG(GetDemuxerLog(), mozilla::LogLevel::Debug, (TOSTRING(name) "(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
@@ -177,37 +178,44 @@ MoofParser::HasMetadata()
 }
 
 already_AddRefed<mozilla::MediaByteBuffer>
 MoofParser::Metadata()
 {
   MediaByteRange ftyp;
   MediaByteRange moov;
   ScanForMetadata(ftyp, moov);
-  if (!ftyp.Length() || !moov.Length() ||
-      ftyp.Length() > Box::kMAX_BOX_READ || moov.Length() > Box::kMAX_BOX_READ) {
-    // No ftyp or moov, or trying to read bigger-that-readable box (32MB).
+  CheckedInt<MediaByteBuffer::size_type> ftypLength = ftyp.Length();
+  CheckedInt<MediaByteBuffer::size_type> moovLength = moov.Length();
+  if (!ftypLength.isValid() || !moovLength.isValid()
+      || !ftypLength.value() || !moovLength.value()) {
+    // No ftyp or moov, or they cannot be used as array size.
+    return nullptr;
+  }
+  CheckedInt<MediaByteBuffer::size_type> totalLength = ftypLength + moovLength;
+  if (!totalLength.isValid()) {
+    // Addition overflow, or sum cannot be used as array size.
     return nullptr;
   }
   RefPtr<MediaByteBuffer> metadata = new MediaByteBuffer();
-  if (!metadata->SetLength(ftyp.Length() + moov.Length(), fallible)) {
+  if (!metadata->SetLength(totalLength.value(), fallible)) {
     // OOM
     return nullptr;
   }
 
   RefPtr<mp4_demuxer::BlockingStream> stream = new BlockingStream(mSource);
   size_t read;
   bool rv =
-    stream->ReadAt(ftyp.mStart, metadata->Elements(), ftyp.Length(), &read);
-  if (!rv || read != ftyp.Length()) {
+    stream->ReadAt(ftyp.mStart, metadata->Elements(), ftypLength.value(), &read);
+  if (!rv || read != ftypLength.value()) {
     return nullptr;
   }
   rv =
-    stream->ReadAt(moov.mStart, metadata->Elements() + ftyp.Length(), moov.Length(), &read);
-  if (!rv || read != moov.Length()) {
+    stream->ReadAt(moov.mStart, metadata->Elements() + ftypLength.value(), moovLength.value(), &read);
+  if (!rv || read != moovLength.value()) {
     return nullptr;
   }
   return metadata.forget();
 }
 
 Interval<Microseconds>
 MoofParser::GetCompositionRange(const MediaByteRangeSet& aByteRanges)
 {