Bug 1314533: P5. Abort when webm parser encounter an error. r?kinetik
MozReview-Commit-ID: 6XHthan8LLp
--- a/dom/media/webm/WebMBufferedParser.cpp
+++ b/dom/media/webm/WebMBufferedParser.cpp
@@ -28,17 +28,17 @@ VIntLength(unsigned char aFirstByte, uin
}
if (aMask) {
*aMask = mask;
}
NS_ASSERTION(count >= 1 && count <= 8, "Insane VInt length.");
return count;
}
-void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
+bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
nsTArray<WebMTimeDataOffset>& aMapping,
ReentrantMonitor& aReentrantMonitor)
{
static const uint32_t EBML_ID = 0x1a45dfa3;
static const uint32_t SEGMENT_ID = 0x18538067;
static const uint32_t SEGINFO_ID = 0x1549a966;
static const uint32_t TRACKS_ID = 0x1654AE6B;
static const uint32_t CLUSTER_ID = 0x1f43b675;
@@ -158,17 +158,19 @@ void WebMBufferedParser::Append(const un
mVInt.mValue <<= 8;
mVInt.mValue |= *p++;
mVIntLeft -= 1;
} else {
mState = mNextState;
}
break;
case READ_TIMECODESCALE:
- MOZ_ASSERT(mGotTimecodeScale);
+ if (!mGotTimecodeScale) {
+ return false;
+ }
mTimecodeScale = mVInt.mValue;
mState = READ_ELEMENT_ID;
break;
case READ_CLUSTER_TIMECODE:
mClusterTimecode = mVInt.mValue;
mState = READ_ELEMENT_ID;
break;
case READ_BLOCK_TIMECODE:
@@ -182,17 +184,19 @@ void WebMBufferedParser::Append(const un
{
ReentrantMonitorAutoEnter mon(aReentrantMonitor);
int64_t endOffset = mBlockOffset + mBlockSize +
mElement.mID.mLength + mElement.mSize.mLength;
uint32_t idx = aMapping.IndexOfFirstElementGt(endOffset);
if (idx == 0 || aMapping[idx - 1] != endOffset) {
// Don't insert invalid negative timecodes.
if (mBlockTimecode >= 0 || mClusterTimecode >= uint16_t(abs(mBlockTimecode))) {
- MOZ_ASSERT(mGotTimecodeScale);
+ if (!mGotTimecodeScale) {
+ return false;
+ }
uint64_t absTimecode = mClusterTimecode + mBlockTimecode;
absTimecode *= mTimecodeScale;
// Avoid creating an entry if the timecode is out of order
// (invalid according to the WebM specification) so that
// ordering invariants of aMapping are not violated.
if (idx == 0 ||
aMapping[idx - 1].mTimecode <= absTimecode ||
(idx + 1 < aMapping.Length() &&
@@ -243,16 +247,18 @@ void WebMBufferedParser::Append(const un
mState = READ_ELEMENT_ID;
}
break;
}
}
NS_ASSERTION(p == aBuffer + aLength, "Must have parsed to end of data.");
mCurrentOffset += aLength;
+
+ return true;
}
int64_t
WebMBufferedParser::EndSegmentOffset(int64_t aOffset)
{
if (mLastInitStartOffset > aOffset || mClusterOffset > aOffset) {
return std::min(mLastInitStartOffset >= 0 ? mLastInitStartOffset : INT64_MAX,
mClusterOffset >= 0 ? mClusterOffset : INT64_MAX);
--- a/dom/media/webm/WebMBufferedParser.h
+++ b/dom/media/webm/WebMBufferedParser.h
@@ -91,17 +91,18 @@ struct WebMBufferedParser
void SetTimecodeScale(uint32_t aTimecodeScale) {
mTimecodeScale = aTimecodeScale;
mGotTimecodeScale = true;
}
// Steps the parser through aLength bytes of data. Always consumes
// aLength bytes. Updates mCurrentOffset before returning. Acquires
// aReentrantMonitor before using aMapping.
- void Append(const unsigned char* aBuffer, uint32_t aLength,
+ // Returns false if an error was encountered.
+ bool Append(const unsigned char* aBuffer, uint32_t aLength,
nsTArray<WebMTimeDataOffset>& aMapping,
ReentrantMonitor& aReentrantMonitor);
bool operator==(int64_t aOffset) const {
return mCurrentOffset == aOffset;
}
bool operator<(int64_t aOffset) const {