mkvparser: Add error checking in Block::Parse.

Instead of relying solely on asserts, which compile away to
nothing in downstream projects using libwebm for parsing webm
input streams, actually check for the conditions being asserted,
and return errors when appropriate.

Change-Id: Id8b6352e8dda69782129dcea8f67203fd9c4f572
This commit is contained in:
Tom Finegan 2015-08-14 10:45:46 -07:00
parent 2dec09426a
commit 986b64b8c0

View File

@ -7240,12 +7240,17 @@ long Block::Parse(const Cluster* pCluster) {
++pos; // consume frame count ++pos; // consume frame count
assert(pos <= stop); assert(pos <= stop);
if (pos > stop)
return E_FILE_FORMAT_INVALID;
m_frame_count = int(biased_count) + 1; m_frame_count = int(biased_count) + 1;
m_frames = new Frame[m_frame_count]; m_frames = new Frame[m_frame_count];
assert(m_frames); assert(m_frames);
if (!m_frames)
return E_FILE_FORMAT_INVALID;
if (lacing == 1) { // Xiph if (lacing == 1) { // Xiph
Frame* pf = m_frames; Frame* pf = m_frames;
Frame* const pf_end = pf + m_frame_count; Frame* const pf_end = pf + m_frame_count;
@ -7277,6 +7282,8 @@ long Block::Parse(const Cluster* pCluster) {
Frame& f = *pf++; Frame& f = *pf++;
assert(pf < pf_end); assert(pf < pf_end);
if (pf >= pf_end)
return E_FILE_FORMAT_INVALID;
f.pos = 0; // patch later f.pos = 0; // patch later
@ -7291,6 +7298,8 @@ long Block::Parse(const Cluster* pCluster) {
assert(pf < pf_end); assert(pf < pf_end);
assert(pos <= stop); assert(pos <= stop);
if (pf >= pf_end || pos > stop)
return E_FILE_FORMAT_INVALID;
{ {
Frame& f = *pf++; Frame& f = *pf++;
@ -7318,11 +7327,17 @@ long Block::Parse(const Cluster* pCluster) {
Frame& f = *pf++; Frame& f = *pf++;
assert((pos + f.len) <= stop); assert((pos + f.len) <= stop);
if ((pos + f.len) > stop)
return E_FILE_FORMAT_INVALID;
f.pos = pos; f.pos = pos;
pos += f.len; pos += f.len;
} }
assert(pos == stop); assert(pos == stop);
if (pos != stop)
return E_FILE_FORMAT_INVALID;
} else if (lacing == 2) { // fixed-size lacing } else if (lacing == 2) { // fixed-size lacing
if (pos >= stop) if (pos >= stop)
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
@ -7342,6 +7357,8 @@ long Block::Parse(const Cluster* pCluster) {
while (pf != pf_end) { while (pf != pf_end) {
assert((pos + frame_size) <= stop); assert((pos + frame_size) <= stop);
if ((pos + frame_size) > stop)
return E_FILE_FORMAT_INVALID;
Frame& f = *pf++; Frame& f = *pf++;
@ -7352,6 +7369,9 @@ long Block::Parse(const Cluster* pCluster) {
} }
assert(pos == stop); assert(pos == stop);
if (pos != stop)
return E_FILE_FORMAT_INVALID;
} else { } else {
assert(lacing == 3); // EBML lacing assert(lacing == 3); // EBML lacing
@ -7396,6 +7416,9 @@ long Block::Parse(const Cluster* pCluster) {
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
assert(pf < pf_end); assert(pf < pf_end);
if (pf >= pf_end)
return E_FILE_FORMAT_INVALID;
const Frame& prev = *pf++; const Frame& prev = *pf++;
assert(prev.len == frame_size); assert(prev.len == frame_size);
@ -7403,6 +7426,8 @@ long Block::Parse(const Cluster* pCluster) {
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
assert(pf < pf_end); assert(pf < pf_end);
if (pf >= pf_end)
return E_FILE_FORMAT_INVALID;
Frame& curr = *pf; Frame& curr = *pf;
@ -7418,6 +7443,8 @@ long Block::Parse(const Cluster* pCluster) {
pos += len; // consume length of (delta) size pos += len; // consume length of (delta) size
assert(pos <= stop); assert(pos <= stop);
if (pos > stop)
return E_FILE_FORMAT_INVALID;
const int exp = 7 * len - 1; const int exp = 7 * len - 1;
const long long bias = (1LL << exp) - 1LL; const long long bias = (1LL << exp) - 1LL;
@ -7448,9 +7475,13 @@ long Block::Parse(const Cluster* pCluster) {
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
assert(pf < pf_end); assert(pf < pf_end);
if (pf >= pf_end)
return E_FILE_FORMAT_INVALID;
Frame& curr = *pf++; Frame& curr = *pf++;
assert(pf == pf_end); assert(pf == pf_end);
if (pf != pf_end)
return E_FILE_FORMAT_INVALID;
curr.pos = 0; // patch later curr.pos = 0; // patch later
@ -7471,6 +7502,8 @@ long Block::Parse(const Cluster* pCluster) {
while (pf != pf_end) { while (pf != pf_end) {
Frame& f = *pf++; Frame& f = *pf++;
assert((pos + f.len) <= stop); assert((pos + f.len) <= stop);
if ((pos + f.len) > stop)
return E_FILE_FORMAT_INVALID;
f.pos = pos; f.pos = pos;
pos += f.len; pos += f.len;