LoadCluster now checks for underflow

Change-Id: I5a1ad57753657f71075d0ad8ca39841e7aae9e57
This commit is contained in:
matthewjheaney
2010-11-29 11:55:55 -05:00
parent 157775ac74
commit cb7b24880f

View File

@@ -29,16 +29,11 @@ long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
assert(pReader); assert(pReader);
assert(pos >= 0); assert(pos >= 0);
long long total, available; #if 0
long hr = pReader->Length(&total, &available);
assert(hr >= 0);
assert(pos < available);
assert((available - pos) >= 1); //assume here max u-int len is 8
unsigned char b; unsigned char b;
hr = pReader->Read(pos, 1, &b); int hr = pReader->Read(pos, 1, &b);
if (hr < 0) if (hr < 0)
return hr; return hr;
@@ -86,10 +81,11 @@ long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
b = 0; //0000 0000 b = 0; //0000 0000
} }
assert((available - pos) >= len); //assert((available - pos) >= len);
long long result = b; long long result = b;
++pos; ++pos;
for (long i = 1; i < len; ++i) for (long i = 1; i < len; ++i)
{ {
hr = pReader->Read(pos, 1, &b); hr = pReader->Read(pos, 1, &b);
@@ -106,6 +102,66 @@ long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
} }
return result; return result;
#else
int status;
#ifdef _DEBUG
long long total, available;
status = pReader->Length(&total, &available);
assert(status >= 0);
assert(total > 0);
assert(available <= total);
assert(pos < available);
assert((available - pos) >= 1); //assume here max u-int len is 8
#endif
unsigned char b;
status = pReader->Read(pos, 1, &b);
if (status < 0) //error
return status;
if (status > 0) //interpreted as "underflow"
return E_BUFFER_NOT_FULL;
if (b == 0) //we can't handle u-int values larger than 8 bytes
return E_FILE_FORMAT_INVALID;
unsigned char m = 0x80;
len = 1;
while (!(b & m))
{
m >>= 1;
++len;
}
#ifdef _DEBUG
assert((available - pos) >= len);
#endif
long long result = b & (~m);
++pos;
for (int i = 1; i < len; ++i)
{
status = pReader->Read(pos, 1, &b);
if (status < 0)
return status;
if (status > 0)
return E_BUFFER_NOT_FULL;
result <<= 8;
result |= b;
++pos;
}
return result;
#endif
} }
long long mkvparser::GetUIntLength( long long mkvparser::GetUIntLength(
@@ -928,9 +984,7 @@ long long Segment::ParseHeaders()
assert(stop <= total); assert(stop <= total);
assert(m_pos <= stop); assert(m_pos <= stop);
bool bQuit = false; while (m_pos < stop)
while ((m_pos < stop) && !bQuit)
{ {
long long pos = m_pos; long long pos = m_pos;
@@ -952,6 +1006,9 @@ long long Segment::ParseHeaders()
if (id < 0) //error if (id < 0) //error
return id; return id;
if (id == 0x0F43B675) //Cluster ID
break;
pos += len; //consume ID pos += len; //consume ID
//Read Size //Read Size
@@ -1009,12 +1066,7 @@ long long Segment::ParseHeaders()
{ {
ParseSeekHead(pos, size); ParseSeekHead(pos, size);
} }
else if (id == 0x0F43B675) //Cluster ID
{
bQuit = true;
}
if (!bQuit)
m_pos = pos + size; //consume payload m_pos = pos + size; //consume payload
} }
@@ -1194,6 +1246,9 @@ long Segment::LoadCluster()
if (result < 0) //error if (result < 0) //error
return static_cast<long>(result); return static_cast<long>(result);
if (result > 0)
return E_BUFFER_NOT_FULL;
if ((pos + len) > stop) if ((pos + len) > stop)
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
@@ -1211,6 +1266,9 @@ long Segment::LoadCluster()
if (result < 0) //error if (result < 0) //error
return static_cast<long>(result); return static_cast<long>(result);
if (result > 0)
return E_BUFFER_NOT_FULL;
if ((pos + len) > stop) if ((pos + len) > stop)
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
@@ -1232,6 +1290,16 @@ long Segment::LoadCluster()
if ((pos + size) > stop) if ((pos + size) > stop)
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
long long total, avail;
const int status = m_pReader->Length(&total, &avail);
assert(status == 0);
assert(total >= 0);
assert(avail <= total);
if ((pos + size) > avail)
return E_BUFFER_NOT_FULL;
if (id == 0x0C53BB6B) //Cues ID if (id == 0x0C53BB6B) //Cues ID
{ {
if (m_pCues == NULL) if (m_pCues == NULL)