summaryrefslogtreecommitdiffstats
path: root/media/mp4/box_reader.cc
diff options
context:
space:
mode:
authorstrobe@google.com <strobe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-02 23:15:18 +0000
committerstrobe@google.com <strobe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-02 23:15:18 +0000
commitfce177d8da4579e7db21a0078a79a1602fa6ef76 (patch)
tree53cbf6a28c45755ed500c032365d178fa6857c2d /media/mp4/box_reader.cc
parent3426ce1981d7ace455c51c5cc74fe80e5d2d5b4d (diff)
downloadchromium_src-fce177d8da4579e7db21a0078a79a1602fa6ef76.zip
chromium_src-fce177d8da4579e7db21a0078a79a1602fa6ef76.tar.gz
chromium_src-fce177d8da4579e7db21a0078a79a1602fa6ef76.tar.bz2
Set error on unrecognized top-level BMFF boxes.
A common error when using BMFF with Media Source is to begin appending at an incorrect offset, such that the parser sees an extremely large value for the box size and consequently waits forever for input without failing. This change adds a whitelist of permitted top-level boxes, which allows these situations to be detected as soon as the header is read. BUG= TEST=BoxReaderTest.WrongFourCCTest Review URL: https://chromiumcodereview.appspot.com/10823139 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149735 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/mp4/box_reader.cc')
-rw-r--r--media/mp4/box_reader.cc47
1 files changed, 43 insertions, 4 deletions
diff --git a/media/mp4/box_reader.cc b/media/mp4/box_reader.cc
index 8892a43..b352664 100644
--- a/media/mp4/box_reader.cc
+++ b/media/mp4/box_reader.cc
@@ -10,6 +10,7 @@
#include <set>
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "media/mp4/box_definitions.h"
#include "media/mp4/rcheck.h"
@@ -95,14 +96,22 @@ BoxReader::~BoxReader() {
}
}
+// static
BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf,
const int buf_size,
bool* err) {
- BoxReader* reader = new BoxReader(buf, buf_size);
- if (reader->ReadHeader(err) && reader->size() <= buf_size) {
- return reader;
+ scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size));
+ if (!reader->ReadHeader(err))
+ return NULL;
+
+ if (!IsValidTopLevelBox(reader->type())) {
+ *err = true;
+ return NULL;
}
- delete reader;
+
+ if (reader->size() <= buf_size)
+ return reader.release();
+
return NULL;
}
@@ -114,11 +123,41 @@ bool BoxReader::StartTopLevelBox(const uint8* buf,
bool* err) {
BoxReader reader(buf, buf_size);
if (!reader.ReadHeader(err)) return false;
+ if (!IsValidTopLevelBox(reader.type())) {
+ *err = true;
+ return false;
+ }
*type = reader.type();
*box_size = reader.size();
return true;
}
+// static
+bool BoxReader::IsValidTopLevelBox(const FourCC& type) {
+ switch (type) {
+ case FOURCC_FTYP:
+ case FOURCC_PDIN:
+ case FOURCC_MOOV:
+ case FOURCC_MOOF:
+ case FOURCC_MFRA:
+ case FOURCC_MDAT:
+ case FOURCC_FREE:
+ case FOURCC_SKIP:
+ case FOURCC_META:
+ case FOURCC_MECO:
+ case FOURCC_STYP:
+ case FOURCC_SIDX:
+ case FOURCC_SSIX:
+ case FOURCC_PRFT:
+ return true;
+ default:
+ // Hex is used to show nonprintable characters and aid in debugging
+ LOG(WARNING) << "Unrecognized top-level box type 0x"
+ << std::hex << type;
+ return false;
+ }
+}
+
bool BoxReader::ScanChildren() {
DCHECK(!scanned_);
scanned_ = true;