зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1116056: Ensure all atoms read are valid. r=mattwoodrow
--HG-- extra : rebase_source : 6d5575bd0886b70dec23e1bccb638b1591eef5e9
This commit is contained in:
Родитель
772dc9f60d
Коммит
dcd8fcb072
|
@ -94,7 +94,7 @@ Box::Read(nsTArray<uint8_t>* aDest)
|
|||
{
|
||||
aDest->SetLength(mRange.mEnd - mChildOffset);
|
||||
size_t bytes;
|
||||
if (!mContext->mSource->CachedReadAt(mChildOffset, &(*aDest)[0],
|
||||
if (!mContext->mSource->CachedReadAt(mChildOffset, aDest->Elements(),
|
||||
aDest->Length(), &bytes) ||
|
||||
bytes != aDest->Length()) {
|
||||
// Byte ranges are being reported incorrectly
|
||||
|
|
|
@ -286,21 +286,43 @@ public:
|
|||
void
|
||||
Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts)
|
||||
{
|
||||
if (!aMdhd.mTimescale) {
|
||||
if (!aTfhd.IsValid() || !aTfdt.IsValid() ||
|
||||
!aMdhd.IsValid() || !aEdts.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BoxReader reader(aBox);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t flags = reader->ReadU32();
|
||||
if ((flags & 0x404) == 0x404) {
|
||||
// Can't use these flags together
|
||||
reader->DiscardRemaining();
|
||||
mValid = true;
|
||||
return;
|
||||
}
|
||||
uint8_t version = flags >> 24;
|
||||
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t sampleCount = reader->ReadU32();
|
||||
if (sampleCount == 0) {
|
||||
mValid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -354,13 +376,22 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts)
|
|||
}
|
||||
mTimeRange = Interval<Microseconds>(ctsOrder[0]->mCompositionRange.start,
|
||||
ctsOrder.LastElement()->mCompositionRange.end);
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
Tkhd::Tkhd(Box& aBox)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t 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) {
|
||||
return;
|
||||
}
|
||||
if (version == 0) {
|
||||
mCreationTime = reader->ReadU32();
|
||||
mModificationTime = reader->ReadU32();
|
||||
|
@ -378,13 +409,23 @@ Tkhd::Tkhd(Box& aBox)
|
|||
}
|
||||
// More stuff that we don't care about
|
||||
reader->DiscardRemaining();
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
Mdhd::Mdhd(Box& aBox)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t flags = reader->ReadU32();
|
||||
uint8_t version = flags >> 24;
|
||||
size_t need =
|
||||
3*(version ? sizeof(int64_t) : sizeof(int32_t)) + 2*sizeof(uint32_t);
|
||||
if (reader->Remaining() < need) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
mCreationTime = reader->ReadU32();
|
||||
mModificationTime = reader->ReadU32();
|
||||
|
@ -398,17 +439,24 @@ Mdhd::Mdhd(Box& aBox)
|
|||
}
|
||||
// language and pre_defined=0
|
||||
reader->ReadU32();
|
||||
if (mTimescale) {
|
||||
mValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
Trex::Trex(Box& aBox)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
if (reader->Remaining() < 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;
|
||||
}
|
||||
|
||||
Tfhd::Tfhd(Box& aBox, Trex& aTrex) : Trex(aTrex)
|
||||
|
@ -418,7 +466,20 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex) : Trex(aTrex)
|
|||
MOZ_ASSERT(aBox.Parent()->Parent()->IsType("moof"));
|
||||
|
||||
BoxReader reader(aBox);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
mFlags = reader->ReadU32();
|
||||
size_t need = sizeof(uint32_t) /* trackid */;
|
||||
uint8_t flag[] = { 1, 2, 8, 0x10, 0x20, 0 };
|
||||
for (size_t i = 0; flag[i]; i++) {
|
||||
if (mFlags & flag[i]) {
|
||||
need += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
if (reader->Remaining() < need) {
|
||||
return;
|
||||
}
|
||||
mBaseDataOffset =
|
||||
mFlags & 1 ? reader->ReadU32() : aBox.Parent()->Parent()->Offset();
|
||||
mTrackId = reader->ReadU32();
|
||||
|
@ -434,19 +495,28 @@ Tfhd::Tfhd(Box& aBox, Trex& aTrex) : Trex(aTrex)
|
|||
if (mFlags & 0x20) {
|
||||
mDefaultSampleFlags = reader->ReadU32();
|
||||
}
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
Tfdt::Tfdt(Box& aBox)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t flags = reader->ReadU32();
|
||||
uint8_t version = flags >> 24;
|
||||
size_t need = version ? sizeof(uint64_t) : sizeof(uint32_t) ;
|
||||
if (reader->Remaining() < need) {
|
||||
return;
|
||||
}
|
||||
if (version == 0) {
|
||||
mBaseMediaDecodeTime = reader->ReadU32();
|
||||
} else if (version == 1) {
|
||||
mBaseMediaDecodeTime = reader->ReadU64();
|
||||
}
|
||||
reader->DiscardRemaining();
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
Edts::Edts(Box& aBox)
|
||||
|
@ -458,9 +528,16 @@ Edts::Edts(Box& aBox)
|
|||
}
|
||||
|
||||
BoxReader reader(child);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t 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) {
|
||||
return;
|
||||
}
|
||||
uint32_t entryCount = reader->ReadU32();
|
||||
NS_ASSERTION(entryCount == 1, "Can't handle videos with multiple edits");
|
||||
if (entryCount != 1) {
|
||||
|
@ -483,9 +560,16 @@ Edts::Edts(Box& aBox)
|
|||
Saiz::Saiz(Box& aBox) : mAuxInfoType("sinf"), mAuxInfoTypeParameter(0)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t 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) {
|
||||
return;
|
||||
}
|
||||
if (flags & 1) {
|
||||
mAuxInfoType = reader->ReadU32();
|
||||
mAuxInfoTypeParameter = reader->ReadU32();
|
||||
|
@ -497,21 +581,34 @@ Saiz::Saiz(Box& aBox) : mAuxInfoType("sinf"), mAuxInfoTypeParameter(0)
|
|||
mSampleInfoSize.AppendElement(defaultSampleInfoSize);
|
||||
}
|
||||
} else {
|
||||
reader->ReadArray(mSampleInfoSize, count);
|
||||
if (!reader->ReadArray(mSampleInfoSize, count)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
Saio::Saio(Box& aBox) : mAuxInfoType("sinf"), mAuxInfoTypeParameter(0)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
if (!reader->CanReadType<uint32_t>()) {
|
||||
return;
|
||||
}
|
||||
uint32_t 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) {
|
||||
return;
|
||||
}
|
||||
if (flags & 1) {
|
||||
mAuxInfoType = reader->ReadU32();
|
||||
mAuxInfoTypeParameter = reader->ReadU32();
|
||||
}
|
||||
size_t count = reader->ReadU32();
|
||||
need = (version ? sizeof(uint64_t) : sizeof(uint32_t)) * count;
|
||||
if (reader->Remaining() < count) {
|
||||
return;
|
||||
}
|
||||
mOffsets.SetCapacity(count);
|
||||
if (version == 0) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
|
@ -522,5 +619,6 @@ Saio::Saio(Box& aBox) : mAuxInfoType("sinf"), mAuxInfoTypeParameter(0)
|
|||
mOffsets.AppendElement(reader->ReadU64());
|
||||
}
|
||||
}
|
||||
mValid = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,14 +36,14 @@ public:
|
|||
void SetData(const nsTArray<uint8_t>& aData)
|
||||
{
|
||||
MOZ_ASSERT(!mPtr && !mRemaining);
|
||||
mPtr = &aData[0];
|
||||
mPtr = aData.Elements();
|
||||
mRemaining = aData.Length();
|
||||
mLength = mRemaining;
|
||||
}
|
||||
|
||||
~ByteReader()
|
||||
{
|
||||
MOZ_ASSERT(!mRemaining);
|
||||
NS_ASSERTION(!mRemaining, "Not all bytes have been processed");
|
||||
}
|
||||
|
||||
size_t Offset()
|
||||
|
|
|
@ -16,7 +16,22 @@ class Box;
|
|||
class BoxContext;
|
||||
class Moof;
|
||||
|
||||
class Tkhd
|
||||
class Atom
|
||||
{
|
||||
public:
|
||||
Atom()
|
||||
: mValid(false)
|
||||
{
|
||||
}
|
||||
virtual bool IsValid()
|
||||
{
|
||||
return mValid;
|
||||
}
|
||||
protected:
|
||||
bool mValid;
|
||||
};
|
||||
|
||||
class Tkhd : public Atom
|
||||
{
|
||||
public:
|
||||
Tkhd()
|
||||
|
@ -34,7 +49,7 @@ public:
|
|||
uint64_t mDuration;
|
||||
};
|
||||
|
||||
class Mdhd
|
||||
class Mdhd : public Atom
|
||||
{
|
||||
public:
|
||||
Mdhd()
|
||||
|
@ -57,7 +72,7 @@ public:
|
|||
uint64_t mDuration;
|
||||
};
|
||||
|
||||
class Trex
|
||||
class Trex : public Atom
|
||||
{
|
||||
public:
|
||||
explicit Trex(uint32_t aTrackId)
|
||||
|
@ -83,26 +98,42 @@ public:
|
|||
class Tfhd : public Trex
|
||||
{
|
||||
public:
|
||||
explicit Tfhd(Trex& aTrex) : Trex(aTrex), mBaseDataOffset(0) {}
|
||||
explicit Tfhd(Trex& aTrex)
|
||||
: Trex(aTrex)
|
||||
, mBaseDataOffset(0)
|
||||
{
|
||||
mValid = aTrex.IsValid();
|
||||
}
|
||||
Tfhd(Box& aBox, Trex& aTrex);
|
||||
|
||||
uint64_t mBaseDataOffset;
|
||||
};
|
||||
|
||||
class Tfdt
|
||||
class Tfdt : public Atom
|
||||
{
|
||||
public:
|
||||
Tfdt() : mBaseMediaDecodeTime(0) {}
|
||||
Tfdt()
|
||||
: mBaseMediaDecodeTime(0)
|
||||
{
|
||||
}
|
||||
explicit Tfdt(Box& aBox);
|
||||
|
||||
uint64_t mBaseMediaDecodeTime;
|
||||
};
|
||||
|
||||
class Edts
|
||||
class Edts : public Atom
|
||||
{
|
||||
public:
|
||||
Edts() : mMediaStart(0) {}
|
||||
Edts()
|
||||
: mMediaStart(0)
|
||||
{
|
||||
}
|
||||
explicit Edts(Box& aBox);
|
||||
virtual bool IsValid()
|
||||
{
|
||||
// edts is optional
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t mMediaStart;
|
||||
};
|
||||
|
@ -116,7 +147,7 @@ struct Sample
|
|||
bool mSync;
|
||||
};
|
||||
|
||||
class Saiz
|
||||
class Saiz : public Atom
|
||||
{
|
||||
public:
|
||||
explicit Saiz(Box& aBox);
|
||||
|
@ -126,7 +157,7 @@ public:
|
|||
nsTArray<uint8_t> mSampleInfoSize;
|
||||
};
|
||||
|
||||
class Saio
|
||||
class Saio : public Atom
|
||||
{
|
||||
public:
|
||||
explicit Saio(Box& aBox);
|
||||
|
@ -142,13 +173,12 @@ public:
|
|||
bool GetByteRanges(nsTArray<MediaByteRange>* aByteRanges);
|
||||
|
||||
private:
|
||||
|
||||
int64_t mMoofOffset;
|
||||
Saiz& mSaiz;
|
||||
Saio& mSaio;
|
||||
};
|
||||
|
||||
class Moof
|
||||
class Moof : public Atom
|
||||
{
|
||||
public:
|
||||
Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Microseconds aTimestampOffset);
|
||||
|
|
Загрузка…
Ссылка в новой задаче