diff options
author | Moonchild <mcwerewolf@gmail.com> | 2018-07-22 17:49:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-22 17:49:14 +0200 |
commit | 72e628874a7b96d33fa550626be56e334dda50c8 (patch) | |
tree | fad6ef6a185545083e56c63983540186c0d51f8d | |
parent | 14c53fcf71dbcae1472b4713817ac3851cd22b77 (diff) | |
parent | 0adebd32d9edaf37ef2396408d4fd76a9b255872 (diff) | |
download | UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar.gz UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar.lz UXP-72e628874a7b96d33fa550626be56e334dda50c8.tar.xz UXP-72e628874a7b96d33fa550626be56e334dda50c8.zip |
Merge pull request #665 from trav90/media-work
Add some error handling when parsing MP4 files
-rw-r--r-- | media/libstagefright/binding/MoofParser.cpp | 273 | ||||
-rw-r--r-- | media/libstagefright/binding/SinfParser.cpp | 24 | ||||
-rw-r--r-- | media/libstagefright/binding/include/mp4_demuxer/Box.h | 6 | ||||
-rw-r--r-- | media/libstagefright/binding/include/mp4_demuxer/BufferReader.h | 225 | ||||
-rw-r--r-- | media/libstagefright/binding/include/mp4_demuxer/ByteReader.h | 38 | ||||
-rw-r--r-- | media/libstagefright/moz.build | 1 |
6 files changed, 467 insertions, 100 deletions
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<uint32_t>()) { 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<Interval<Microseconds>> 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<uint8_t> mBuffer; - ByteReader mReader; + BufferReader mReader; }; } diff --git a/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h b/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h new file mode 100644 index 000000000..160c97fa0 --- /dev/null +++ b/media/libstagefright/binding/include/mp4_demuxer/BufferReader.h @@ -0,0 +1,225 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BUFFER_READER_H_ +#define BUFFER_READER_H_ + +#include "mozilla/EndianUtils.h" +#include "mozilla/Vector.h" +#include "nsTArray.h" +#include "MediaData.h" + +namespace mp4_demuxer { + +class MOZ_RAII BufferReader +{ +public: + BufferReader() : mPtr(nullptr), mRemaining(0) {} + explicit BufferReader(const mozilla::Vector<uint8_t>& aData) + : mPtr(aData.begin()), mRemaining(aData.length()), mLength(aData.length()) + { + } + BufferReader(const uint8_t* aData, size_t aSize) + : mPtr(aData), mRemaining(aSize), mLength(aSize) + { + } + template<size_t S> + explicit BufferReader(const AutoTArray<uint8_t, S>& aData) + : mPtr(aData.Elements()), mRemaining(aData.Length()), mLength(aData.Length()) + { + } + explicit BufferReader(const nsTArray<uint8_t>& aData) + : mPtr(aData.Elements()), mRemaining(aData.Length()), mLength(aData.Length()) + { + } + explicit BufferReader(const mozilla::MediaByteBuffer* aData) + : mPtr(aData->Elements()), mRemaining(aData->Length()), mLength(aData->Length()) + { + } + + void SetData(const nsTArray<uint8_t>& aData) + { + MOZ_ASSERT(!mPtr && !mRemaining); + mPtr = aData.Elements(); + mRemaining = aData.Length(); + mLength = mRemaining; + } + + ~BufferReader() + { + } + + size_t Offset() const + { + return mLength - mRemaining; + } + + size_t Remaining() const { return mRemaining; } + + bool CanRead8() const { return mRemaining >= 1; } + + bool ReadU8(uint8_t& aU8) + { + const uint8_t* ptr; + if (!Read(1, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + aU8 = *ptr; + return true; + } + + bool CanRead16() { return mRemaining >= 2; } + + bool ReadU16(uint16_t& u16) + { + const uint8_t* ptr; + if (!Read(2, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u16 = mozilla::BigEndian::readUint16(ptr); + return true; + } + + bool CanRead32() { return mRemaining >= 4; } + + bool ReadU32(uint32_t& u32) + { + const uint8_t* ptr; + if (!Read(4, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u32 = mozilla::BigEndian::readUint32(ptr); + return true; + } + + bool Read32(int32_t& i32) + { + const uint8_t* ptr; + if (!Read(4, &ptr)) { + NS_WARNING("Failed to read data"); + return 0; + } + i32 = mozilla::BigEndian::readInt32(ptr); + return true; + } + + bool ReadU64(uint64_t& u64) + { + const uint8_t* ptr; + if (!Read(8, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u64 = mozilla::BigEndian::readUint64(ptr); + return true; + } + + bool Read64(int64_t& i64) + { + const uint8_t* ptr; + if (!Read(8, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + i64 = mozilla::BigEndian::readInt64(ptr); + return true; + } + + bool ReadU24(uint32_t& u32) + { + const uint8_t* ptr; + if (!Read(3, &ptr)) { + NS_WARNING("Failed to read data"); + return false; + } + u32 = ptr[0] << 16 | ptr[1] << 8 | ptr[2]; + return true; + } + + bool Skip(size_t aCount) + { + const uint8_t* ptr; + if (!Read(aCount, &ptr)) { + NS_WARNING("Failed to skip data"); + return false; + } + return true; + } + + bool Read(size_t aCount, const uint8_t** aPtr) + { + if (aCount > mRemaining) { + mRemaining = 0; + return false; + } + mRemaining -= aCount; + + *aPtr = mPtr; + mPtr += aCount; + + return true; + } + + uint32_t Align() const + { + return 4 - ((intptr_t)mPtr & 3); + } + + template <typename T> bool CanReadType() const { return mRemaining >= sizeof(T); } + + template <typename T> T ReadType() + { + const uint8_t* ptr; + if (!Read(sizeof(T), &ptr)) { + NS_WARNING("ReadType failed"); + return 0; + } + return *reinterpret_cast<const T*>(ptr); + } + + template <typename T> + MOZ_MUST_USE bool ReadArray(nsTArray<T>& aDest, size_t aLength) + { + const uint8_t* ptr; + if (!Read(aLength * sizeof(T), &ptr)) { + NS_WARNING("ReadArray failed"); + 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) + { + const uint8_t* ptr; + if (!Read(aLength * sizeof(T), &ptr)) { + NS_WARNING("ReadArray failed"); + 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; +}; + +} // namespace mp4_demuxer + +#endif diff --git a/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h b/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h index 9c7df04bd..f316daa41 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h +++ b/media/libstagefright/binding/include/mp4_demuxer/ByteReader.h @@ -63,7 +63,7 @@ public: { auto ptr = Read(1); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return *ptr; @@ -75,7 +75,7 @@ public: { auto ptr = Read(2); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readUint16(ptr); @@ -85,7 +85,7 @@ public: { auto ptr = Read(2); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::LittleEndian::readInt16(ptr); @@ -95,7 +95,7 @@ public: { auto ptr = Read(3); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; @@ -110,7 +110,7 @@ public: { auto ptr = Read(3); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } int32_t result = int32_t(ptr[2] << 16 | ptr[1] << 8 | ptr[0]); @@ -126,7 +126,7 @@ public: { auto ptr = Read(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readUint32(ptr); @@ -136,7 +136,7 @@ public: { auto ptr = Read(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readInt32(ptr); @@ -146,7 +146,7 @@ public: { auto ptr = Read(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readUint64(ptr); @@ -156,7 +156,7 @@ public: { auto ptr = Read(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to read data"); return 0; } return mozilla::BigEndian::readInt64(ptr); @@ -192,7 +192,7 @@ public: { auto ptr = Peek(1); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return *ptr; @@ -202,7 +202,7 @@ public: { auto ptr = Peek(2); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readUint16(ptr); @@ -212,7 +212,7 @@ public: { auto ptr = Peek(3); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; @@ -227,7 +227,7 @@ public: { auto ptr = Peek(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readUint32(ptr); @@ -237,7 +237,7 @@ public: { auto ptr = Peek(4); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readInt32(ptr); @@ -247,7 +247,7 @@ public: { auto ptr = Peek(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readUint64(ptr); @@ -257,7 +257,7 @@ public: { auto ptr = Peek(8); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("Failed to peek data"); return 0; } return mozilla::BigEndian::readInt64(ptr); @@ -274,7 +274,7 @@ public: const uint8_t* Seek(size_t aOffset) { if (aOffset >= mLength) { - MOZ_ASSERT(false); + NS_WARNING("Seek failed"); return nullptr; } @@ -301,7 +301,7 @@ public: { auto ptr = Read(sizeof(T)); if (!ptr) { - MOZ_ASSERT(false); + NS_WARNING("ReadType failed"); return 0; } return *reinterpret_cast<const T*>(ptr); @@ -312,6 +312,7 @@ public: { auto ptr = Read(aLength * sizeof(T)); if (!ptr) { + NS_WARNING("ReadArray failed"); return false; } @@ -325,6 +326,7 @@ public: { auto ptr = Read(aLength * sizeof(T)); if (!ptr) { + NS_WARNING("ReadArray failed"); return false; } diff --git a/media/libstagefright/moz.build b/media/libstagefright/moz.build index c6072d840..5a8c9521a 100644 --- a/media/libstagefright/moz.build +++ b/media/libstagefright/moz.build @@ -53,6 +53,7 @@ EXPORTS.mp4_demuxer += [ 'binding/include/mp4_demuxer/Atom.h', 'binding/include/mp4_demuxer/AtomType.h', 'binding/include/mp4_demuxer/BitReader.h', + 'binding/include/mp4_demuxer/BufferReader.h', 'binding/include/mp4_demuxer/BufferStream.h', 'binding/include/mp4_demuxer/ByteReader.h', 'binding/include/mp4_demuxer/ByteWriter.h', |