mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 16:28:38 +09:00
Rework MoofParser to return an error when the underlying BufferReader returns an error.
This commit is contained in:
parent
bee1316729
commit
d6f3f831c5
3 changed files with 221 additions and 82 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue