| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/formats/webm/cluster_builder.h" | 5 #include "media/formats/webm/cluster_builder.h" |
| 6 #include "media/formats/webm/webm_constants.h" | 6 #include "media/formats/webm/webm_constants.h" |
| 7 #include "media/formats/webm/webm_parser.h" | 7 #include "media/formats/webm/webm_parser.h" |
| 8 #include "testing/gmock/include/gmock/gmock.h" | 8 #include "testing/gmock/include/gmock/gmock.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 10 |
| 11 using ::testing::InSequence; | 11 using ::testing::InSequence; |
| 12 using ::testing::Return; | 12 using ::testing::Return; |
| 13 using ::testing::ReturnNull; | 13 using ::testing::ReturnNull; |
| 14 using ::testing::StrictMock; | 14 using ::testing::StrictMock; |
| 15 using ::testing::_; | 15 using ::testing::_; |
| 16 | 16 |
| 17 namespace media { | 17 namespace media { |
| 18 | 18 |
| 19 enum { kBlockCount = 5 }; | 19 enum { kBlockCount = 5 }; |
| 20 | 20 |
| 21 class MockWebMParserClient : public WebMParserClient { | 21 class MockWebMParserClient : public WebMParserClient { |
| 22 public: | 22 public: |
| 23 virtual ~MockWebMParserClient() {} | 23 virtual ~MockWebMParserClient() {} |
| 24 | 24 |
| 25 // WebMParserClient methods. | 25 // WebMParserClient methods. |
| 26 MOCK_METHOD1(OnListStart, WebMParserClient*(int)); | 26 MOCK_METHOD1(OnListStart, WebMParserClient*(int)); |
| 27 MOCK_METHOD1(OnListEnd, bool(int)); | 27 MOCK_METHOD1(OnListEnd, bool(int)); |
| 28 MOCK_METHOD2(OnUInt, bool(int, int64)); | 28 MOCK_METHOD2(OnUInt, bool(int, int64_t)); |
| 29 MOCK_METHOD2(OnFloat, bool(int, double)); | 29 MOCK_METHOD2(OnFloat, bool(int, double)); |
| 30 MOCK_METHOD3(OnBinary, bool(int, const uint8*, int)); | 30 MOCK_METHOD3(OnBinary, bool(int, const uint8_t*, int)); |
| 31 MOCK_METHOD2(OnString, bool(int, const std::string&)); | 31 MOCK_METHOD2(OnString, bool(int, const std::string&)); |
| 32 }; | 32 }; |
| 33 | 33 |
| 34 class WebMParserTest : public testing::Test { | 34 class WebMParserTest : public testing::Test { |
| 35 protected: | 35 protected: |
| 36 StrictMock<MockWebMParserClient> client_; | 36 StrictMock<MockWebMParserClient> client_; |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 static scoped_ptr<Cluster> CreateCluster(int block_count) { | 39 static scoped_ptr<Cluster> CreateCluster(int block_count) { |
| 40 ClusterBuilder cb; | 40 ClusterBuilder cb; |
| 41 cb.SetClusterTimecode(0); | 41 cb.SetClusterTimecode(0); |
| 42 | 42 |
| 43 for (int i = 0; i < block_count; i++) { | 43 for (int i = 0; i < block_count; i++) { |
| 44 uint8 data[] = { 0x00 }; | 44 uint8_t data[] = {0x00}; |
| 45 cb.AddSimpleBlock(0, i, 0, data, sizeof(data)); | 45 cb.AddSimpleBlock(0, i, 0, data, sizeof(data)); |
| 46 } | 46 } |
| 47 | 47 |
| 48 return cb.Finish(); | 48 return cb.Finish(); |
| 49 } | 49 } |
| 50 | 50 |
| 51 static void CreateClusterExpectations(int block_count, | 51 static void CreateClusterExpectations(int block_count, |
| 52 bool is_complete_cluster, | 52 bool is_complete_cluster, |
| 53 MockWebMParserClient* client) { | 53 MockWebMParserClient* client) { |
| 54 | 54 |
| 55 InSequence s; | 55 InSequence s; |
| 56 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(client)); | 56 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(client)); |
| 57 EXPECT_CALL(*client, OnUInt(kWebMIdTimecode, 0)) | 57 EXPECT_CALL(*client, OnUInt(kWebMIdTimecode, 0)) |
| 58 .WillOnce(Return(true)); | 58 .WillOnce(Return(true)); |
| 59 | 59 |
| 60 for (int i = 0; i < block_count; i++) { | 60 for (int i = 0; i < block_count; i++) { |
| 61 EXPECT_CALL(*client, OnBinary(kWebMIdSimpleBlock, _, _)) | 61 EXPECT_CALL(*client, OnBinary(kWebMIdSimpleBlock, _, _)) |
| 62 .WillOnce(Return(true)); | 62 .WillOnce(Return(true)); |
| 63 } | 63 } |
| 64 | 64 |
| 65 if (is_complete_cluster) | 65 if (is_complete_cluster) |
| 66 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); | 66 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); |
| 67 } | 67 } |
| 68 | 68 |
| 69 TEST_F(WebMParserTest, EmptyCluster) { | 69 TEST_F(WebMParserTest, EmptyCluster) { |
| 70 const uint8 kEmptyCluster[] = { | 70 const uint8_t kEmptyCluster[] = { |
| 71 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0) | 71 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0) |
| 72 }; | 72 }; |
| 73 int size = sizeof(kEmptyCluster); | 73 int size = sizeof(kEmptyCluster); |
| 74 | 74 |
| 75 InSequence s; | 75 InSequence s; |
| 76 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); | 76 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); |
| 77 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); | 77 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); |
| 78 | 78 |
| 79 WebMListParser parser(kWebMIdCluster, &client_); | 79 WebMListParser parser(kWebMIdCluster, &client_); |
| 80 EXPECT_EQ(size, parser.Parse(kEmptyCluster, size)); | 80 EXPECT_EQ(size, parser.Parse(kEmptyCluster, size)); |
| 81 EXPECT_TRUE(parser.IsParsingComplete()); | 81 EXPECT_TRUE(parser.IsParsingComplete()); |
| 82 } | 82 } |
| 83 | 83 |
| 84 TEST_F(WebMParserTest, EmptyClusterInSegment) { | 84 TEST_F(WebMParserTest, EmptyClusterInSegment) { |
| 85 const uint8 kBuffer[] = { | 85 const uint8_t kBuffer[] = { |
| 86 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5) | 86 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5) |
| 87 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0) | 87 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0) |
| 88 }; | 88 }; |
| 89 int size = sizeof(kBuffer); | 89 int size = sizeof(kBuffer); |
| 90 | 90 |
| 91 InSequence s; | 91 InSequence s; |
| 92 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); | 92 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); |
| 93 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); | 93 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); |
| 94 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); | 94 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); |
| 95 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); | 95 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); |
| 96 | 96 |
| 97 WebMListParser parser(kWebMIdSegment, &client_); | 97 WebMListParser parser(kWebMIdSegment, &client_); |
| 98 EXPECT_EQ(size, parser.Parse(kBuffer, size)); | 98 EXPECT_EQ(size, parser.Parse(kBuffer, size)); |
| 99 EXPECT_TRUE(parser.IsParsingComplete()); | 99 EXPECT_TRUE(parser.IsParsingComplete()); |
| 100 } | 100 } |
| 101 | 101 |
| 102 // Test the case where a non-list child element has a size | 102 // Test the case where a non-list child element has a size |
| 103 // that is beyond the end of the parent. | 103 // that is beyond the end of the parent. |
| 104 TEST_F(WebMParserTest, ChildNonListLargerThanParent) { | 104 TEST_F(WebMParserTest, ChildNonListLargerThanParent) { |
| 105 const uint8 kBuffer[] = { | 105 const uint8_t kBuffer[] = { |
| 106 0x1F, 0x43, 0xB6, 0x75, 0x81, // CLUSTER (size = 1) | 106 0x1F, 0x43, 0xB6, 0x75, 0x81, // CLUSTER (size = 1) |
| 107 0xE7, 0x81, 0x01, // Timecode (size=1, value=1) | 107 0xE7, 0x81, 0x01, // Timecode (size=1, value=1) |
| 108 }; | 108 }; |
| 109 | 109 |
| 110 InSequence s; | 110 InSequence s; |
| 111 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); | 111 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); |
| 112 | 112 |
| 113 WebMListParser parser(kWebMIdCluster, &client_); | 113 WebMListParser parser(kWebMIdCluster, &client_); |
| 114 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); | 114 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); |
| 115 EXPECT_FALSE(parser.IsParsingComplete()); | 115 EXPECT_FALSE(parser.IsParsingComplete()); |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Test the case where a list child element has a size | 118 // Test the case where a list child element has a size |
| 119 // that is beyond the end of the parent. | 119 // that is beyond the end of the parent. |
| 120 TEST_F(WebMParserTest, ChildListLargerThanParent) { | 120 TEST_F(WebMParserTest, ChildListLargerThanParent) { |
| 121 const uint8 kBuffer[] = { | 121 const uint8_t kBuffer[] = { |
| 122 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5) | 122 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5) |
| 123 0x1F, 0x43, 0xB6, 0x75, 0x81, 0x11 // CLUSTER (size = 1) | 123 0x1F, 0x43, 0xB6, 0x75, 0x81, |
| 124 0x11 // CLUSTER (size = 1) |
| 124 }; | 125 }; |
| 125 | 126 |
| 126 InSequence s; | 127 InSequence s; |
| 127 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); | 128 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); |
| 128 | 129 |
| 129 WebMListParser parser(kWebMIdSegment, &client_); | 130 WebMListParser parser(kWebMIdSegment, &client_); |
| 130 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); | 131 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); |
| 131 EXPECT_FALSE(parser.IsParsingComplete()); | 132 EXPECT_FALSE(parser.IsParsingComplete()); |
| 132 } | 133 } |
| 133 | 134 |
| 134 // Expecting to parse a Cluster, but get a Segment. | 135 // Expecting to parse a Cluster, but get a Segment. |
| 135 TEST_F(WebMParserTest, ListIdDoesNotMatch) { | 136 TEST_F(WebMParserTest, ListIdDoesNotMatch) { |
| 136 const uint8 kBuffer[] = { | 137 const uint8_t kBuffer[] = { |
| 137 0x18, 0x53, 0x80, 0x67, 0x80, // SEGMENT (size = 0) | 138 0x18, 0x53, 0x80, 0x67, 0x80, // SEGMENT (size = 0) |
| 138 }; | 139 }; |
| 139 | 140 |
| 140 WebMListParser parser(kWebMIdCluster, &client_); | 141 WebMListParser parser(kWebMIdCluster, &client_); |
| 141 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); | 142 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); |
| 142 EXPECT_FALSE(parser.IsParsingComplete()); | 143 EXPECT_FALSE(parser.IsParsingComplete()); |
| 143 } | 144 } |
| 144 | 145 |
| 145 TEST_F(WebMParserTest, InvalidElementInList) { | 146 TEST_F(WebMParserTest, InvalidElementInList) { |
| 146 const uint8 kBuffer[] = { | 147 const uint8_t kBuffer[] = { |
| 147 0x18, 0x53, 0x80, 0x67, 0x82, // SEGMENT (size = 2) | 148 0x18, 0x53, 0x80, 0x67, 0x82, // SEGMENT (size = 2) |
| 148 0xAE, 0x80, // TrackEntry (size = 0) | 149 0xAE, 0x80, // TrackEntry (size = 0) |
| 149 }; | 150 }; |
| 150 | 151 |
| 151 InSequence s; | 152 InSequence s; |
| 152 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); | 153 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); |
| 153 | 154 |
| 154 WebMListParser parser(kWebMIdSegment, &client_); | 155 WebMListParser parser(kWebMIdSegment, &client_); |
| 155 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); | 156 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); |
| 156 EXPECT_FALSE(parser.IsParsingComplete()); | 157 EXPECT_FALSE(parser.IsParsingComplete()); |
| 157 } | 158 } |
| 158 | 159 |
| 159 // Test specific case of InvalidElementInList to verify EBMLHEADER within | 160 // Test specific case of InvalidElementInList to verify EBMLHEADER within |
| 160 // known-sized cluster causes parse error. | 161 // known-sized cluster causes parse error. |
| 161 TEST_F(WebMParserTest, InvalidEBMLHeaderInCluster) { | 162 TEST_F(WebMParserTest, InvalidEBMLHeaderInCluster) { |
| 162 const uint8 kBuffer[] = { | 163 const uint8_t kBuffer[] = { |
| 163 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5) | 164 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5) |
| 164 0x1A, 0x45, 0xDF, 0xA3, 0x80, // EBMLHEADER (size = 0) | 165 0x1A, 0x45, 0xDF, 0xA3, 0x80, // EBMLHEADER (size = 0) |
| 165 }; | 166 }; |
| 166 | 167 |
| 167 InSequence s; | 168 InSequence s; |
| 168 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); | 169 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); |
| 169 | 170 |
| 170 WebMListParser parser(kWebMIdCluster, &client_); | 171 WebMListParser parser(kWebMIdCluster, &client_); |
| 171 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); | 172 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); |
| 172 EXPECT_FALSE(parser.IsParsingComplete()); | 173 EXPECT_FALSE(parser.IsParsingComplete()); |
| 173 } | 174 } |
| 174 | 175 |
| 175 // Verify that EBMLHEADER ends a preceding "unknown"-sized CLUSTER. | 176 // Verify that EBMLHEADER ends a preceding "unknown"-sized CLUSTER. |
| 176 TEST_F(WebMParserTest, UnknownSizeClusterFollowedByEBMLHeader) { | 177 TEST_F(WebMParserTest, UnknownSizeClusterFollowedByEBMLHeader) { |
| 177 const uint8 kBuffer[] = { | 178 const uint8_t kBuffer[] = { |
| 178 0x1F, 0x43, 0xB6, 0x75, 0xFF, // CLUSTER (size = unknown; really 0 due to:) | 179 0x1F, 0x43, 0xB6, |
| 179 0x1A, 0x45, 0xDF, 0xA3, 0x80, // EBMLHEADER (size = 0) | 180 0x75, 0xFF, // CLUSTER (size = unknown; really 0 due to:) |
| 181 0x1A, 0x45, 0xDF, |
| 182 0xA3, 0x80, // EBMLHEADER (size = 0) |
| 180 }; | 183 }; |
| 181 | 184 |
| 182 InSequence s; | 185 InSequence s; |
| 183 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); | 186 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); |
| 184 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); | 187 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); |
| 185 | 188 |
| 186 WebMListParser parser(kWebMIdCluster, &client_); | 189 WebMListParser parser(kWebMIdCluster, &client_); |
| 187 | 190 |
| 188 // List parse should consume the CLUSTER but not the EBMLHEADER. | 191 // List parse should consume the CLUSTER but not the EBMLHEADER. |
| 189 EXPECT_EQ(5, parser.Parse(kBuffer, sizeof(kBuffer))); | 192 EXPECT_EQ(5, parser.Parse(kBuffer, sizeof(kBuffer))); |
| 190 EXPECT_TRUE(parser.IsParsingComplete()); | 193 EXPECT_TRUE(parser.IsParsingComplete()); |
| 191 } | 194 } |
| 192 | 195 |
| 193 TEST_F(WebMParserTest, VoidAndCRC32InList) { | 196 TEST_F(WebMParserTest, VoidAndCRC32InList) { |
| 194 const uint8 kBuffer[] = { | 197 const uint8_t kBuffer[] = { |
| 195 0x18, 0x53, 0x80, 0x67, 0x99, // SEGMENT (size = 25) | 198 0x18, 0x53, 0x80, 0x67, 0x99, // SEGMENT (size = 25) |
| 196 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) | 199 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) |
| 197 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3) | 200 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3) |
| 198 0x1F, 0x43, 0xB6, 0x75, 0x8A, // CLUSTER (size = 10) | 201 0x1F, 0x43, 0xB6, 0x75, 0x8A, // CLUSTER (size = 10) |
| 199 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) | 202 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) |
| 200 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3) | 203 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3) |
| 201 }; | 204 }; |
| 202 int size = sizeof(kBuffer); | 205 int size = sizeof(kBuffer); |
| 203 | 206 |
| 204 InSequence s; | 207 InSequence s; |
| 205 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); | 208 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); |
| 206 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); | 209 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); |
| 207 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); | 210 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); |
| 208 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); | 211 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); |
| 209 | 212 |
| 210 WebMListParser parser(kWebMIdSegment, &client_); | 213 WebMListParser parser(kWebMIdSegment, &client_); |
| 211 EXPECT_EQ(size, parser.Parse(kBuffer, size)); | 214 EXPECT_EQ(size, parser.Parse(kBuffer, size)); |
| 212 EXPECT_TRUE(parser.IsParsingComplete()); | 215 EXPECT_TRUE(parser.IsParsingComplete()); |
| 213 } | 216 } |
| 214 | 217 |
| 215 | 218 |
| 216 TEST_F(WebMParserTest, ParseListElementWithSingleCall) { | 219 TEST_F(WebMParserTest, ParseListElementWithSingleCall) { |
| 217 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount)); | 220 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount)); |
| 218 CreateClusterExpectations(kBlockCount, true, &client_); | 221 CreateClusterExpectations(kBlockCount, true, &client_); |
| 219 | 222 |
| 220 WebMListParser parser(kWebMIdCluster, &client_); | 223 WebMListParser parser(kWebMIdCluster, &client_); |
| 221 EXPECT_EQ(cluster->size(), parser.Parse(cluster->data(), cluster->size())); | 224 EXPECT_EQ(cluster->size(), parser.Parse(cluster->data(), cluster->size())); |
| 222 EXPECT_TRUE(parser.IsParsingComplete()); | 225 EXPECT_TRUE(parser.IsParsingComplete()); |
| 223 } | 226 } |
| 224 | 227 |
| 225 TEST_F(WebMParserTest, ParseListElementWithMultipleCalls) { | 228 TEST_F(WebMParserTest, ParseListElementWithMultipleCalls) { |
| 226 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount)); | 229 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount)); |
| 227 CreateClusterExpectations(kBlockCount, true, &client_); | 230 CreateClusterExpectations(kBlockCount, true, &client_); |
| 228 | 231 |
| 229 const uint8* data = cluster->data(); | 232 const uint8_t* data = cluster->data(); |
| 230 int size = cluster->size(); | 233 int size = cluster->size(); |
| 231 int default_parse_size = 3; | 234 int default_parse_size = 3; |
| 232 WebMListParser parser(kWebMIdCluster, &client_); | 235 WebMListParser parser(kWebMIdCluster, &client_); |
| 233 int parse_size = std::min(default_parse_size, size); | 236 int parse_size = std::min(default_parse_size, size); |
| 234 | 237 |
| 235 while (size > 0) { | 238 while (size > 0) { |
| 236 int result = parser.Parse(data, parse_size); | 239 int result = parser.Parse(data, parse_size); |
| 237 ASSERT_GE(result, 0); | 240 ASSERT_GE(result, 0); |
| 238 ASSERT_LE(result, parse_size); | 241 ASSERT_LE(result, parse_size); |
| 239 | 242 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 | 279 |
| 277 parser.Reset(); | 280 parser.Reset(); |
| 278 | 281 |
| 279 // Now parse a whole cluster to verify that all the blocks will get parsed. | 282 // 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())); | 283 EXPECT_EQ(cluster->size(), parser.Parse(cluster->data(), cluster->size())); |
| 281 EXPECT_TRUE(parser.IsParsingComplete()); | 284 EXPECT_TRUE(parser.IsParsingComplete()); |
| 282 } | 285 } |
| 283 | 286 |
| 284 // Test the case where multiple clients are used for different lists. | 287 // Test the case where multiple clients are used for different lists. |
| 285 TEST_F(WebMParserTest, MultipleClients) { | 288 TEST_F(WebMParserTest, MultipleClients) { |
| 286 const uint8 kBuffer[] = { | 289 const uint8_t kBuffer[] = { |
| 287 0x18, 0x53, 0x80, 0x67, 0x94, // SEGMENT (size = 20) | 290 0x18, 0x53, 0x80, 0x67, 0x94, // SEGMENT (size = 20) |
| 288 0x16, 0x54, 0xAE, 0x6B, 0x85, // TRACKS (size = 5) | 291 0x16, 0x54, 0xAE, 0x6B, 0x85, // TRACKS (size = 5) |
| 289 0xAE, 0x83, // TRACKENTRY (size = 3) | 292 0xAE, 0x83, // TRACKENTRY (size = 3) |
| 290 0xD7, 0x81, 0x01, // TRACKNUMBER (size = 1) | 293 0xD7, 0x81, 0x01, // TRACKNUMBER (size = 1) |
| 291 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5) | 294 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5) |
| 292 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) | 295 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) |
| 293 }; | 296 }; |
| 294 int size = sizeof(kBuffer); | 297 int size = sizeof(kBuffer); |
| 295 | 298 |
| 296 StrictMock<MockWebMParserClient> c1_; | 299 StrictMock<MockWebMParserClient> c1_; |
| 297 StrictMock<MockWebMParserClient> c2_; | 300 StrictMock<MockWebMParserClient> c2_; |
| 298 StrictMock<MockWebMParserClient> c3_; | 301 StrictMock<MockWebMParserClient> c3_; |
| 299 | 302 |
| 300 InSequence s; | 303 InSequence s; |
| 301 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&c1_)); | 304 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&c1_)); |
| 302 EXPECT_CALL(c1_, OnListStart(kWebMIdTracks)).WillOnce(Return(&c2_)); | 305 EXPECT_CALL(c1_, OnListStart(kWebMIdTracks)).WillOnce(Return(&c2_)); |
| 303 EXPECT_CALL(c2_, OnListStart(kWebMIdTrackEntry)).WillOnce(Return(&c3_)); | 306 EXPECT_CALL(c2_, OnListStart(kWebMIdTrackEntry)).WillOnce(Return(&c3_)); |
| 304 EXPECT_CALL(c3_, OnUInt(kWebMIdTrackNumber, 1)).WillOnce(Return(true)); | 307 EXPECT_CALL(c3_, OnUInt(kWebMIdTrackNumber, 1)).WillOnce(Return(true)); |
| 305 EXPECT_CALL(c2_, OnListEnd(kWebMIdTrackEntry)).WillOnce(Return(true)); | 308 EXPECT_CALL(c2_, OnListEnd(kWebMIdTrackEntry)).WillOnce(Return(true)); |
| 306 EXPECT_CALL(c1_, OnListEnd(kWebMIdTracks)).WillOnce(Return(true)); | 309 EXPECT_CALL(c1_, OnListEnd(kWebMIdTracks)).WillOnce(Return(true)); |
| 307 EXPECT_CALL(c1_, OnListStart(kWebMIdCluster)).WillOnce(Return(&c2_)); | 310 EXPECT_CALL(c1_, OnListStart(kWebMIdCluster)).WillOnce(Return(&c2_)); |
| 308 EXPECT_CALL(c1_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); | 311 EXPECT_CALL(c1_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); |
| 309 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); | 312 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); |
| 310 | 313 |
| 311 WebMListParser parser(kWebMIdSegment, &client_); | 314 WebMListParser parser(kWebMIdSegment, &client_); |
| 312 EXPECT_EQ(size, parser.Parse(kBuffer, size)); | 315 EXPECT_EQ(size, parser.Parse(kBuffer, size)); |
| 313 EXPECT_TRUE(parser.IsParsingComplete()); | 316 EXPECT_TRUE(parser.IsParsingComplete()); |
| 314 } | 317 } |
| 315 | 318 |
| 316 // Test the case where multiple clients are used for different lists. | 319 // Test the case where multiple clients are used for different lists. |
| 317 TEST_F(WebMParserTest, InvalidClient) { | 320 TEST_F(WebMParserTest, InvalidClient) { |
| 318 const uint8 kBuffer[] = { | 321 const uint8_t kBuffer[] = { |
| 319 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 20) | 322 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 20) |
| 320 0x16, 0x54, 0xAE, 0x6B, 0x80, // TRACKS (size = 5) | 323 0x16, 0x54, 0xAE, 0x6B, 0x80, // TRACKS (size = 5) |
| 321 }; | 324 }; |
| 322 | 325 |
| 323 InSequence s; | 326 InSequence s; |
| 324 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(ReturnNull()); | 327 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(ReturnNull()); |
| 325 | 328 |
| 326 WebMListParser parser(kWebMIdSegment, &client_); | 329 WebMListParser parser(kWebMIdSegment, &client_); |
| 327 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); | 330 EXPECT_EQ(-1, parser.Parse(kBuffer, sizeof(kBuffer))); |
| 328 EXPECT_FALSE(parser.IsParsingComplete()); | 331 EXPECT_FALSE(parser.IsParsingComplete()); |
| 329 } | 332 } |
| 330 | 333 |
| 331 TEST_F(WebMParserTest, ReservedIds) { | 334 TEST_F(WebMParserTest, ReservedIds) { |
| 332 const uint8 k1ByteReservedId[] = { 0xFF, 0x81 }; | 335 const uint8_t k1ByteReservedId[] = {0xFF, 0x81}; |
| 333 const uint8 k2ByteReservedId[] = { 0x7F, 0xFF, 0x81 }; | 336 const uint8_t k2ByteReservedId[] = {0x7F, 0xFF, 0x81}; |
| 334 const uint8 k3ByteReservedId[] = { 0x3F, 0xFF, 0xFF, 0x81 }; | 337 const uint8_t k3ByteReservedId[] = {0x3F, 0xFF, 0xFF, 0x81}; |
| 335 const uint8 k4ByteReservedId[] = { 0x1F, 0xFF, 0xFF, 0xFF, 0x81 }; | 338 const uint8_t k4ByteReservedId[] = {0x1F, 0xFF, 0xFF, 0xFF, 0x81}; |
| 336 const uint8* kBuffers[] = { | 339 const uint8_t* kBuffers[] = {k1ByteReservedId, k2ByteReservedId, |
| 337 k1ByteReservedId, | 340 k3ByteReservedId, k4ByteReservedId}; |
| 338 k2ByteReservedId, | |
| 339 k3ByteReservedId, | |
| 340 k4ByteReservedId | |
| 341 }; | |
| 342 | 341 |
| 343 for (size_t i = 0; i < arraysize(kBuffers); i++) { | 342 for (size_t i = 0; i < arraysize(kBuffers); i++) { |
| 344 int id; | 343 int id; |
| 345 int64 element_size; | 344 int64_t element_size; |
| 346 int buffer_size = 2 + i; | 345 int buffer_size = 2 + i; |
| 347 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size, | 346 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size, |
| 348 &id, &element_size)); | 347 &id, &element_size)); |
| 349 EXPECT_EQ(id, kWebMReservedId); | 348 EXPECT_EQ(id, kWebMReservedId); |
| 350 EXPECT_EQ(element_size, 1); | 349 EXPECT_EQ(element_size, 1); |
| 351 } | 350 } |
| 352 } | 351 } |
| 353 | 352 |
| 354 TEST_F(WebMParserTest, ReservedSizes) { | 353 TEST_F(WebMParserTest, ReservedSizes) { |
| 355 const uint8 k1ByteReservedSize[] = { 0xA3, 0xFF }; | 354 const uint8_t k1ByteReservedSize[] = {0xA3, 0xFF}; |
| 356 const uint8 k2ByteReservedSize[] = { 0xA3, 0x7F, 0xFF }; | 355 const uint8_t k2ByteReservedSize[] = {0xA3, 0x7F, 0xFF}; |
| 357 const uint8 k3ByteReservedSize[] = { 0xA3, 0x3F, 0xFF, 0xFF }; | 356 const uint8_t k3ByteReservedSize[] = {0xA3, 0x3F, 0xFF, 0xFF}; |
| 358 const uint8 k4ByteReservedSize[] = { 0xA3, 0x1F, 0xFF, 0xFF, 0xFF }; | 357 const uint8_t k4ByteReservedSize[] = {0xA3, 0x1F, 0xFF, 0xFF, 0xFF}; |
| 359 const uint8 k5ByteReservedSize[] = { 0xA3, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF }; | 358 const uint8_t k5ByteReservedSize[] = {0xA3, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF}; |
| 360 const uint8 k6ByteReservedSize[] = { 0xA3, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, | 359 const uint8_t k6ByteReservedSize[] = {0xA3, 0x07, 0xFF, 0xFF, |
| 361 0xFF }; | 360 0xFF, 0xFF, 0xFF}; |
| 362 const uint8 k7ByteReservedSize[] = { 0xA3, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 361 const uint8_t k7ByteReservedSize[] = {0xA3, 0x03, 0xFF, 0xFF, |
| 363 0xFF }; | 362 0xFF, 0xFF, 0xFF, 0xFF}; |
| 364 const uint8 k8ByteReservedSize[] = { 0xA3, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 363 const uint8_t k8ByteReservedSize[] = {0xA3, 0x01, 0xFF, 0xFF, 0xFF, |
| 365 0xFF, 0xFF }; | 364 0xFF, 0xFF, 0xFF, 0xFF}; |
| 366 const uint8* kBuffers[] = { | 365 const uint8_t* kBuffers[] = {k1ByteReservedSize, k2ByteReservedSize, |
| 367 k1ByteReservedSize, | 366 k3ByteReservedSize, k4ByteReservedSize, |
| 368 k2ByteReservedSize, | 367 k5ByteReservedSize, k6ByteReservedSize, |
| 369 k3ByteReservedSize, | 368 k7ByteReservedSize, k8ByteReservedSize}; |
| 370 k4ByteReservedSize, | |
| 371 k5ByteReservedSize, | |
| 372 k6ByteReservedSize, | |
| 373 k7ByteReservedSize, | |
| 374 k8ByteReservedSize | |
| 375 }; | |
| 376 | 369 |
| 377 for (size_t i = 0; i < arraysize(kBuffers); i++) { | 370 for (size_t i = 0; i < arraysize(kBuffers); i++) { |
| 378 int id; | 371 int id; |
| 379 int64 element_size; | 372 int64_t element_size; |
| 380 int buffer_size = 2 + i; | 373 int buffer_size = 2 + i; |
| 381 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size, | 374 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size, |
| 382 &id, &element_size)); | 375 &id, &element_size)); |
| 383 EXPECT_EQ(id, 0xA3); | 376 EXPECT_EQ(id, 0xA3); |
| 384 EXPECT_EQ(element_size, kWebMUnknownSize); | 377 EXPECT_EQ(element_size, kWebMUnknownSize); |
| 385 } | 378 } |
| 386 } | 379 } |
| 387 | 380 |
| 388 TEST_F(WebMParserTest, ZeroPaddedStrings) { | 381 TEST_F(WebMParserTest, ZeroPaddedStrings) { |
| 389 const uint8 kBuffer[] = { | 382 const uint8_t kBuffer[] = { |
| 390 0x1A, 0x45, 0xDF, 0xA3, 0x91, // EBMLHEADER (size = 17) | 383 0x1A, 0x45, 0xDF, 0xA3, 0x91, // EBMLHEADER (size = 17) |
| 391 0x42, 0x82, 0x80, // DocType (size = 0) | 384 0x42, 0x82, 0x80, // DocType (size = 0) |
| 392 0x42, 0x82, 0x81, 0x00, // DocType (size = 1) "" | 385 0x42, 0x82, 0x81, 0x00, // DocType (size = 1) "" |
| 393 0x42, 0x82, 0x81, 'a', // DocType (size = 1) "a" | 386 0x42, 0x82, 0x81, 'a', // DocType (size = 1) "a" |
| 394 0x42, 0x82, 0x83, 'a', 0x00, 0x00 // DocType (size = 3) "a" | 387 0x42, 0x82, 0x83, 'a', 0x00, |
| 388 0x00 // DocType (size = 3) "a" |
| 395 }; | 389 }; |
| 396 int size = sizeof(kBuffer); | 390 int size = sizeof(kBuffer); |
| 397 | 391 |
| 398 InSequence s; | 392 InSequence s; |
| 399 EXPECT_CALL(client_, OnListStart(kWebMIdEBMLHeader)) | 393 EXPECT_CALL(client_, OnListStart(kWebMIdEBMLHeader)) |
| 400 .WillOnce(Return(&client_)); | 394 .WillOnce(Return(&client_)); |
| 401 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true)); | 395 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true)); |
| 402 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true)); | 396 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true)); |
| 403 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true)); | 397 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true)); |
| 404 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true)); | 398 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true)); |
| 405 EXPECT_CALL(client_, OnListEnd(kWebMIdEBMLHeader)).WillOnce(Return(true)); | 399 EXPECT_CALL(client_, OnListEnd(kWebMIdEBMLHeader)).WillOnce(Return(true)); |
| 406 | 400 |
| 407 WebMListParser parser(kWebMIdEBMLHeader, &client_); | 401 WebMListParser parser(kWebMIdEBMLHeader, &client_); |
| 408 EXPECT_EQ(size, parser.Parse(kBuffer, size)); | 402 EXPECT_EQ(size, parser.Parse(kBuffer, size)); |
| 409 EXPECT_TRUE(parser.IsParsingComplete()); | 403 EXPECT_TRUE(parser.IsParsingComplete()); |
| 410 } | 404 } |
| 411 | 405 |
| 412 } // namespace media | 406 } // namespace media |
| OLD | NEW |