Remove top level box check in BoxReader
Change-Id: I3d0e5865851030264d7174031a98031b413e90ce
This commit is contained in:
parent
bd1328500c
commit
84f3911985
|
@ -49,7 +49,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
|
||||||
buffer_->AppendInt(static_cast<uint32_t>(FOURCC_skip));
|
buffer_->AppendInt(static_cast<uint32_t>(FOURCC_skip));
|
||||||
buffer_->AppendBuffer(buffer);
|
buffer_->AppendBuffer(buffer);
|
||||||
bool err = false;
|
bool err = false;
|
||||||
return BoxReader::ReadTopLevelBox(buffer_->Buffer(), buffer_->Size(), &err);
|
return BoxReader::ReadBox(buffer_->Buffer(), buffer_->Size(), &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadBack(Box* box) {
|
bool ReadBack(Box* box) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ BoxReader::~BoxReader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
BoxReader* BoxReader::ReadTopLevelBox(const uint8_t* buf,
|
BoxReader* BoxReader::ReadBox(const uint8_t* buf,
|
||||||
const size_t buf_size,
|
const size_t buf_size,
|
||||||
bool* err) {
|
bool* err) {
|
||||||
scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size));
|
scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size));
|
||||||
|
@ -45,11 +45,6 @@ BoxReader* BoxReader::ReadTopLevelBox(const uint8_t* buf,
|
||||||
if (reader->type() == FOURCC_mdat)
|
if (reader->type() == FOURCC_mdat)
|
||||||
return reader.release();
|
return reader.release();
|
||||||
|
|
||||||
if (!IsValidTopLevelBox(reader->type())) {
|
|
||||||
*err = true;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->size() <= buf_size)
|
if (reader->size() <= buf_size)
|
||||||
return reader.release();
|
return reader.release();
|
||||||
|
|
||||||
|
@ -57,7 +52,7 @@ BoxReader* BoxReader::ReadTopLevelBox(const uint8_t* buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool BoxReader::StartTopLevelBox(const uint8_t* buf,
|
bool BoxReader::StartBox(const uint8_t* buf,
|
||||||
const size_t buf_size,
|
const size_t buf_size,
|
||||||
FourCC* type,
|
FourCC* type,
|
||||||
uint64_t* box_size,
|
uint64_t* box_size,
|
||||||
|
@ -65,42 +60,11 @@ bool BoxReader::StartTopLevelBox(const uint8_t* buf,
|
||||||
BoxReader reader(buf, buf_size);
|
BoxReader reader(buf, buf_size);
|
||||||
if (!reader.ReadHeader(err))
|
if (!reader.ReadHeader(err))
|
||||||
return false;
|
return false;
|
||||||
if (!IsValidTopLevelBox(reader.type())) {
|
|
||||||
*err = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*type = reader.type();
|
*type = reader.type();
|
||||||
*box_size = reader.size();
|
*box_size = reader.size();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
bool BoxReader::IsValidTopLevelBox(const FourCC& type) {
|
|
||||||
switch (type) {
|
|
||||||
case FOURCC_ftyp:
|
|
||||||
case FOURCC_pdin:
|
|
||||||
case FOURCC_bloc:
|
|
||||||
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:
|
|
||||||
case FOURCC_uuid:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
// Hex is used to show nonprintable characters and aid in debugging
|
|
||||||
LOG(ERROR) << "Unrecognized top-level box type 0x" << std::hex << type;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoxReader::ScanChildren() {
|
bool BoxReader::ScanChildren() {
|
||||||
DCHECK(!scanned_);
|
DCHECK(!scanned_);
|
||||||
scanned_ = true;
|
scanned_ = true;
|
||||||
|
|
|
@ -35,7 +35,7 @@ class BoxReader : public BufferReader {
|
||||||
/// function may return NULL if an intact, complete box is not
|
/// function may return NULL if an intact, complete box is not
|
||||||
/// available in the buffer. For MDAT box only, a BoxReader object is
|
/// available in the buffer. For MDAT box only, a BoxReader object is
|
||||||
/// returned as long as the box header is available.
|
/// returned as long as the box header is available.
|
||||||
static BoxReader* ReadTopLevelBox(const uint8_t* buf,
|
static BoxReader* ReadBox(const uint8_t* buf,
|
||||||
const size_t buf_size,
|
const size_t buf_size,
|
||||||
bool* err);
|
bool* err);
|
||||||
|
|
||||||
|
@ -48,18 +48,12 @@ class BoxReader : public BufferReader {
|
||||||
/// reading the box.
|
/// reading the box.
|
||||||
/// @return true if there is enough data to read the header and the header is
|
/// @return true if there is enough data to read the header and the header is
|
||||||
/// sane, which does not imply that the entire box is in the buffer.
|
/// sane, which does not imply that the entire box is in the buffer.
|
||||||
static bool StartTopLevelBox(const uint8_t* buf,
|
static bool StartBox(const uint8_t* buf,
|
||||||
const size_t buf_size,
|
const size_t buf_size,
|
||||||
FourCC* type,
|
FourCC* type,
|
||||||
uint64_t* box_size,
|
uint64_t* box_size,
|
||||||
bool* err) WARN_UNUSED_RESULT;
|
bool* err) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/// @return true if @a type is recognized to be the fourcc of a top-level box,
|
|
||||||
/// false otherwise. This returns true for some boxes which we do not
|
|
||||||
/// parse.
|
|
||||||
/// This method is helpful for debugging misaligned appends.
|
|
||||||
static bool IsValidTopLevelBox(const FourCC& type);
|
|
||||||
|
|
||||||
/// Scan through all boxes within the current box, starting at the current
|
/// Scan through all boxes within the current box, starting at the current
|
||||||
/// buffer position. Must be called before any of the @b *Child functions
|
/// buffer position. Must be called before any of the @b *Child functions
|
||||||
/// work.
|
/// work.
|
||||||
|
|
|
@ -93,8 +93,7 @@ class BoxReaderTest : public testing::Test {
|
||||||
TEST_F(BoxReaderTest, ExpectedOperationTest) {
|
TEST_F(BoxReaderTest, ExpectedOperationTest) {
|
||||||
std::vector<uint8_t> buf = GetBuf();
|
std::vector<uint8_t> buf = GetBuf();
|
||||||
bool err;
|
bool err;
|
||||||
scoped_ptr<BoxReader> reader(
|
scoped_ptr<BoxReader> reader(BoxReader::ReadBox(&buf[0], buf.size(), &err));
|
||||||
BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err));
|
|
||||||
EXPECT_FALSE(err);
|
EXPECT_FALSE(err);
|
||||||
EXPECT_TRUE(reader.get());
|
EXPECT_TRUE(reader.get());
|
||||||
|
|
||||||
|
@ -121,8 +120,7 @@ TEST_F(BoxReaderTest, OuterTooShortTest) {
|
||||||
bool err;
|
bool err;
|
||||||
|
|
||||||
// Create a soft failure by truncating the outer box.
|
// Create a soft failure by truncating the outer box.
|
||||||
scoped_ptr<BoxReader> r(
|
scoped_ptr<BoxReader> r(BoxReader::ReadBox(&buf[0], buf.size() - 2, &err));
|
||||||
BoxReader::ReadTopLevelBox(&buf[0], buf.size() - 2, &err));
|
|
||||||
|
|
||||||
EXPECT_FALSE(err);
|
EXPECT_FALSE(err);
|
||||||
EXPECT_FALSE(r.get());
|
EXPECT_FALSE(r.get());
|
||||||
|
@ -134,30 +132,16 @@ TEST_F(BoxReaderTest, InnerTooLongTest) {
|
||||||
|
|
||||||
// Make an inner box too big for its outer box.
|
// Make an inner box too big for its outer box.
|
||||||
buf[25] = 1;
|
buf[25] = 1;
|
||||||
scoped_ptr<BoxReader> reader(
|
scoped_ptr<BoxReader> reader(BoxReader::ReadBox(&buf[0], buf.size(), &err));
|
||||||
BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err));
|
|
||||||
|
|
||||||
SkipBox box;
|
SkipBox box;
|
||||||
EXPECT_FALSE(box.Parse(reader.get()));
|
EXPECT_FALSE(box.Parse(reader.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BoxReaderTest, WrongFourCCTest) {
|
|
||||||
std::vector<uint8_t> buf = GetBuf();
|
|
||||||
bool err;
|
|
||||||
|
|
||||||
// Set an unrecognized top-level FourCC.
|
|
||||||
buf[5] = 1;
|
|
||||||
scoped_ptr<BoxReader> reader(
|
|
||||||
BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err));
|
|
||||||
EXPECT_FALSE(reader.get());
|
|
||||||
EXPECT_TRUE(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BoxReaderTest, ScanChildrenTest) {
|
TEST_F(BoxReaderTest, ScanChildrenTest) {
|
||||||
std::vector<uint8_t> buf = GetBuf();
|
std::vector<uint8_t> buf = GetBuf();
|
||||||
bool err;
|
bool err;
|
||||||
scoped_ptr<BoxReader> reader(
|
scoped_ptr<BoxReader> reader(BoxReader::ReadBox(&buf[0], buf.size(), &err));
|
||||||
BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err));
|
|
||||||
|
|
||||||
EXPECT_TRUE(reader->SkipBytes(16) && reader->ScanChildren());
|
EXPECT_TRUE(reader->SkipBytes(16) && reader->ScanChildren());
|
||||||
|
|
||||||
|
@ -180,8 +164,7 @@ TEST_F(BoxReaderTest, ReadAllChildrenTest) {
|
||||||
// Modify buffer to exclude its last 'free' box.
|
// Modify buffer to exclude its last 'free' box.
|
||||||
buf[3] = 0x38;
|
buf[3] = 0x38;
|
||||||
bool err;
|
bool err;
|
||||||
scoped_ptr<BoxReader> reader(
|
scoped_ptr<BoxReader> reader(BoxReader::ReadBox(&buf[0], buf.size(), &err));
|
||||||
BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err));
|
|
||||||
|
|
||||||
std::vector<PsshBox> kids;
|
std::vector<PsshBox> kids;
|
||||||
EXPECT_TRUE(reader->SkipBytes(16) && reader->ReadAllChildren(&kids));
|
EXPECT_TRUE(reader->SkipBytes(16) && reader->ReadAllChildren(&kids));
|
||||||
|
@ -190,21 +173,16 @@ TEST_F(BoxReaderTest, ReadAllChildrenTest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BoxReaderTest, SkippingBloc) {
|
TEST_F(BoxReaderTest, SkippingBloc) {
|
||||||
static const uint8_t kData[] = {0x00,
|
static const uint8_t kData[] = {
|
||||||
0x00,
|
0x00, 0x00, 0x00, 0x09, // Box size.
|
||||||
0x00,
|
'b', 'l', 'o', 'c', // FourCC.
|
||||||
0x09, // Box size.
|
0x00, // Reserved byte.
|
||||||
'b',
|
};
|
||||||
'l',
|
|
||||||
'o',
|
|
||||||
'c', // FourCC.
|
|
||||||
0x00}; // Reserved byte.
|
|
||||||
|
|
||||||
std::vector<uint8_t> buf(kData, kData + sizeof(kData));
|
std::vector<uint8_t> buf(kData, kData + sizeof(kData));
|
||||||
|
|
||||||
bool err;
|
bool err;
|
||||||
scoped_ptr<BoxReader> reader(
|
scoped_ptr<BoxReader> reader(BoxReader::ReadBox(&buf[0], buf.size(), &err));
|
||||||
BoxReader::ReadTopLevelBox(&buf[0], buf.size(), &err));
|
|
||||||
|
|
||||||
EXPECT_FALSE(err);
|
EXPECT_FALSE(err);
|
||||||
EXPECT_TRUE(reader);
|
EXPECT_TRUE(reader);
|
||||||
|
|
|
@ -192,10 +192,9 @@ bool MP4MediaParser::LoadMoov(const std::string& file_path) {
|
||||||
uint64_t box_size;
|
uint64_t box_size;
|
||||||
FourCC box_type;
|
FourCC box_type;
|
||||||
bool err;
|
bool err;
|
||||||
if (!BoxReader::StartTopLevelBox(&buffer[0], kBoxHeaderReadSize, &box_type,
|
if (!BoxReader::StartBox(&buffer[0], kBoxHeaderReadSize, &box_type,
|
||||||
&box_size, &err)) {
|
&box_size, &err)) {
|
||||||
LOG(ERROR) << "Could not start top level box from file '" << file_path
|
LOG(ERROR) << "Could not start box from file '" << file_path << "'";
|
||||||
<< "'";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (box_type == FOURCC_mdat) {
|
if (box_type == FOURCC_mdat) {
|
||||||
|
@ -245,7 +244,7 @@ bool MP4MediaParser::ParseBox(bool* err) {
|
||||||
if (!size)
|
if (!size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
scoped_ptr<BoxReader> reader(BoxReader::ReadTopLevelBox(buf, size, err));
|
scoped_ptr<BoxReader> reader(BoxReader::ReadBox(buf, size, err));
|
||||||
if (reader.get() == NULL)
|
if (reader.get() == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -749,7 +748,7 @@ bool MP4MediaParser::ReadAndDiscardMDATsUntil(const int64_t offset) {
|
||||||
|
|
||||||
FourCC type;
|
FourCC type;
|
||||||
uint64_t box_sz;
|
uint64_t box_sz;
|
||||||
if (!BoxReader::StartTopLevelBox(buf, size, &type, &box_sz, &err))
|
if (!BoxReader::StartBox(buf, size, &type, &box_sz, &err))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mdat_tail_ += box_sz;
|
mdat_tail_ += box_sz;
|
||||||
|
|
Loading…
Reference in New Issue