Bug 1329480: [MSE] Do not reject partial boxes. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 13 Jan 2017 17:38:40 +0100
changeset 374535 37d35f87e0fe226e6294aa7ef0c34a0d49a7fe19
parent 374534 7de18c5dbc39005603649a55b928e7a2b235395c
child 374536 00f3061cb568898110c41a27297b14c2f48370fd
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1329480
milestone53.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 1329480: [MSE] Do not reject partial boxes. r=gerald Partial content less than 8 bytes long was incorrectly rejected. We now assume that content is valid unless it is explicitly incorrect (bad box type) MozReview-Commit-ID: 8L32mNVjzxh
dom/media/mediasource/ContainerParser.cpp
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -15,16 +15,17 @@
 #include "MediaData.h"
 #ifdef MOZ_FMP4
 #include "MP4Stream.h"
 #include "mp4_demuxer/AtomType.h"
 #include "mp4_demuxer/ByteReader.h"
 #endif
 #include "nsAutoPtr.h"
 #include "SourceBufferResource.h"
+#include <algorithm>
 
 extern mozilla::LogModule* GetMediaSourceSamplesLog();
 
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 #define MSE_DEBUG(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 #define MSE_DEBUGV(name, arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Verbose, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 
@@ -343,27 +344,33 @@ public:
   {}
 
   MediaResult IsInitSegmentPresent(MediaByteBuffer* aData) override
   {
     ContainerParser::IsInitSegmentPresent(aData);
     // Each MP4 atom has a chunk size and chunk type. The root chunk in an MP4
     // file is the 'ftyp' atom followed by a file type. We just check for a
     // vaguely valid 'ftyp' atom.
+    if (aData->Length() < 8) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
     AtomParser parser(mType, aData);
     if (!parser.IsValid()) {
       return MediaResult(
         NS_ERROR_FAILURE,
         RESULT_DETAIL("Invalid Top-Level Box:%s", parser.LastInvalidBox()));
     }
     return parser.StartWithInitSegment() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
   }
 
   MediaResult IsMediaSegmentPresent(MediaByteBuffer* aData) override
   {
+    if (aData->Length() < 8) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
     AtomParser parser(mType, aData);
     if (!parser.IsValid()) {
       return MediaResult(
         NS_ERROR_FAILURE,
         RESULT_DETAIL("Invalid Box:%s", parser.LastInvalidBox()));
     }
     return parser.StartWithMediaSegment() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
   }
@@ -391,30 +398,25 @@ private:
 
       while (reader.Remaining() >= 8) {
         uint64_t size = reader.ReadU32();
         const uint8_t* typec = reader.Peek(4);
         mp4_demuxer::AtomType type(reader.ReadU32());
         MSE_DEBUGV(AtomParser ,"Checking atom:'%c%c%c%c' @ %u",
                    typec[0], typec[1], typec[2], typec[3],
                    (uint32_t)reader.Offset() - 8);
-
-        for (const auto& boxType : validBoxes) {
-          if (type == boxType) {
-            mValid = true;
-            break;
-          }
-        }
-        if (!mValid) {
-          // No point continuing.
+        if (std::find(std::begin(validBoxes), std::end(validBoxes), type)
+            == std::end(validBoxes)) {
+          // No valid box found, no point continuing.
           mLastInvalidBox[0] = typec[0];
           mLastInvalidBox[1] = typec[1];
           mLastInvalidBox[2] = typec[2];
           mLastInvalidBox[3] = typec[3];
           mLastInvalidBox[4] = '\0';
+          mValid = false;
           break;
         }
         if (mInitOffset.isNothing() &&
             mp4_demuxer::AtomType(type) == initAtom) {
           mInitOffset = Some(reader.Offset());
         }
         if (mMediaOffset.isNothing() &&
             mp4_demuxer::AtomType(type) == mediaAtom) {
@@ -453,17 +455,17 @@ private:
       return mMediaOffset.isSome() &&
         (mInitOffset.isNothing() || mMediaOffset.ref() < mInitOffset.ref());
     }
     bool IsValid() const { return mValid; }
     const char* LastInvalidBox() const { return mLastInvalidBox; }
   private:
     Maybe<size_t> mInitOffset;
     Maybe<size_t> mMediaOffset;
-    bool mValid = false;
+    bool mValid = true;
     char mLastInvalidBox[5];
   };
 
 public:
   MediaResult ParseStartAndEndTimestamps(MediaByteBuffer* aData,
                                          int64_t& aStart,
                                          int64_t& aEnd) override
   {