MPEG4Extractor: ensure returned status is checked. Also fix handling of zero atom size in MPEG4Source::parseChunk. IDataSource: ensure readAt returns correct status. Test: manually test with mediaplayer. Bug: 34718515 Change-Id: I1219ec579aa0876dc1230e36af46b158b84c6d77 (cherry picked from commit ff1fb4d5cdd3b2b28c69edd8cd3021e335ca381a) (cherry picked from commit 371561214467f848496928914f771703d6c331e6) Change-Id: Idfbee6317dfea21a526a0522f65fbcb67d92ab60
diff --git a/media/libmedia/IDataSource.cpp b/media/libmedia/IDataSource.cpp index 51c9938..5ad39fe 100644 --- a/media/libmedia/IDataSource.cpp +++ b/media/libmedia/IDataSource.cpp
@@ -54,8 +54,16 @@ data.writeInterfaceToken(IDataSource::getInterfaceDescriptor()); data.writeInt64(offset); data.writeInt64(size); - remote()->transact(READ_AT, data, &reply); - return reply.readInt64(); + status_t err = remote()->transact(READ_AT, data, &reply); + if (err != OK) { + return err; + } + int64_t value = 0; + err = reply.readInt64(&value); + if (err != OK) { + return err; + } + return (ssize_t)value; } virtual status_t getSize(off64_t* size) {
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index f6242d1..efaba41 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -71,6 +71,7 @@ Vector<SidxEntry> &sidx, const Trex *trex, off64_t firstMoofOffset); + virtual status_t init(); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); @@ -2102,7 +2103,10 @@ *offset += chunk_size; if (underQTMetaPath(mPath, 3)) { - parseQTMetaKey(data_offset, chunk_data_size); + status_t err = parseQTMetaKey(data_offset, chunk_data_size); + if (err != OK) { + return err; + } } break; } @@ -2261,7 +2265,10 @@ case FOURCC('s', 'i', 'd', 'x'): { - parseSegmentIndex(data_offset, chunk_data_size); + status_t err = parseSegmentIndex(data_offset, chunk_data_size); + if (err != OK) { + return err; + } *offset += chunk_size; return UNKNOWN_ERROR; // stop parsing after sidx } @@ -2271,7 +2278,10 @@ // check if we're parsing 'ilst' for meta keys // if so, treat type as a number (key-id). if (underQTMetaPath(mPath, 3)) { - parseQTMetaVal(chunk_type, data_offset, chunk_data_size); + status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size); + if (err != OK) { + return err; + } } *offset += chunk_size; @@ -3096,9 +3106,13 @@ } } - return new MPEG4Source(this, + sp<MPEG4Source> source = new MPEG4Source(this, track->meta, mDataSource, track->timescale, track->sampleTable, mSidxEntries, trex, mMoofOffset); + if (source->init() != OK) { + return NULL; + } + return source; } // static @@ -3495,6 +3509,7 @@ mTrex(trex), mFirstMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), + mNextMoofOffset(-1), mCurrentTime(0), mCurrentSampleInfoAllocSize(0), mCurrentSampleInfoSizes(NULL), @@ -3559,10 +3574,14 @@ CHECK(format->findInt32(kKeyTrackID, &mTrackId)); +} + +status_t MPEG4Source::init() { if (mFirstMoofOffset != 0) { off64_t offset = mFirstMoofOffset; - parseChunk(&offset); + return parseChunk(&offset); } + return OK; } MPEG4Source::~MPEG4Source() { @@ -3686,9 +3705,30 @@ } chunk_size = ntohl(hdr[0]); chunk_type = ntohl(hdr[1]); + if (chunk_size == 1) { + // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box + // which is defined in 4.2 Object Structure. + // When chunk_size==1, 8 bytes follows as "largesize". + if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { + return ERROR_IO; + } + chunk_size = ntoh64(chunk_size); + if (chunk_size < 16) { + // The smallest valid chunk is 16 bytes long in this case. + return ERROR_MALFORMED; + } + } else if (chunk_size == 0) { + // next box extends to end of file. + } else if (chunk_size < 8) { + // The smallest valid chunk is 8 bytes long in this case. + return ERROR_MALFORMED; + } + if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { mNextMoofOffset = *offset; break; + } else if (chunk_size == 0) { + break; } *offset += chunk_size; } @@ -4553,17 +4593,25 @@ totalOffset += se->mSize; } mCurrentMoofOffset = totalOffset; + mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSampleIndex = 0; - parseChunk(&totalOffset); + status_t err = parseChunk(&totalOffset); + if (err != OK) { + return err; + } mCurrentTime = totalTime * mTimescale / 1000000ll; } else { // without sidx boxes, we can only seek to 0 mCurrentMoofOffset = mFirstMoofOffset; + mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSampleIndex = 0; off64_t tmp = mCurrentMoofOffset; - parseChunk(&tmp); + status_t err = parseChunk(&tmp); + if (err != OK) { + return err; + } mCurrentTime = 0; } @@ -4592,7 +4640,10 @@ mCurrentMoofOffset = nextMoof; mCurrentSamples.clear(); mCurrentSampleIndex = 0; - parseChunk(&nextMoof); + status_t err = parseChunk(&nextMoof); + if (err != OK) { + return err; + } if (mCurrentSampleIndex >= mCurrentSamples.size()) { return ERROR_END_OF_STREAM; }