Bug 1387798 - remove uncessary check for remaining data and add error log when parsing fails. r?kinetik draft
authorAlfredo.Yang <ayang@mozilla.com>
Fri, 13 Oct 2017 14:40:05 +0800
changeset 681372 70cc0796f5daf988a46beac83af78503eed38e99
parent 681371 00131d123a85706c395c05454c82952a858d60cf
child 681411 5be2a2c50f0689f0343b9d7c421069a1cd41191c
push id84803
push userbmo:ayang@mozilla.com
push dateTue, 17 Oct 2017 07:13:43 +0000
reviewerskinetik
bugs1387798
milestone58.0a1
Bug 1387798 - remove uncessary check for remaining data and add error log when parsing fails. r?kinetik MozReview-Commit-ID: Bo6q3ysvktr
media/libstagefright/binding/MoofParser.cpp
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -588,16 +588,17 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, 
   // Now search for TRUN boxes.
   uint64_t decodeTime =
     tfdt.IsValid() ? tfdt.mBaseMediaDecodeTime : *aDecodeTime;
   for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
     if (box.IsType("trun")) {
       if (ParseTrun(box, tfhd, aMvhd, aMdhd, aEdts, &decodeTime, aIsAudio).isOk()) {
         mValid = true;
       } else {
+        LOG(Moof, "ParseTrun failed");
         mValid = false;
         break;
       }
     }
   }
   *aDecodeTime = decodeTime;
 }
 
@@ -633,31 +634,16 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
     return Err(NS_ERROR_FAILURE);
   }
   uint32_t sampleCount;
   MOZ_TRY_VAR(sampleCount, reader->ReadU32());
   if (sampleCount == 0) {
     return Ok();
   }
 
-  size_t need =
-    ((flags & 1) ? sizeof(uint32_t) : 0) +
-    ((flags & 4) ? sizeof(uint32_t) : 0);
-  uint16_t flag[] = { 0x100, 0x200, 0x400, 0x800, 0 };
-  for (size_t i = 0; flag[i]; i++) {
-    if (flags & flag[i]) {
-      need += sizeof(uint32_t) * sampleCount;
-    }
-  }
-  if (reader->Remaining() < need) {
-    LOG(Moof, "Incomplete Box (have:%zu need:%zu)",
-        reader->Remaining(), need);
-    return Err(NS_ERROR_FAILURE);
-  }
-
   uint64_t offset = aTfhd.mBaseDataOffset;
   if (flags & 0x01) {
     uint32_t tmp;
     MOZ_TRY_VAR(tmp, reader->ReadU32());
     offset += tmp;
   }
   uint32_t firstSampleFlags = aTfhd.mDefaultSampleFlags;
   if (flags & 0x04) {
@@ -716,38 +702,28 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
   *aDecodeTime = decodeTime;
 
   return Ok();
 }
 
 Tkhd::Tkhd(Box& aBox)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Tkhd, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Tkhd::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Tkhd, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
-  size_t need =
-    3*(version ? sizeof(int64_t) : sizeof(int32_t)) + 2*sizeof(int32_t);
-  if (reader->Remaining() < need) {
-    LOG(Tkhd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   if (version == 0) {
     uint32_t creationTime, modificationTime, reserved, duration;
     MOZ_TRY_VAR(creationTime, reader->ReadU32());
     MOZ_TRY_VAR(modificationTime, reader->ReadU32());
     MOZ_TRY_VAR(mTrackId, reader->ReadU32());
     MOZ_TRY_VAR(reserved, reader->ReadU32());
     MOZ_TRY_VAR(duration, reader->ReadU32());
 
@@ -766,38 +742,29 @@ Tkhd::Parse(Box& aBox)
     MOZ_TRY_VAR(mDuration, reader->ReadU64());
   }
   return Ok();
 }
 
 Mvhd::Mvhd(Box& aBox)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Mvhd, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Mvhd::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Mdhd, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
+
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
-  size_t need =
-    3*(version ? sizeof(int64_t) : sizeof(int32_t)) + sizeof(uint32_t);
-  if (reader->Remaining() < need) {
-    LOG(Mvhd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
 
   if (version == 0) {
     uint32_t creationTime, modificationTime, duration;
     MOZ_TRY_VAR(creationTime, reader->ReadU32());
     MOZ_TRY_VAR(modificationTime, reader->ReadU32());
     MOZ_TRY_VAR(mTimescale, reader->ReadU32());
     MOZ_TRY_VAR(duration, reader->ReadU32());
     mCreationTime = creationTime;
@@ -817,73 +784,55 @@ Mvhd::Parse(Box& aBox)
 Mdhd::Mdhd(Box& aBox)
   : Mvhd(aBox)
 {
 }
 
 Trex::Trex(Box& aBox)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Trex, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Trex::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
-  if (reader->Remaining() < 6*sizeof(uint32_t)) {
-    LOG(Trex, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)6*sizeof(uint32_t));
-    return Err(NS_ERROR_FAILURE);
-  }
+
   MOZ_TRY_VAR(mFlags, reader->ReadU32());
   MOZ_TRY_VAR(mTrackId, reader->ReadU32());
   MOZ_TRY_VAR(mDefaultSampleDescriptionIndex, reader->ReadU32());
   MOZ_TRY_VAR(mDefaultSampleDuration, reader->ReadU32());
   MOZ_TRY_VAR(mDefaultSampleSize, reader->ReadU32());
   MOZ_TRY_VAR(mDefaultSampleFlags, reader->ReadU32());
 
   return Ok();
 }
 
 Tfhd::Tfhd(Box& aBox, Trex& aTrex)
   : Trex(aTrex)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Tfhd, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Tfhd::Parse(Box& aBox)
 {
   MOZ_ASSERT(aBox.IsType("tfhd"));
   MOZ_ASSERT(aBox.Parent()->IsType("traf"));
   MOZ_ASSERT(aBox.Parent()->Parent()->IsType("moof"));
 
   BoxReader reader(aBox);
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Tfhd, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
+
   MOZ_TRY_VAR(mFlags, reader->ReadU32());
-  size_t need = sizeof(uint32_t) /* trackid */;
-  uint8_t flag[] = { 1, 2, 8, 0x10, 0x20, 0 };
-  uint8_t flagSize[] = { sizeof(uint64_t), sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t) };
-  for (size_t i = 0; flag[i]; i++) {
-    if (mFlags & flag[i]) {
-      need += flagSize[i];
-    }
-  }
-  if (reader->Remaining() < need) {
-    LOG(Tfhd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   MOZ_TRY_VAR(mTrackId, reader->ReadU32());
   mBaseDataOffset = aBox.Parent()->Parent()->Offset();
   if (mFlags & 0x01) {
     MOZ_TRY_VAR(mBaseDataOffset, reader->ReadU64());
   }
   if (mFlags & 0x02) {
     MOZ_TRY_VAR(mDefaultSampleDescriptionIndex, reader->ReadU32());
   }
@@ -898,79 +847,61 @@ Tfhd::Parse(Box& aBox)
   }
 
   return Ok();
 }
 
 Tfdt::Tfdt(Box& aBox)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Tfdt, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Tfdt::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Tfdt, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
+
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
-  size_t need = version ? sizeof(uint64_t) : sizeof(uint32_t) ;
-  if (reader->Remaining() < need) {
-    LOG(Tfdt, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   if (version == 0) {
     uint32_t tmp;
     MOZ_TRY_VAR(tmp, reader->ReadU32());
     mBaseMediaDecodeTime = tmp;
   } else if (version == 1) {
     MOZ_TRY_VAR(mBaseMediaDecodeTime, reader->ReadU64());
   }
   return Ok();
 }
 
 Edts::Edts(Box& aBox)
   : mMediaStart(0)
   , mEmptyOffset(0)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Edts, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Edts::Parse(Box& aBox)
 {
   Box child = aBox.FirstChild();
   if (!child.IsType("elst")) {
     return Err(NS_ERROR_FAILURE);
   }
 
   BoxReader reader(child);
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Edts, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
-  size_t need =
-    sizeof(uint32_t) + 2*(version ? sizeof(int64_t) : sizeof(uint32_t));
-  if (reader->Remaining() < need) {
-    LOG(Edts, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   bool emptyEntry = false;
   uint32_t entryCount;
   MOZ_TRY_VAR(entryCount, reader->ReadU32());
   for (uint32_t i = 0; i < entryCount; i++) {
     uint64_t segment_duration;
     int64_t media_time;
     if (version == 1) {
       MOZ_TRY_VAR(segment_duration, reader->ReadU64());
@@ -1000,38 +931,29 @@ Edts::Parse(Box& aBox)
   return Ok();
 }
 
 Saiz::Saiz(Box& aBox, AtomType aDefaultType)
   : mAuxInfoType(aDefaultType)
   , mAuxInfoTypeParameter(0)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Saiz, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Saiz::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Saiz, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
+
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
-  size_t need =
-    ((flags & 1) ? 2*sizeof(uint32_t) : 0) + sizeof(uint8_t) + sizeof(uint32_t);
-  if (reader->Remaining() < need) {
-    LOG(Saiz, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   if (flags & 1) {
     MOZ_TRY_VAR(mAuxInfoType, reader->ReadU32());
     MOZ_TRY_VAR(mAuxInfoTypeParameter, reader->ReadU32());
   }
   uint8_t defaultSampleInfoSize;
   MOZ_TRY_VAR(defaultSampleInfoSize, reader->ReadU8());
   uint32_t count;
   MOZ_TRY_VAR(count, reader->ReadU32());
@@ -1050,49 +972,36 @@ Saiz::Parse(Box& aBox)
   return Ok();
 }
 
 Saio::Saio(Box& aBox, AtomType aDefaultType)
   : mAuxInfoType(aDefaultType)
   , mAuxInfoTypeParameter(0)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Saio, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Saio::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Saio, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
+
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   uint8_t version = flags >> 24;
-  size_t need = ((flags & 1) ? (2*sizeof(uint32_t)) : 0) + sizeof(uint32_t);
-  if (reader->Remaining() < need) {
-    LOG(Saio, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   if (flags & 1) {
     MOZ_TRY_VAR(mAuxInfoType, reader->ReadU32());
     MOZ_TRY_VAR(mAuxInfoTypeParameter, reader->ReadU32());
   }
+
   size_t count;
   MOZ_TRY_VAR(count, reader->ReadU32());
-  need = (version ? sizeof(uint64_t) : sizeof(uint32_t)) * count;
-  if (reader->Remaining() < need) {
-    LOG(Saio, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   if (!mOffsets.SetCapacity(count, fallible)) {
     LOG(Saiz, "OOM");
     return Err(NS_ERROR_FAILURE);
   }
   if (version == 0) {
     uint32_t offset;
     for (size_t i = 0; i < count; i++) {
       MOZ_TRY_VAR(offset, reader->ReadU32());
@@ -1115,53 +1024,32 @@ Sbgp::Sbgp(Box& aBox)
   }
 }
 
 Result<Ok, nsresult>
 Sbgp::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
 
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Sbgp, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
-
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   const uint8_t version = flags >> 24;
   flags = flags & 0xffffff;
 
-  // Make sure we have enough bytes to read as far as the count.
-  uint32_t need = (version == 1 ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2;
-  if (reader->Remaining() < need) {
-    LOG(Sbgp, "Incomplete Box (have:%" PRIu64 ", need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
-
   uint32_t type;
   MOZ_TRY_VAR(type, reader->ReadU32());
   mGroupingType = type;
 
   if (version == 1) {
     MOZ_TRY_VAR(mGroupingTypeParam, reader->ReadU32());
   }
 
   uint32_t count;
   MOZ_TRY_VAR(count, reader->ReadU32());
 
-  // Make sure we can read all the entries.
-  need = sizeof(uint32_t) * 2 * count;
-  if (reader->Remaining() < need) {
-    LOG(Sbgp, "Incomplete Box (have:%" PRIu64 ", need:%" PRIu64 "). Failed to read entries",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
-
   for (uint32_t i = 0; i < count; i++) {
     uint32_t sampleCount;
     MOZ_TRY_VAR(sampleCount, reader->ReadU32());
     uint32_t groupDescriptionIndex;
     MOZ_TRY_VAR(groupDescriptionIndex, reader->ReadU32());
 
     SampleToGroupEntry entry(sampleCount, groupDescriptionIndex);
     if (!mEntries.AppendElement(entry, mozilla::fallible)) {
@@ -1170,42 +1058,31 @@ Sbgp::Parse(Box& aBox)
     }
   }
   return Ok();
 }
 
 Sgpd::Sgpd(Box& aBox)
 {
   if (Parse(aBox).isOk()) {
+    LOG(Sgpd, "Parse failed");
     mValid = true;
   }
 }
 
 Result<Ok, nsresult>
 Sgpd::Parse(Box& aBox)
 {
   BoxReader reader(aBox);
 
-  if (!reader->CanReadType<uint32_t>()) {
-    LOG(Sgpd, "Incomplete Box (missing flags)");
-    return Err(NS_ERROR_FAILURE);
-  }
-
   uint32_t flags;
   MOZ_TRY_VAR(flags, reader->ReadU32());
   const uint8_t version = flags >> 24;
   flags = flags & 0xffffff;
 
-  uint32_t need = ((flags & 1) ? sizeof(uint32_t) : 0) + sizeof(uint32_t) * 2;
-  if (reader->Remaining() < need) {
-    LOG(Sgpd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 ")",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
-
   uint32_t type;
   MOZ_TRY_VAR(type, reader->ReadU32());
   mGroupingType = type;
 
   const uint32_t entrySize = sizeof(uint32_t) + kKeyIdSize;
   uint32_t defaultLength = 0;
 
   if (version == 1) {
@@ -1213,25 +1090,16 @@ Sgpd::Parse(Box& aBox)
     if (defaultLength < entrySize && defaultLength != 0) {
       return Err(NS_ERROR_FAILURE);
     }
   }
 
   uint32_t count;
   MOZ_TRY_VAR(count, reader->ReadU32());
 
-  // Make sure we have sufficient remaining bytes to read the entries.
-  need =
-    count * (sizeof(uint32_t) * (version == 1 && defaultLength == 0 ? 2 : 1) +
-             kKeyIdSize * sizeof(uint8_t));
-  if (reader->Remaining() < need) {
-    LOG(Sgpd, "Incomplete Box (have:%" PRIu64 " need:%" PRIu64 "). Failed to read entries",
-        (uint64_t)reader->Remaining(), (uint64_t)need);
-    return Err(NS_ERROR_FAILURE);
-  }
   for (uint32_t i = 0; i < count; ++i) {
     if (version == 1 && defaultLength == 0) {
       uint32_t descriptionLength;
       MOZ_TRY_VAR(descriptionLength, reader->ReadU32());
       if (descriptionLength < entrySize) {
         return Err(NS_ERROR_FAILURE);
       }
     }