From af0725a8870d572ad35641f7d102aeb969979d6f Mon Sep 17 00:00:00 2001 From: Kongqun Yang Date: Fri, 14 Mar 2014 11:42:11 -0700 Subject: [PATCH] Fix crash when parsing MP4 with MDAT before MOOV Exit gracefully rather than crash with segmentation fault. Bug: 13458666 Change-Id: Ic34bbd9aa2e2fa69c46a47f9cfeb326a910121a5 --- media/mp4/box_reader.cc | 4 ++++ media/mp4/box_reader.h | 5 ++++- media/mp4/mp4_media_parser.cc | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/media/mp4/box_reader.cc b/media/mp4/box_reader.cc index 2d7689c76b..2c6fe5fad3 100644 --- a/media/mp4/box_reader.cc +++ b/media/mp4/box_reader.cc @@ -35,6 +35,10 @@ BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf, if (!reader->ReadHeader(err)) 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())) { *err = true; return NULL; diff --git a/media/mp4/box_reader.h b/media/mp4/box_reader.h index 1a7261b31e..036124d9ae 100644 --- a/media/mp4/box_reader.h +++ b/media/mp4/box_reader.h @@ -30,7 +30,10 @@ class BoxReader : public BufferReader { /// @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 /// 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, const int buf_size, bool* err); diff --git a/media/mp4/mp4_media_parser.cc b/media/mp4/mp4_media_parser.cc index 25d9cf48fd..03f38d6b5d 100644 --- a/media/mp4/mp4_media_parser.cc +++ b/media/mp4/mp4_media_parser.cc @@ -108,6 +108,17 @@ bool MP4MediaParser::ParseBox(bool* err) { if (reader.get() == NULL) 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(). mdat_tail_ = queue_.head() + reader->size();