зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1788557 - Return MediaResult from WebMBufferedParser::Append to expose more details on error. r=alwu
Differential Revision: https://phabricator.services.mozilla.com/D156678
This commit is contained in:
Родитель
5414a94fa3
Коммит
2325f95234
|
@ -10,6 +10,20 @@
|
|||
|
||||
using namespace mozilla;
|
||||
|
||||
std::ostream& operator<<(std::ostream& aStream, nsresult aResult) {
|
||||
return aStream << GetStaticErrorName(aResult);
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
std::ostream& operator<<(std::ostream& aStream, const MediaResult& aResult) {
|
||||
aStream << aResult.Code();
|
||||
if (!aResult.Message().IsEmpty()) {
|
||||
aStream << " (" << aResult.Message() << ")";
|
||||
}
|
||||
return aStream;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
// "test.webm" contains 8 SimpleBlocks in a single Cluster. The blocks with
|
||||
// timecodes 100000000 and are 133000000 skipped by WebMBufferedParser
|
||||
// because they occur after a block with timecode 160000000 and the parser
|
||||
|
@ -24,13 +38,13 @@ TEST(WebMBuffered, BasicTests)
|
|||
WebMBufferedParser parser(0);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_TRUE(parser.Append(nullptr, 0, mapping));
|
||||
EXPECT_EQ(parser.Append(nullptr, 0, mapping), NS_OK);
|
||||
EXPECT_TRUE(mapping.IsEmpty());
|
||||
EXPECT_EQ(parser.mStartOffset, 0);
|
||||
EXPECT_EQ(parser.mCurrentOffset, 0);
|
||||
|
||||
unsigned char buf[] = {0x1a, 0x45, 0xdf, 0xa3};
|
||||
EXPECT_TRUE(parser.Append(buf, ArrayLength(buf), mapping));
|
||||
EXPECT_EQ(parser.Append(buf, ArrayLength(buf), mapping), NS_OK);
|
||||
EXPECT_TRUE(mapping.IsEmpty());
|
||||
EXPECT_EQ(parser.mStartOffset, 0);
|
||||
EXPECT_EQ(parser.mCurrentOffset, 4);
|
||||
|
@ -65,7 +79,8 @@ TEST(WebMBuffered, RealData)
|
|||
ReadFile("test.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_TRUE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_OK);
|
||||
EXPECT_EQ(mapping.Length(), 6u);
|
||||
EXPECT_EQ(parser.mStartOffset, 0);
|
||||
EXPECT_EQ(parser.mCurrentOffset, int64_t(webmData.Length()));
|
||||
|
@ -89,7 +104,7 @@ TEST(WebMBuffered, RealDataAppend)
|
|||
uint32_t arrayEntries = mapping.Length();
|
||||
size_t offset = 0;
|
||||
while (offset < webmData.Length()) {
|
||||
EXPECT_TRUE(parser.Append(webmData.Elements() + offset, 1, mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements() + offset, 1, mapping), NS_OK);
|
||||
offset += 1;
|
||||
EXPECT_EQ(parser.mCurrentOffset, int64_t(offset));
|
||||
if (mapping.Length() != arrayEntries) {
|
||||
|
@ -124,7 +139,8 @@ TEST(WebMBuffered, InvalidEBMLMaxIdLength)
|
|||
ReadFile("test_InvalidElementId.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_FALSE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
TEST(WebMBuffered, InvalidLargeElementIdLength)
|
||||
|
@ -137,7 +153,8 @@ TEST(WebMBuffered, InvalidLargeElementIdLength)
|
|||
ReadFile("test_InvalidLargeElementId.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_FALSE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
TEST(WebMBuffered, InvalidSmallEBMLMaxIdLength)
|
||||
|
@ -152,7 +169,8 @@ TEST(WebMBuffered, InvalidSmallEBMLMaxIdLength)
|
|||
ReadFile("test_InvalidSmallEBMLMaxIdLength.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_FALSE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
TEST(WebMBuffered, ValidLargeEBMLMaxIdLength)
|
||||
|
@ -167,7 +185,8 @@ TEST(WebMBuffered, ValidLargeEBMLMaxIdLength)
|
|||
ReadFile("test_ValidLargeEBMLMaxIdLength.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_TRUE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_OK);
|
||||
}
|
||||
|
||||
TEST(WebMBuffered, InvalidLargeEBMLMaxIdLength)
|
||||
|
@ -182,7 +201,8 @@ TEST(WebMBuffered, InvalidLargeEBMLMaxIdLength)
|
|||
ReadFile("test_InvalidLargeEBMLMaxIdLength.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_FALSE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
TEST(WebMBuffered, ValidSmallEBMLMaxSizeLength)
|
||||
|
@ -195,7 +215,8 @@ TEST(WebMBuffered, ValidSmallEBMLMaxSizeLength)
|
|||
ReadFile("test_ValidSmallEBMLMaxSizeLength.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_TRUE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_OK);
|
||||
}
|
||||
|
||||
TEST(WebMBuffered, InvalidEBMLMaxSizeLength)
|
||||
|
@ -208,5 +229,6 @@ TEST(WebMBuffered, InvalidEBMLMaxSizeLength)
|
|||
ReadFile("test_InvalidElementSize.webm", webmData);
|
||||
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
EXPECT_FALSE(parser.Append(webmData.Elements(), webmData.Length(), mapping));
|
||||
EXPECT_EQ(parser.Append(webmData.Elements(), webmData.Length(), mapping),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
|
|
|
@ -116,10 +116,9 @@ class WebMContainerParser
|
|||
|
||||
WebMBufferedParser parser(0);
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
bool result = parser.Append(aData.Elements(), aData.Length(), mapping);
|
||||
if (!result) {
|
||||
return MediaResult(NS_ERROR_FAILURE,
|
||||
RESULT_DETAIL("Invalid webm content"));
|
||||
if (auto result = parser.Append(aData.Elements(), aData.Length(), mapping);
|
||||
NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
return parser.mInitEndOffset > 0 ? NS_OK : NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
@ -133,10 +132,9 @@ class WebMContainerParser
|
|||
WebMBufferedParser parser(0);
|
||||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
parser.AppendMediaSegmentOnly();
|
||||
bool result = parser.Append(aData.Elements(), aData.Length(), mapping);
|
||||
if (!result) {
|
||||
return MediaResult(NS_ERROR_FAILURE,
|
||||
RESULT_DETAIL("Invalid webm content"));
|
||||
if (auto result = parser.Append(aData.Elements(), aData.Length(), mapping);
|
||||
NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
return parser.GetClusterOffset() >= 0 ? NS_OK : NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
@ -178,7 +176,10 @@ class WebMContainerParser
|
|||
nsTArray<WebMTimeDataOffset> mapping;
|
||||
mapping.AppendElements(mOverlappedMapping);
|
||||
mOverlappedMapping.Clear();
|
||||
mParser.Append(aData.Elements(), aData.Length(), mapping);
|
||||
if (auto result = mParser.Append(aData.Elements(), aData.Length(), mapping);
|
||||
NS_FAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
if (mResource) {
|
||||
mResource->AppendData(aData);
|
||||
}
|
||||
|
|
|
@ -69,8 +69,9 @@ WebMBufferedParser::WebMBufferedParser(int64_t aOffset)
|
|||
}
|
||||
}
|
||||
|
||||
bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
nsTArray<WebMTimeDataOffset>& aMapping) {
|
||||
MediaResult WebMBufferedParser::Append(const unsigned char* aBuffer,
|
||||
uint32_t aLength,
|
||||
nsTArray<WebMTimeDataOffset>& aMapping) {
|
||||
static const uint32_t EBML_ID = 0x1a45dfa3;
|
||||
static const uint32_t SEGMENT_ID = 0x18538067;
|
||||
static const uint32_t SEGINFO_ID = 0x1549a966;
|
||||
|
@ -102,8 +103,10 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
break;
|
||||
case READ_ELEMENT_SIZE:
|
||||
if (mVInt.mLength > mEBMLMaxIdLength) {
|
||||
WEBM_DEBUG("Invalid element id of length %" PRIu64, mVInt.mLength);
|
||||
return false;
|
||||
nsPrintfCString detail("Invalid element id of length %" PRIu64,
|
||||
mVInt.mLength);
|
||||
WEBM_DEBUG("%s", detail.get());
|
||||
return MediaResult(NS_ERROR_FAILURE, detail);
|
||||
}
|
||||
mVIntRaw = false;
|
||||
mElement.mID = mVInt;
|
||||
|
@ -124,8 +127,10 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
break;
|
||||
case PARSE_ELEMENT:
|
||||
if (mVInt.mLength > mEBMLMaxSizeLength) {
|
||||
WEBM_DEBUG("Invalid element size of length %" PRIu64, mVInt.mLength);
|
||||
return false;
|
||||
nsPrintfCString detail("Invalid element size of length %" PRIu64,
|
||||
mVInt.mLength);
|
||||
WEBM_DEBUG("%s", detail.get());
|
||||
return MediaResult(NS_ERROR_FAILURE, detail);
|
||||
}
|
||||
mElement.mSize = mVInt;
|
||||
switch (mElement.mID.mValue) {
|
||||
|
@ -173,7 +178,10 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
WEBM_DEBUG(
|
||||
"The Timecode element must appear before any Block or "
|
||||
"SimpleBlock elements in a Cluster");
|
||||
return false;
|
||||
return MediaResult(
|
||||
NS_ERROR_FAILURE,
|
||||
"The Timecode element must appear before any Block or "
|
||||
"SimpleBlock elements in a Cluster");
|
||||
}
|
||||
mBlockSize = mElement.mSize.mValue;
|
||||
mBlockTimecode = 0;
|
||||
|
@ -192,21 +200,23 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
if (int64_t currentOffset = mCurrentOffset + (p - aBuffer);
|
||||
currentOffset < mLastInitStartOffset ||
|
||||
currentOffset >= mLastInitStartOffset + mLastInitSize) {
|
||||
WEBM_DEBUG("Unexpected %s outside init segment",
|
||||
mElement.mID.mValue == EBML_MAX_ID_LENGTH_ID
|
||||
? "EBMLMaxIdLength"
|
||||
: "EBMLMaxSizeLength");
|
||||
return false;
|
||||
nsPrintfCString str("Unexpected %s outside init segment",
|
||||
mElement.mID.mValue == EBML_MAX_ID_LENGTH_ID
|
||||
? "EBMLMaxIdLength"
|
||||
: "EBMLMaxSizeLength");
|
||||
WEBM_DEBUG("%s", str.get());
|
||||
return MediaResult(NS_ERROR_FAILURE, str);
|
||||
}
|
||||
if (mElement.mSize.mValue > 8) {
|
||||
// https://www.rfc-editor.org/rfc/rfc8794.html (EBML):
|
||||
// An Unsigned Integer Element MUST declare a length from zero
|
||||
// to eight octets.
|
||||
WEBM_DEBUG("Bad length of %s size",
|
||||
mElement.mID.mValue == EBML_MAX_ID_LENGTH_ID
|
||||
? "EBMLMaxIdLength"
|
||||
: "EBMLMaxSizeLength");
|
||||
return false;
|
||||
nsPrintfCString str("Bad length of %s size",
|
||||
mElement.mID.mValue == EBML_MAX_ID_LENGTH_ID
|
||||
? "EBMLMaxIdLength"
|
||||
: "EBMLMaxSizeLength");
|
||||
WEBM_DEBUG("%s", str.get());
|
||||
return MediaResult(NS_ERROR_FAILURE, str);
|
||||
}
|
||||
mVInt = VInt();
|
||||
mVIntLeft = mElement.mSize.mValue;
|
||||
|
@ -252,7 +262,8 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
case READ_TIMECODESCALE:
|
||||
if (!mGotTimecodeScale) {
|
||||
WEBM_DEBUG("Should get the SegmentInfo first");
|
||||
return false;
|
||||
return MediaResult(NS_ERROR_FAILURE,
|
||||
"TimecodeScale appeared before SegmentInfo");
|
||||
}
|
||||
mTimecodeScale = mVInt.mValue;
|
||||
mState = READ_ELEMENT_ID;
|
||||
|
@ -280,7 +291,8 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
mClusterTimecode >= uint16_t(abs(mBlockTimecode))) {
|
||||
if (!mGotTimecodeScale) {
|
||||
WEBM_DEBUG("Should get the TimecodeScale first");
|
||||
return false;
|
||||
return MediaResult(NS_ERROR_FAILURE,
|
||||
"Timecode appeared before SegmentInfo");
|
||||
}
|
||||
uint64_t absTimecode = mClusterTimecode + mBlockTimecode;
|
||||
absTimecode *= mTimecodeScale;
|
||||
|
@ -329,8 +341,10 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
// Section 4 of [RFC8794] and can be between one and five octets
|
||||
// long. Five-octet-long Element IDs are possible only if declared
|
||||
// in the EBML header.
|
||||
WEBM_DEBUG("Invalid EMBLMaxIdLength %" PRIu64, mVInt.mValue);
|
||||
return false;
|
||||
nsPrintfCString detail("Invalid EMBLMaxIdLength %" PRIu64,
|
||||
mVInt.mValue);
|
||||
WEBM_DEBUG("%s", detail.get());
|
||||
return MediaResult(NS_ERROR_FAILURE, detail);
|
||||
}
|
||||
mEBMLMaxIdLength = mVInt.mValue;
|
||||
mState = READ_ELEMENT_ID;
|
||||
|
@ -348,8 +362,10 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
// (Matroska):
|
||||
// The EBMLMaxSizeLength of the EBML Header MUST be between "1" and
|
||||
// "8" inclusive.
|
||||
WEBM_DEBUG("Invalid EMBLMaxSizeLength %" PRIu64, mVInt.mValue);
|
||||
return false;
|
||||
nsPrintfCString detail("Invalid EMBLMaxSizeLength %" PRIu64,
|
||||
mVInt.mValue);
|
||||
WEBM_DEBUG("%s", detail.get());
|
||||
return MediaResult(NS_ERROR_FAILURE, detail);
|
||||
}
|
||||
mEBMLMaxSizeLength = mVInt.mValue;
|
||||
mState = READ_ELEMENT_ID;
|
||||
|
@ -387,7 +403,7 @@ bool WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||
NS_ASSERTION(p == aBuffer + aLength, "Must have parsed to end of data.");
|
||||
mCurrentOffset += aLength;
|
||||
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int64_t WebMBufferedParser::EndSegmentOffset(int64_t aOffset) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
# include "nsTArray.h"
|
||||
# include "mozilla/Mutex.h"
|
||||
# include "MediaResource.h"
|
||||
# include "MediaResult.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -65,8 +66,8 @@ struct WebMBufferedParser {
|
|||
// Steps the parser through aLength bytes of data. Always consumes
|
||||
// aLength bytes. Updates mCurrentOffset before returning.
|
||||
// Returns false if an error was encountered.
|
||||
bool Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
nsTArray<WebMTimeDataOffset>& aMapping);
|
||||
MediaResult Append(const unsigned char* aBuffer, uint32_t aLength,
|
||||
nsTArray<WebMTimeDataOffset>& aMapping);
|
||||
|
||||
bool operator==(int64_t aOffset) const { return mCurrentOffset == aOffset; }
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче