Bug 1296532 - Use fallible arrays in MoofParser - r=jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 25 Aug 2016 16:41:50 +1000
changeset 405909 bc603c30214768b9a39c83bd92bc0df31d1498e4
parent 405908 fbdddecf6058662ae850366bb5f0c3afb691dd10
child 405965 16b23cdd7d9342671bf20adf136e2a39cb5ab429
child 405972 d55fd46a9a46ad9d0819d51da017acc68f97b212
child 406086 9660a2882c89df4e5d7feae9f5e484cfde6c1864
child 406087 54fca3168a70d951e6012baea4bf0544827cae11
push id27594
push usergsquelart@mozilla.com
push dateFri, 26 Aug 2016 03:08:37 +0000
reviewersjya
bugs1296532
milestone51.0a1
Bug 1296532 - Use fallible arrays in MoofParser - r=jya Use fallible allocations for arrays that could get arbitrarily long (independant of the media file size.) MozReview-Commit-ID: LWiKFVpYK5d
media/libstagefright/binding/MoofParser.cpp
media/libstagefright/binding/include/mp4_demuxer/ByteReader.h
media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -847,25 +847,33 @@ Saiz::Saiz(Box& aBox, AtomType aDefaultT
   }
   if (flags & 1) {
     mAuxInfoType = reader->ReadU32();
     mAuxInfoTypeParameter = reader->ReadU32();
   }
   uint8_t defaultSampleInfoSize = reader->ReadU8();
   uint32_t count = reader->ReadU32();
   if (defaultSampleInfoSize) {
+    if (!mSampleInfoSize.SetCapacity(count, fallible)) {
+      LOG(Saiz, "OOM");
+      reader->DiscardRemaining();
+      return;
+    }
     for (int i = 0; i < count; i++) {
-      mSampleInfoSize.AppendElement(defaultSampleInfoSize);
+      MOZ_ALWAYS_TRUE(mSampleInfoSize.AppendElement(defaultSampleInfoSize,
+                                                    fallible));
     }
   } else {
     if (!reader->ReadArray(mSampleInfoSize, count)) {
-      LOG(Saiz, "Incomplete Box (missing count:%u)", count);
+      LOG(Saiz, "Incomplete Box (OOM or missing count:%u)", count);
+      reader->DiscardRemaining();
       return;
     }
   }
+  reader->DiscardRemaining();
   mValid = true;
 }
 
 Saio::Saio(Box& aBox, AtomType aDefaultType)
   : mAuxInfoType(aDefaultType)
   , mAuxInfoTypeParameter(0)
 {
   BoxReader reader(aBox);
@@ -887,23 +895,27 @@ Saio::Saio(Box& aBox, AtomType aDefaultT
   }
   size_t count = reader->ReadU32();
   need = (version ? sizeof(uint64_t) : sizeof(uint32_t)) * count;
   if (reader->Remaining() < need) {
     LOG(Saio, "Incomplete Box (have:%lld need:%lld)",
         (uint64_t)reader->Remaining(), (uint64_t)need);
     return;
   }
-  mOffsets.SetCapacity(count);
+  if (!mOffsets.SetCapacity(count, fallible)) {
+    LOG(Saiz, "OOM");
+    reader->DiscardRemaining();
+    return;
+  }
   if (version == 0) {
     for (size_t i = 0; i < count; i++) {
-      mOffsets.AppendElement(reader->ReadU32());
+      MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU32(), fallible));
     }
   } else {
     for (size_t i = 0; i < count; i++) {
-      mOffsets.AppendElement(reader->ReadU64());
+      MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU64(), fallible));
     }
   }
   mValid = true;
 }
 
 #undef LOG
 }
--- a/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h
@@ -309,28 +309,46 @@ public:
     if (!ptr) {
       MOZ_ASSERT(false);
       return 0;
     }
     return *reinterpret_cast<const T*>(ptr);
   }
 
   template <typename T>
-  bool ReadArray(nsTArray<T>& aDest, size_t aLength)
+  MOZ_MUST_USE bool ReadArray(nsTArray<T>& aDest, size_t aLength)
   {
     auto ptr = Read(aLength * sizeof(T));
     if (!ptr) {
       return false;
     }
 
     aDest.Clear();
     aDest.AppendElements(reinterpret_cast<const T*>(ptr), aLength);
     return true;
   }
 
+  template <typename T>
+  MOZ_MUST_USE bool ReadArray(FallibleTArray<T>& aDest, size_t aLength)
+  {
+    auto ptr = Read(aLength * sizeof(T));
+    if (!ptr) {
+      return false;
+    }
+
+    aDest.Clear();
+    if (!aDest.SetCapacity(aLength, mozilla::fallible)) {
+      return false;
+    }
+    MOZ_ALWAYS_TRUE(aDest.AppendElements(reinterpret_cast<const T*>(ptr),
+                                         aLength,
+                                         mozilla::fallible));
+    return true;
+  }
+
 private:
   const uint8_t* mPtr;
   size_t mRemaining;
   size_t mLength;
 };
 }
 
 #endif
--- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
@@ -142,27 +142,27 @@ struct Sample
 
 class Saiz final : public Atom
 {
 public:
   Saiz(Box& aBox, AtomType aDefaultType);
 
   AtomType mAuxInfoType;
   uint32_t mAuxInfoTypeParameter;
-  nsTArray<uint8_t> mSampleInfoSize;
+  FallibleTArray<uint8_t> mSampleInfoSize;
 };
 
 class Saio final : public Atom
 {
 public:
   Saio(Box& aBox, AtomType aDefaultType);
 
   AtomType mAuxInfoType;
   uint32_t mAuxInfoTypeParameter;
-  nsTArray<uint64_t> mOffsets;
+  FallibleTArray<uint64_t> mOffsets;
 };
 
 class AuxInfo {
 public:
   AuxInfo(int64_t aMoofOffset, Saiz& aSaiz, Saio& aSaio);
 
 private:
   int64_t mMoofOffset;