Roll ANGLE e754fb8..6ffeb74
[chromium-blink-merge.git] / media / formats / webm / webm_parser_unittest.cc
bloba1249e89c42b7c6a7f2ca0af86248889c3cd2379
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/formats/webm/cluster_builder.h"
6 #include "media/formats/webm/webm_constants.h"
7 #include "media/formats/webm/webm_parser.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using ::testing::InSequence;
12 using ::testing::Return;
13 using ::testing::ReturnNull;
14 using ::testing::StrictMock;
15 using ::testing::_;
17 namespace media {
19 enum { kBlockCount = 5 };
21 class MockWebMParserClient : public WebMParserClient {
22 public:
23 virtual ~MockWebMParserClient() {}
25 // WebMParserClient methods.
26 MOCK_METHOD1(OnListStart, WebMParserClient*(int));
27 MOCK_METHOD1(OnListEnd, bool(int));
28 MOCK_METHOD2(OnUInt, bool(int, int64));
29 MOCK_METHOD2(OnFloat, bool(int, double));
30 MOCK_METHOD3(OnBinary, bool(int, const uint8*, int));
31 MOCK_METHOD2(OnString, bool(int, const std::string&));
34 class WebMParserTest : public testing::Test {
35 protected:
36 StrictMock<MockWebMParserClient> client_;
39 static scoped_ptr<Cluster> CreateCluster(int block_count) {
40 ClusterBuilder cb;
41 cb.SetClusterTimecode(0);
43 for (int i = 0; i < block_count; i++) {
44 uint8 data[] = { 0x00 };
45 cb.AddSimpleBlock(0, i, 0, data, sizeof(data));
48 return cb.Finish();
51 static void CreateClusterExpectations(int block_count,
52 bool is_complete_cluster,
53 MockWebMParserClient* client) {
55 InSequence s;
56 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(client));
57 EXPECT_CALL(*client, OnUInt(kWebMIdTimecode, 0))
58 .WillOnce(Return(true));
60 for (int i = 0; i < block_count; i++) {
61 EXPECT_CALL(*client, OnBinary(kWebMIdSimpleBlock, _, _))
62 .WillOnce(Return(true));
65 if (is_complete_cluster)
66 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
69 TEST_F(WebMParserTest, EmptyCluster) {
70 const uint8 kEmptyCluster[] = {
71 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0)
73 int size = sizeof(kEmptyCluster);
75 InSequence s;
76 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
77 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
79 WebMListParser parser(kWebMIdCluster, &client_);
80 EXPECT_EQ(size, parser.Parse(kEmptyCluster, size));
81 EXPECT_TRUE(parser.IsParsingComplete());
84 TEST_F(WebMParserTest, EmptyClusterInSegment) {
85 const uint8 kBuffer[] = {
86 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
87 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0)
89 int size = sizeof(kBuffer);
91 InSequence s;
92 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
93 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
94 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
95 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
97 WebMListParser parser(kWebMIdSegment, &client_);
98 EXPECT_EQ(size, parser.Parse(kBuffer, size));
99 EXPECT_TRUE(parser.IsParsingComplete());
102 // Test the case where a non-list child element has a size
103 // that is beyond the end of the parent.
104 TEST_F(WebMParserTest, ChildNonListLargerThanParent) {
105 const uint8 kBuffer[] = {
106 0x1F, 0x43, 0xB6, 0x75, 0x81, // CLUSTER (size = 1)
107 0xE7, 0x81, 0x01, // Timecode (size=1, value=1)
110 InSequence s;
111 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
113 WebMListParser parser(kWebMIdCluster, &client_);
114 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer)));
115 EXPECT_FALSE(parser.IsParsingComplete());
118 // Test the case where a list child element has a size
119 // that is beyond the end of the parent.
120 TEST_F(WebMParserTest, ChildListLargerThanParent) {
121 const uint8 kBuffer[] = {
122 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
123 0x1F, 0x43, 0xB6, 0x75, 0x81, 0x11 // CLUSTER (size = 1)
126 InSequence s;
127 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
129 WebMListParser parser(kWebMIdSegment, &client_);
130 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer)));
131 EXPECT_FALSE(parser.IsParsingComplete());
134 // Expecting to parse a Cluster, but get a Segment.
135 TEST_F(WebMParserTest, ListIdDoesNotMatch) {
136 const uint8 kBuffer[] = {
137 0x18, 0x53, 0x80, 0x67, 0x80, // SEGMENT (size = 0)
140 WebMListParser parser(kWebMIdCluster, &client_);
141 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer)));
142 EXPECT_FALSE(parser.IsParsingComplete());
145 TEST_F(WebMParserTest, InvalidElementInList) {
146 const uint8 kBuffer[] = {
147 0x18, 0x53, 0x80, 0x67, 0x82, // SEGMENT (size = 2)
148 0xAE, 0x80, // TrackEntry (size = 0)
151 InSequence s;
152 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
154 WebMListParser parser(kWebMIdSegment, &client_);
155 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer)));
156 EXPECT_FALSE(parser.IsParsingComplete());
159 // Test specific case of InvalidElementInList to verify EBMLHEADER within
160 // known-sized cluster causes parse error.
161 TEST_F(WebMParserTest, InvalidEBMLHeaderInCluster) {
162 const uint8 kBuffer[] = {
163 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5)
164 0x1A, 0x45, 0xDF, 0xA3, 0x80, // EBMLHEADER (size = 0)
167 InSequence s;
168 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
170 WebMListParser parser(kWebMIdCluster, &client_);
171 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer)));
172 EXPECT_FALSE(parser.IsParsingComplete());
175 // Verify that EBMLHEADER ends a preceding "unknown"-sized CLUSTER.
176 TEST_F(WebMParserTest, UnknownSizeClusterFollowedByEBMLHeader) {
177 const uint8 kBuffer[] = {
178 0x1F, 0x43, 0xB6, 0x75, 0xFF, // CLUSTER (size = unknown; really 0 due to:)
179 0x1A, 0x45, 0xDF, 0xA3, 0x80, // EBMLHEADER (size = 0)
182 InSequence s;
183 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
184 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
186 WebMListParser parser(kWebMIdCluster, &client_);
188 // List parse should consume the CLUSTER but not the EBMLHEADER.
189 EXPECT_EQ(5, parser.Parse(kBuffer, sizeof(kBuffer)));
190 EXPECT_TRUE(parser.IsParsingComplete());
193 TEST_F(WebMParserTest, VoidAndCRC32InList) {
194 const uint8 kBuffer[] = {
195 0x18, 0x53, 0x80, 0x67, 0x99, // SEGMENT (size = 25)
196 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
197 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
198 0x1F, 0x43, 0xB6, 0x75, 0x8A, // CLUSTER (size = 10)
199 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
200 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
202 int size = sizeof(kBuffer);
204 InSequence s;
205 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
206 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
207 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
208 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
210 WebMListParser parser(kWebMIdSegment, &client_);
211 EXPECT_EQ(size, parser.Parse(kBuffer, size));
212 EXPECT_TRUE(parser.IsParsingComplete());
216 TEST_F(WebMParserTest, ParseListElementWithSingleCall) {
217 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount));
218 CreateClusterExpectations(kBlockCount, true, &client_);
220 WebMListParser parser(kWebMIdCluster, &client_);
221 EXPECT_EQ(cluster->size(), parser.Parse(cluster->data(), cluster->size()));
222 EXPECT_TRUE(parser.IsParsingComplete());
225 TEST_F(WebMParserTest, ParseListElementWithMultipleCalls) {
226 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount));
227 CreateClusterExpectations(kBlockCount, true, &client_);
229 const uint8* data = cluster->data();
230 int size = cluster->size();
231 int default_parse_size = 3;
232 WebMListParser parser(kWebMIdCluster, &client_);
233 int parse_size = std::min(default_parse_size, size);
235 while (size > 0) {
236 int result = parser.Parse(data, parse_size);
237 ASSERT_GE(result, 0);
238 ASSERT_LE(result, parse_size);
240 if (result == 0) {
241 // The parser needs more data so increase the parse_size a little.
242 EXPECT_FALSE(parser.IsParsingComplete());
243 parse_size += default_parse_size;
244 parse_size = std::min(parse_size, size);
245 continue;
248 parse_size = default_parse_size;
250 data += result;
251 size -= result;
253 EXPECT_EQ((size == 0), parser.IsParsingComplete());
255 EXPECT_TRUE(parser.IsParsingComplete());
258 TEST_F(WebMParserTest, Reset) {
259 InSequence s;
260 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount));
262 // First expect all but the last block.
263 CreateClusterExpectations(kBlockCount - 1, false, &client_);
265 // Now expect all blocks.
266 CreateClusterExpectations(kBlockCount, true, &client_);
268 WebMListParser parser(kWebMIdCluster, &client_);
270 // Send slightly less than the full cluster so all but the last block is
271 // parsed.
272 int result = parser.Parse(cluster->data(), cluster->size() - 1);
273 EXPECT_GT(result, 0);
274 EXPECT_LT(result, cluster->size());
275 EXPECT_FALSE(parser.IsParsingComplete());
277 parser.Reset();
279 // Now parse a whole cluster to verify that all the blocks will get parsed.
280 EXPECT_EQ(cluster->size(), parser.Parse(cluster->data(), cluster->size()));
281 EXPECT_TRUE(parser.IsParsingComplete());
284 // Test the case where multiple clients are used for different lists.
285 TEST_F(WebMParserTest, MultipleClients) {
286 const uint8 kBuffer[] = {
287 0x18, 0x53, 0x80, 0x67, 0x94, // SEGMENT (size = 20)
288 0x16, 0x54, 0xAE, 0x6B, 0x85, // TRACKS (size = 5)
289 0xAE, 0x83, // TRACKENTRY (size = 3)
290 0xD7, 0x81, 0x01, // TRACKNUMBER (size = 1)
291 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5)
292 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
294 int size = sizeof(kBuffer);
296 StrictMock<MockWebMParserClient> c1_;
297 StrictMock<MockWebMParserClient> c2_;
298 StrictMock<MockWebMParserClient> c3_;
300 InSequence s;
301 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&c1_));
302 EXPECT_CALL(c1_, OnListStart(kWebMIdTracks)).WillOnce(Return(&c2_));
303 EXPECT_CALL(c2_, OnListStart(kWebMIdTrackEntry)).WillOnce(Return(&c3_));
304 EXPECT_CALL(c3_, OnUInt(kWebMIdTrackNumber, 1)).WillOnce(Return(true));
305 EXPECT_CALL(c2_, OnListEnd(kWebMIdTrackEntry)).WillOnce(Return(true));
306 EXPECT_CALL(c1_, OnListEnd(kWebMIdTracks)).WillOnce(Return(true));
307 EXPECT_CALL(c1_, OnListStart(kWebMIdCluster)).WillOnce(Return(&c2_));
308 EXPECT_CALL(c1_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
309 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
311 WebMListParser parser(kWebMIdSegment, &client_);
312 EXPECT_EQ(size, parser.Parse(kBuffer, size));
313 EXPECT_TRUE(parser.IsParsingComplete());
316 // Test the case where multiple clients are used for different lists.
317 TEST_F(WebMParserTest, InvalidClient) {
318 const uint8 kBuffer[] = {
319 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 20)
320 0x16, 0x54, 0xAE, 0x6B, 0x80, // TRACKS (size = 5)
323 InSequence s;
324 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(ReturnNull());
326 WebMListParser parser(kWebMIdSegment, &client_);
327 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer)));
328 EXPECT_FALSE(parser.IsParsingComplete());
331 TEST_F(WebMParserTest, ReservedIds) {
332 const uint8 k1ByteReservedId[] = { 0xFF, 0x81 };
333 const uint8 k2ByteReservedId[] = { 0x7F, 0xFF, 0x81 };
334 const uint8 k3ByteReservedId[] = { 0x3F, 0xFF, 0xFF, 0x81 };
335 const uint8 k4ByteReservedId[] = { 0x1F, 0xFF, 0xFF, 0xFF, 0x81 };
336 const uint8* kBuffers[] = {
337 k1ByteReservedId,
338 k2ByteReservedId,
339 k3ByteReservedId,
340 k4ByteReservedId
343 for (size_t i = 0; i < arraysize(kBuffers); i++) {
344 int id;
345 int64 element_size;
346 int buffer_size = 2 + i;
347 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size,
348 &id, &element_size));
349 EXPECT_EQ(id, kWebMReservedId);
350 EXPECT_EQ(element_size, 1);
354 TEST_F(WebMParserTest, ReservedSizes) {
355 const uint8 k1ByteReservedSize[] = { 0xA3, 0xFF };
356 const uint8 k2ByteReservedSize[] = { 0xA3, 0x7F, 0xFF };
357 const uint8 k3ByteReservedSize[] = { 0xA3, 0x3F, 0xFF, 0xFF };
358 const uint8 k4ByteReservedSize[] = { 0xA3, 0x1F, 0xFF, 0xFF, 0xFF };
359 const uint8 k5ByteReservedSize[] = { 0xA3, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF };
360 const uint8 k6ByteReservedSize[] = { 0xA3, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,
361 0xFF };
362 const uint8 k7ByteReservedSize[] = { 0xA3, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
363 0xFF };
364 const uint8 k8ByteReservedSize[] = { 0xA3, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
365 0xFF, 0xFF };
366 const uint8* kBuffers[] = {
367 k1ByteReservedSize,
368 k2ByteReservedSize,
369 k3ByteReservedSize,
370 k4ByteReservedSize,
371 k5ByteReservedSize,
372 k6ByteReservedSize,
373 k7ByteReservedSize,
374 k8ByteReservedSize
377 for (size_t i = 0; i < arraysize(kBuffers); i++) {
378 int id;
379 int64 element_size;
380 int buffer_size = 2 + i;
381 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size,
382 &id, &element_size));
383 EXPECT_EQ(id, 0xA3);
384 EXPECT_EQ(element_size, kWebMUnknownSize);
388 TEST_F(WebMParserTest, ZeroPaddedStrings) {
389 const uint8 kBuffer[] = {
390 0x1A, 0x45, 0xDF, 0xA3, 0x91, // EBMLHEADER (size = 17)
391 0x42, 0x82, 0x80, // DocType (size = 0)
392 0x42, 0x82, 0x81, 0x00, // DocType (size = 1) ""
393 0x42, 0x82, 0x81, 'a', // DocType (size = 1) "a"
394 0x42, 0x82, 0x83, 'a', 0x00, 0x00 // DocType (size = 3) "a"
396 int size = sizeof(kBuffer);
398 InSequence s;
399 EXPECT_CALL(client_, OnListStart(kWebMIdEBMLHeader))
400 .WillOnce(Return(&client_));
401 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true));
402 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true));
403 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true));
404 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true));
405 EXPECT_CALL(client_, OnListEnd(kWebMIdEBMLHeader)).WillOnce(Return(true));
407 WebMListParser parser(kWebMIdEBMLHeader, &client_);
408 EXPECT_EQ(size, parser.Parse(kBuffer, size));
409 EXPECT_TRUE(parser.IsParsingComplete());
412 } // namespace media