diff options
author | Andreas Huber <andih@google.com> | 2010-02-23 10:12:02 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-02-23 10:21:39 -0800 |
commit | 5ee0bce5e006610a06d6d8f3572098b1ccaded6d (patch) | |
tree | a9b9e4dbcd7f94be86f6e3773848f6f9369147e7 /media | |
parent | cfe79e9220c996ed9f60fbc00eebb23e7faba2f0 (diff) | |
download | frameworks_base-5ee0bce5e006610a06d6d8f3572098b1ccaded6d.zip frameworks_base-5ee0bce5e006610a06d6d8f3572098b1ccaded6d.tar.gz frameworks_base-5ee0bce5e006610a06d6d8f3572098b1ccaded6d.tar.bz2 |
Return runtime errors instead of asserting in MPEG4 file format validation, also add more validation to ensure presence of codec specific data for avc, aac and mpeg4.
related-to-bug: 2431967
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/MPEG4Extractor.cpp | 111 | ||||
-rw-r--r-- | media/libstagefright/include/MPEG4Extractor.h | 2 |
2 files changed, 87 insertions, 26 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 16635d3..a6053b3 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -463,7 +463,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return err; } } - CHECK_EQ(*offset, stop_offset); + + if (*offset != stop_offset) { + return ERROR_MALFORMED; + } return OK; } @@ -496,6 +499,23 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { } } + if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { + Track *track = new Track; + track->next = NULL; + if (mLastTrack) { + mLastTrack->next = track; + } else { + mFirstTrack = track; + } + mLastTrack = track; + + track->meta = new MetaData; + track->includes_expensive_metadata = false; + track->timescale = 0; + track->sampleTable = new SampleTable(mDataSource); + track->meta->setCString(kKeyMIMEType, "application/octet-stream"); + } + off_t stop_offset = *offset + chunk_size; *offset = data_offset; while (*offset < stop_offset) { @@ -504,9 +524,18 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return err; } } - CHECK_EQ(*offset, stop_offset); - if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { + if (*offset != stop_offset) { + return ERROR_MALFORMED; + } + + if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { + status_t err = verifyTrack(mLastTrack); + + if (err != OK) { + return err; + } + } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { mHaveMetadata = true; return UNKNOWN_ERROR; // Return a dummy error. @@ -516,7 +545,9 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { case FOURCC('t', 'k', 'h', 'd'): { - CHECK(chunk_data_size >= 4); + if (chunk_data_size < 4) { + return ERROR_MALFORMED; + } uint8_t version; if (mDataSource->readAt(data_offset, &version, 1) < 1) { @@ -562,21 +593,6 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { height = U32_AT(&buffer[80]); } - Track *track = new Track; - track->next = NULL; - if (mLastTrack) { - mLastTrack->next = track; - } else { - mFirstTrack = track; - } - mLastTrack = track; - - track->meta = new MetaData; - track->includes_expensive_metadata = false; - track->timescale = 0; - track->sampleTable = new SampleTable(mDataSource); - track->meta->setCString(kKeyMIMEType, "application/octet-stream"); - *offset += chunk_size; break; } @@ -670,7 +686,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { } uint8_t buffer[8]; - CHECK(chunk_data_size >= (off_t)sizeof(buffer)); + if (chunk_data_size < (off_t)sizeof(buffer)) { + return ERROR_MALFORMED; + } + if (mDataSource->readAt( data_offset, buffer, 8) < 8) { return ERROR_IO; @@ -696,7 +715,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return err; } } - CHECK_EQ(*offset, stop_offset); + + if (*offset != stop_offset) { + return ERROR_MALFORMED; + } break; } @@ -748,7 +770,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return err; } } - CHECK_EQ(*offset, stop_offset); + + if (*offset != stop_offset) { + return ERROR_MALFORMED; + } break; } @@ -792,7 +817,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return err; } } - CHECK_EQ(*offset, stop_offset); + + if (*offset != stop_offset) { + return ERROR_MALFORMED; + } break; } @@ -942,7 +970,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { case FOURCC('m', 'e', 't', 'a'): { uint8_t buffer[4]; - CHECK(chunk_data_size >= (off_t)sizeof(buffer)); + if (chunk_data_size < (off_t)sizeof(buffer)) { + return ERROR_MALFORMED; + } + if (mDataSource->readAt( data_offset, buffer, 4) < 4) { return ERROR_IO; @@ -961,7 +992,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return err; } } - CHECK_EQ(*offset, stop_offset); + + if (*offset != stop_offset) { + return ERROR_MALFORMED; + } break; } @@ -995,8 +1029,9 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { int64_t creationTime; if (header[0] == 1) { creationTime = U64_AT(&header[4]); + } else if (header[0] != 0) { + return ERROR_MALFORMED; } else { - CHECK_EQ(header[0], 0); creationTime = U32_AT(&header[4]); } @@ -1174,6 +1209,30 @@ sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { track->meta, mDataSource, track->timescale, track->sampleTable); } +// static +status_t MPEG4Extractor::verifyTrack(Track *track) { + const char *mime; + CHECK(track->meta->findCString(kKeyMIMEType, &mime)); + + uint32_t type; + const void *data; + size_t size; + if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { + if (!track->meta->findData(kKeyAVCC, &type, &data, &size) + || type != kTypeAVCC) { + return ERROR_MALFORMED; + } + } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) + || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { + if (!track->meta->findData(kKeyESDS, &type, &data, &size) + || type != kTypeESDS) { + return ERROR_MALFORMED; + } + } + + return OK; +} + status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( const void *esds_data, size_t esds_size) { ESDS esds(esds_data, esds_size); diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h index 3a63e88..9d35e0c 100644 --- a/media/libstagefright/include/MPEG4Extractor.h +++ b/media/libstagefright/include/MPEG4Extractor.h @@ -68,6 +68,8 @@ private: status_t updateAudioTrackInfoFromESDS_MPEG4Audio( const void *esds_data, size_t esds_size); + static status_t verifyTrack(Track *track); + MPEG4Extractor(const MPEG4Extractor &); MPEG4Extractor &operator=(const MPEG4Extractor &); }; |