From 0adebd32d9edaf37ef2396408d4fd76a9b255872 Mon Sep 17 00:00:00 2001 From: trav90 Date: Sat, 21 Jul 2018 19:57:42 -0500 Subject: Rework MoofParser to return an error when the underlying BufferReader returns an error. --- media/libstagefright/binding/MoofParser.cpp | 273 +++++++++++++++------ media/libstagefright/binding/SinfParser.cpp | 24 +- .../binding/include/mp4_demuxer/Box.h | 6 +- 3 files changed, 221 insertions(+), 82 deletions(-) (limited to 'media') diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp index ced054282..491967a12 100644 --- a/media/libstagefright/binding/MoofParser.cpp +++ b/media/libstagefright/binding/MoofParser.cpp @@ -550,14 +550,20 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u LOG(Moof, "Incomplete Box (missing flags)"); return false; } - uint32_t flags = reader->ReadU32(); + uint32_t flags; + if (!reader->ReadU32(flags)) { + return false; + } uint8_t version = flags >> 24; if (!reader->CanReadType()) { LOG(Moof, "Incomplete Box (missing sampleCount)"); return false; } - uint32_t sampleCount = reader->ReadU32(); + uint32_t sampleCount; + if (!reader->ReadU32(sampleCount)) { + return false; + } if (sampleCount == 0) { return true; } @@ -577,9 +583,21 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u return false; } - uint64_t offset = aTfhd.mBaseDataOffset + (flags & 1 ? reader->ReadU32() : 0); - uint32_t firstSampleFlags = - flags & 4 ? reader->ReadU32() : aTfhd.mDefaultSampleFlags; + uint64_t offset = aTfhd.mBaseDataOffset; + if (flags & 1) { + uint32_t baseOffset; + if (!reader->ReadU32(baseOffset)) { + return false; + } + offset += baseOffset; + } + uint32_t firstSampleFlags = aTfhd.mDefaultSampleFlags; + if (flags & 4) { + if (!reader->ReadU32(firstSampleFlags)) { + return false; + } + } + uint64_t decodeTime = *aDecodeTime; nsTArray> timeRanges; @@ -589,16 +607,29 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u } for (size_t i = 0; i < sampleCount; i++) { - uint32_t sampleDuration = - flags & 0x100 ? reader->ReadU32() : aTfhd.mDefaultSampleDuration; - uint32_t sampleSize = - flags & 0x200 ? reader->ReadU32() : aTfhd.mDefaultSampleSize; - uint32_t sampleFlags = - flags & 0x400 ? reader->ReadU32() - : i ? aTfhd.mDefaultSampleFlags : firstSampleFlags; + uint32_t sampleDuration = aTfhd.mDefaultSampleDuration; + if (flags & 0x100) { + if (!reader->ReadU32(sampleDuration)) { + return false; + } + } + uint32_t sampleSize = aTfhd.mDefaultSampleSize; + if (flags & 0x200) { + if (!reader->ReadU32(sampleSize)) { + return false; + } + } + uint32_t sampleFlags = i ? aTfhd.mDefaultSampleFlags : firstSampleFlags; + if (flags & 0x400) { + if (!reader->ReadU32(sampleFlags)) { + return false; + } + } int32_t ctsOffset = 0; if (flags & 0x800) { - ctsOffset = reader->Read32(); + if (!reader->Read32(ctsOffset)) { + return false; + } } Sample sample; @@ -635,7 +666,10 @@ Tkhd::Tkhd(Box& aBox) LOG(Tkhd, "Incomplete Box (missing flags)"); return; } - uint32_t flags = reader->ReadU32(); + uint32_t flags; + if (!reader->ReadU32(flags)) { + return; + } uint8_t version = flags >> 24; size_t need = 3*(version ? sizeof(int64_t) : sizeof(int32_t)) + 2*sizeof(int32_t); @@ -645,19 +679,30 @@ Tkhd::Tkhd(Box& aBox) return; } if (version == 0) { - mCreationTime = reader->ReadU32(); - mModificationTime = reader->ReadU32(); - mTrackId = reader->ReadU32(); - uint32_t reserved = reader->ReadU32(); + uint32_t createTime, modificationTime, trackId, reserved, duration; + if (!reader->ReadU32(createTime) || + !reader->ReadU32(modificationTime) || + !reader->ReadU32(trackId) || + !reader->ReadU32(reserved) || + !reader->ReadU32(duration)) { + return; + } NS_ASSERTION(!reserved, "reserved should be 0"); - mDuration = reader->ReadU32(); + mCreationTime = createTime; + mModificationTime = modificationTime; + mTrackId = trackId; + mDuration = duration; } else if (version == 1) { - mCreationTime = reader->ReadU64(); - mModificationTime = reader->ReadU64(); - mTrackId = reader->ReadU32(); - uint32_t reserved = reader->ReadU32(); + uint32_t trackId, reserved; + if (!reader->ReadU64(mCreationTime) || + !reader->ReadU64(mModificationTime) || + !reader->ReadU32(trackId) || + !reader->ReadU32(reserved) || + !reader->ReadU64(mDuration)) { + return; + } NS_ASSERTION(!reserved, "reserved should be 0"); - mDuration = reader->ReadU64(); + mTrackId = trackId; } // We don't care about whatever else may be in the box. mValid = true; @@ -670,10 +715,13 @@ Mvhd::Mvhd(Box& aBox) LOG(Mdhd, "Incomplete Box (missing flags)"); return; } - uint32_t flags = reader->ReadU32(); + uint32_t flags; + if (!reader->ReadU32(flags)) { + return; + } uint8_t version = flags >> 24; size_t need = - 3*(version ? sizeof(int64_t) : sizeof(int32_t)) + sizeof(uint32_t); + 3 * (version ? sizeof(int64_t) : sizeof(int32_t)) + sizeof(uint32_t); if (reader->Remaining() < need) { LOG(Mvhd, "Incomplete Box (have:%lld need:%lld)", (uint64_t)reader->Remaining(), (uint64_t)need); @@ -681,15 +729,23 @@ Mvhd::Mvhd(Box& aBox) } if (version == 0) { - mCreationTime = reader->ReadU32(); - mModificationTime = reader->ReadU32(); - mTimescale = reader->ReadU32(); - mDuration = reader->ReadU32(); + uint32_t createTime, modificationTime, duration; + if (!reader->ReadU32(createTime) || + !reader->ReadU32(modificationTime) || + !reader->ReadU32(mTimescale) || + !reader->ReadU32(duration)) { + return; + } + mCreationTime = createTime; + mModificationTime = modificationTime; + mDuration = duration; } else if (version == 1) { - mCreationTime = reader->ReadU64(); - mModificationTime = reader->ReadU64(); - mTimescale = reader->ReadU32(); - mDuration = reader->ReadU64(); + if (!reader->ReadU64(mCreationTime) || + !reader->ReadU64(mModificationTime) || + !reader->ReadU32(mTimescale) || + !reader->ReadU64(mDuration)) { + return; + } } else { return; } @@ -707,18 +763,19 @@ Mdhd::Mdhd(Box& aBox) Trex::Trex(Box& aBox) { BoxReader reader(aBox); - if (reader->Remaining() < 6*sizeof(uint32_t)) { + if (reader->Remaining() < 6 * sizeof(uint32_t)) { LOG(Trex, "Incomplete Box (have:%lld need:%lld)", (uint64_t)reader->Remaining(), (uint64_t)6*sizeof(uint32_t)); return; } - mFlags = reader->ReadU32(); - mTrackId = reader->ReadU32(); - mDefaultSampleDescriptionIndex = reader->ReadU32(); - mDefaultSampleDuration = reader->ReadU32(); - mDefaultSampleSize = reader->ReadU32(); - mDefaultSampleFlags = reader->ReadU32(); - mValid = true; + if (!reader->ReadU32(mFlags) || + !reader->ReadU32(mTrackId) || + !reader->ReadU32(mDefaultSampleDescriptionIndex) || + !reader->ReadU32(mDefaultSampleDuration) || + !reader->ReadU32(mDefaultSampleSize) || + !reader->ReadU32(mDefaultSampleFlags)) { + return; + } } Tfhd::Tfhd(Box& aBox, Trex& aTrex) @@ -733,7 +790,9 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex) LOG(Tfhd, "Incomplete Box (missing flags)"); return; } - mFlags = reader->ReadU32(); + if (!reader->ReadU32(mFlags)) { + return; + } 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) }; @@ -747,20 +806,34 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex) (uint64_t)reader->Remaining(), (uint64_t)need); return; } - mTrackId = reader->ReadU32(); - mBaseDataOffset = - mFlags & 1 ? reader->ReadU64() : aBox.Parent()->Parent()->Offset(); + if (!reader->ReadU32(mTrackId)) { + return; + } + mBaseDataOffset = aBox.Parent()->Parent()->Offset(); + if (mFlags & 1) { + if (!reader->ReadU64(mBaseDataOffset)) { + return; + } + } if (mFlags & 2) { - mDefaultSampleDescriptionIndex = reader->ReadU32(); + if (!reader->ReadU32(mDefaultSampleDescriptionIndex)) { + return; + } } if (mFlags & 8) { - mDefaultSampleDuration = reader->ReadU32(); + if (!reader->ReadU32(mDefaultSampleDuration)) { + return; + } } if (mFlags & 0x10) { - mDefaultSampleSize = reader->ReadU32(); + if (!reader->ReadU32(mDefaultSampleSize)) { + return; + } } if (mFlags & 0x20) { - mDefaultSampleFlags = reader->ReadU32(); + if (!reader->ReadU32(mDefaultSampleFlags)) { + return; + } } mValid = true; } @@ -772,7 +845,10 @@ Tfdt::Tfdt(Box& aBox) LOG(Tfdt, "Incomplete Box (missing flags)"); return; } - uint32_t flags = reader->ReadU32(); + uint32_t flags; + if (!reader->ReadU32(flags)) { + return; + } uint8_t version = flags >> 24; size_t need = version ? sizeof(uint64_t) : sizeof(uint32_t) ; if (reader->Remaining() < need) { @@ -781,9 +857,15 @@ Tfdt::Tfdt(Box& aBox) return; } if (version == 0) { - mBaseMediaDecodeTime = reader->ReadU32(); + uint32_t baseDecodeTime; + if (!reader->ReadU32(baseDecodeTime)) { + return; + } + mBaseMediaDecodeTime = baseDecodeTime; } else if (version == 1) { - mBaseMediaDecodeTime = reader->ReadU64(); + if (!reader->ReadU64(mBaseMediaDecodeTime)) { + return; + } } mValid = true; } @@ -802,7 +884,10 @@ Edts::Edts(Box& aBox) LOG(Edts, "Incomplete Box (missing flags)"); return; } - uint32_t flags = reader->ReadU32(); + uint32_t flags; + if (!reader->ReadU32(flags)) { + return; + } uint8_t version = flags >> 24; size_t need = sizeof(uint32_t) + 2*(version ? sizeof(int64_t) : sizeof(uint32_t)); @@ -812,16 +897,27 @@ Edts::Edts(Box& aBox) return; } bool emptyEntry = false; - uint32_t entryCount = reader->ReadU32(); + uint32_t entryCount; + if (!reader->ReadU32(entryCount)) { + return; + } for (uint32_t i = 0; i < entryCount; i++) { uint64_t segment_duration; int64_t media_time; if (version == 1) { - segment_duration = reader->ReadU64(); - media_time = reader->Read64(); + if (!reader->ReadU64(segment_duration) || + !reader->Read64(media_time)) { + return; + } } else { - segment_duration = reader->ReadU32(); - media_time = reader->Read32(); + uint32_t duration; + int32_t time; + if (!reader->ReadU32(duration) || + !reader->Read32(time)) { + return; + } + segment_duration = duration; + media_time = time; } if (media_time == -1 && i) { LOG(Edts, "Multiple empty edit, not handled"); @@ -834,8 +930,12 @@ Edts::Edts(Box& aBox) } else { mMediaStart = media_time; } - reader->ReadU32(); // media_rate_integer and media_rate_fraction + // media_rate_integer and media_rate_fraction + if (!reader->Skip(4)) { + return; + } } + mValid = true; } Saiz::Saiz(Box& aBox, AtomType aDefaultType) @@ -847,7 +947,10 @@ Saiz::Saiz(Box& aBox, AtomType aDefaultType) LOG(Saiz, "Incomplete Box (missing flags)"); return; } - uint32_t flags = reader->ReadU32(); + uint32_t flags; + if (!reader->ReadU32(flags)) { + return; + } uint8_t version = flags >> 24; size_t need = ((flags & 1) ? 2*sizeof(uint32_t) : 0) + sizeof(uint8_t) + sizeof(uint32_t); @@ -857,11 +960,19 @@ Saiz::Saiz(Box& aBox, AtomType aDefaultType) return; } if (flags & 1) { - mAuxInfoType = reader->ReadU32(); - mAuxInfoTypeParameter = reader->ReadU32(); + uint32_t auxType; + if (!reader->ReadU32(auxType) || + !reader->ReadU32(mAuxInfoTypeParameter)) { + return; + } + mAuxInfoType = auxType; + } + uint8_t defaultSampleInfoSize; + uint32_t count; + if (!reader->ReadU8(defaultSampleInfoSize) || + !reader->ReadU32(count)) { + return; } - uint8_t defaultSampleInfoSize = reader->ReadU8(); - uint32_t count = reader->ReadU32(); if (defaultSampleInfoSize) { if (!mSampleInfoSize.SetLength(count, fallible)) { LOG(Saiz, "OOM"); @@ -886,19 +997,29 @@ Saio::Saio(Box& aBox, AtomType aDefaultType) LOG(Saio, "Incomplete Box (missing flags)"); return; } - uint32_t flags = reader->ReadU32(); + uint32_t flags; + if (!reader->ReadU32(flags)) { + return; + } uint8_t version = flags >> 24; - size_t need = ((flags & 1) ? (2*sizeof(uint32_t)) : 0) + sizeof(uint32_t); + size_t need = ((flags & 1) ? (2 * sizeof(uint32_t)) : 0) + sizeof(uint32_t); if (reader->Remaining() < need) { LOG(Saio, "Incomplete Box (have:%lld need:%lld)", (uint64_t)reader->Remaining(), (uint64_t)need); return; } if (flags & 1) { - mAuxInfoType = reader->ReadU32(); - mAuxInfoTypeParameter = reader->ReadU32(); + uint32_t auxType; + if (!reader->ReadU32(auxType) || + !reader->ReadU32(mAuxInfoTypeParameter)) { + return; + } + mAuxInfoType = auxType; + } + uint32_t count; + if (!reader->ReadU32(count)) { + return; } - 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)", @@ -910,12 +1031,20 @@ Saio::Saio(Box& aBox, AtomType aDefaultType) return; } if (version == 0) { + uint32_t offset; for (size_t i = 0; i < count; i++) { - MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU32(), fallible)); + if (!reader->ReadU32(offset)) { + return; + } + MOZ_ALWAYS_TRUE(mOffsets.AppendElement(offset, fallible)); } } else { + uint64_t offset; for (size_t i = 0; i < count; i++) { - MOZ_ALWAYS_TRUE(mOffsets.AppendElement(reader->ReadU64(), fallible)); + if (!reader->ReadU64(offset)) { + return; + } + MOZ_ALWAYS_TRUE(mOffsets.AppendElement(offset, fallible)); } } mValid = true; diff --git a/media/libstagefright/binding/SinfParser.cpp b/media/libstagefright/binding/SinfParser.cpp index 5cf3aa553..5f3a2889e 100644 --- a/media/libstagefright/binding/SinfParser.cpp +++ b/media/libstagefright/binding/SinfParser.cpp @@ -39,8 +39,13 @@ SinfParser::ParseSchm(Box& aBox) return; } - mozilla::Unused << reader->ReadU32(); // flags -- ignore - mSinf.mDefaultEncryptionType = reader->ReadU32(); + uint32_t type; + if (!reader->Skip(4) || + !reader->ReadU32(type)) { + NS_WARNING("Failed to parse schm data"); + return; + } + mSinf.mDefaultEncryptionType = type; } void @@ -62,11 +67,16 @@ SinfParser::ParseTenc(Box& aBox) return; } - mozilla::Unused << reader->ReadU32(); // flags -- ignore - - uint32_t isEncrypted = reader->ReadU24(); - mSinf.mDefaultIVSize = reader->ReadU8(); - memcpy(mSinf.mDefaultKeyID, reader->Read(16), 16); + uint32_t isEncrypted; + const uint8_t* key; + if (!reader->Skip(4) || // flags -- ignore + !reader->ReadU24(isEncrypted) || + !reader->ReadU8(mSinf.mDefaultIVSize) || + !reader->Read(16, &key)) { + NS_WARNING("Failed to parse tenc data"); + return; + } + memcpy(mSinf.mDefaultKeyID, key, 16); } } diff --git a/media/libstagefright/binding/include/mp4_demuxer/Box.h b/media/libstagefright/binding/include/mp4_demuxer/Box.h index f53404a1d..6612f6b49 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/Box.h +++ b/media/libstagefright/binding/include/mp4_demuxer/Box.h @@ -12,7 +12,7 @@ #include "MediaResource.h" #include "mozilla/EndianUtils.h" #include "mp4_demuxer/AtomType.h" -#include "mp4_demuxer/ByteReader.h" +#include "mp4_demuxer/BufferReader.h" using namespace mozilla; @@ -73,11 +73,11 @@ public: , mReader(mBuffer.Elements(), mBuffer.Length()) { } - ByteReader* operator->() { return &mReader; } + BufferReader* operator->() { return &mReader; } private: nsTArray mBuffer; - ByteReader mReader; + BufferReader mReader; }; } -- cgit v1.2.3