Fix crash when parsing MP4 with MDAT before MOOV

Exit gracefully rather than crash with segmentation fault.

Bug: 13458666
Change-Id: Ic34bbd9aa2e2fa69c46a47f9cfeb326a910121a5
This commit is contained in:
Kongqun Yang 2014-03-14 11:42:11 -07:00
parent aee2419c16
commit af0725a887
3 changed files with 19 additions and 1 deletions

View File

@ -35,6 +35,10 @@ BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf,
if (!reader->ReadHeader(err)) if (!reader->ReadHeader(err))
return NULL; return NULL;
// We don't require the complete box to be available for MDAT box.
if (reader->type() == FOURCC_MDAT)
return reader.release();
if (!IsValidTopLevelBox(reader->type())) { if (!IsValidTopLevelBox(reader->type())) {
*err = true; *err = true;
return NULL; return NULL;

View File

@ -30,7 +30,10 @@ class BoxReader : public BufferReader {
/// @param buf_size indicates the size of the input buffer. /// @param buf_size indicates the size of the input buffer.
/// @param[out] err is set to true if there was a stream-level error when /// @param[out] err is set to true if there was a stream-level error when
/// reading the box. /// reading the box.
/// @return New box reader if successful, NULL otherwise. /// @return New box reader if successful, NULL otherwise. Note that this
/// function may return NULL if an intact, complete box is not
/// available in the buffer. For MDAT box only, a BoxReader object is
/// returned as long as the box header is available.
static BoxReader* ReadTopLevelBox(const uint8* buf, static BoxReader* ReadTopLevelBox(const uint8* buf,
const int buf_size, const int buf_size,
bool* err); bool* err);

View File

@ -108,6 +108,17 @@ bool MP4MediaParser::ParseBox(bool* err) {
if (reader.get() == NULL) if (reader.get() == NULL)
return false; return false;
if (reader->type() == FOURCC_MDAT) {
// The code ends up here only if a MOOV box is not yet seen.
DCHECK(!moov_);
NOTIMPLEMENTED() << " Files with MDAT before MOOV is not supported yet.";
*err = true;
// TODO: Change to return a status so upper level can take appropriate
// actions based on the returned status.
return false;
}
// Set up mdat offset for ReadMDATsUntil(). // Set up mdat offset for ReadMDATsUntil().
mdat_tail_ = queue_.head() + reader->size(); mdat_tail_ = queue_.head() + reader->size();