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 <string.h> | 5 #include <string.h> |
6 | 6 |
7 #include "base/basictypes.h" | |
8 #include "base/logging.h" | 7 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
10 #include "media/base/mock_media_log.h" | 9 #include "media/base/mock_media_log.h" |
11 #include "media/formats/mp4/box_definitions.h" | 10 #include "media/formats/mp4/box_definitions.h" |
12 #include "media/formats/mp4/box_reader.h" | 11 #include "media/formats/mp4/box_reader.h" |
13 #include "media/formats/mp4/rcheck.h" | 12 #include "media/formats/mp4/rcheck.h" |
14 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
16 | 15 |
17 using ::testing::HasSubstr; | 16 using ::testing::HasSubstr; |
18 using ::testing::StrictMock; | 17 using ::testing::StrictMock; |
19 | 18 |
20 namespace media { | 19 namespace media { |
21 namespace mp4 { | 20 namespace mp4 { |
22 | 21 |
23 static const uint8 kSkipBox[] = { | 22 static const uint8_t kSkipBox[] = { |
24 // Top-level test box containing three children | 23 // Top-level test box containing three children |
25 0x00, 0x00, 0x00, 0x40, 's', 'k', 'i', 'p', | 24 0x00, 0x00, 0x00, 0x40, 's', 'k', 'i', 'p', 0x01, 0x02, 0x03, 0x04, 0x05, |
26 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | 25 0x06, 0x07, 0x08, 0xf9, 0x0a, 0x0b, 0x0c, 0xfd, 0x0e, 0x0f, 0x10, |
27 0xf9, 0x0a, 0x0b, 0x0c, 0xfd, 0x0e, 0x0f, 0x10, | 26 // Ordinary (8-byte header) child box |
28 // Ordinary (8-byte header) child box | 27 0x00, 0x00, 0x00, 0x0c, 'p', 's', 's', 'h', 0xde, 0xad, 0xbe, 0xef, |
29 0x00, 0x00, 0x00, 0x0c, 'p', 's', 's', 'h', 0xde, 0xad, 0xbe, 0xef, | 28 // Extended-size header child box |
30 // Extended-size header child box | 29 0x00, 0x00, 0x00, 0x01, 'p', 's', 's', 'h', 0x00, 0x00, 0x00, 0x00, 0x00, |
31 0x00, 0x00, 0x00, 0x01, 'p', 's', 's', 'h', | 30 0x00, 0x00, 0x14, 0xfa, 0xce, 0xca, 0xfe, |
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, | 31 // Empty free box |
33 0xfa, 0xce, 0xca, 0xfe, | 32 0x00, 0x00, 0x00, 0x08, 'f', 'r', 'e', 'e', |
34 // Empty free box | 33 // Trailing garbage |
35 0x00, 0x00, 0x00, 0x08, 'f', 'r', 'e', 'e', | 34 0x00}; |
36 // Trailing garbage | |
37 0x00 }; | |
38 | 35 |
39 struct FreeBox : Box { | 36 struct FreeBox : Box { |
40 bool Parse(BoxReader* reader) override { | 37 bool Parse(BoxReader* reader) override { |
41 return true; | 38 return true; |
42 } | 39 } |
43 FourCC BoxType() const override { return FOURCC_FREE; } | 40 FourCC BoxType() const override { return FOURCC_FREE; } |
44 }; | 41 }; |
45 | 42 |
46 struct PsshBox : Box { | 43 struct PsshBox : Box { |
47 uint32 val; | 44 uint32_t val; |
48 | 45 |
49 bool Parse(BoxReader* reader) override { | 46 bool Parse(BoxReader* reader) override { |
50 return reader->Read4(&val); | 47 return reader->Read4(&val); |
51 } | 48 } |
52 FourCC BoxType() const override { return FOURCC_PSSH; } | 49 FourCC BoxType() const override { return FOURCC_PSSH; } |
53 }; | 50 }; |
54 | 51 |
55 struct SkipBox : Box { | 52 struct SkipBox : Box { |
56 uint8 a, b; | 53 uint8_t a, b; |
57 uint16 c; | 54 uint16_t c; |
58 int32 d; | 55 int32_t d; |
59 int64 e; | 56 int64_t e; |
60 | 57 |
61 std::vector<PsshBox> kids; | 58 std::vector<PsshBox> kids; |
62 FreeBox mpty; | 59 FreeBox mpty; |
63 | 60 |
64 bool Parse(BoxReader* reader) override { | 61 bool Parse(BoxReader* reader) override { |
65 RCHECK(reader->ReadFullBoxHeader() && | 62 RCHECK(reader->ReadFullBoxHeader() && |
66 reader->Read1(&a) && | 63 reader->Read1(&a) && |
67 reader->Read1(&b) && | 64 reader->Read1(&b) && |
68 reader->Read2(&c) && | 65 reader->Read2(&c) && |
69 reader->Read4s(&d) && | 66 reader->Read4s(&d) && |
70 reader->Read4sInto8s(&e)); | 67 reader->Read4sInto8s(&e)); |
71 return reader->ScanChildren() && | 68 return reader->ScanChildren() && |
72 reader->ReadChildren(&kids) && | 69 reader->ReadChildren(&kids) && |
73 reader->MaybeReadChild(&mpty); | 70 reader->MaybeReadChild(&mpty); |
74 } | 71 } |
75 FourCC BoxType() const override { return FOURCC_SKIP; } | 72 FourCC BoxType() const override { return FOURCC_SKIP; } |
76 | 73 |
77 SkipBox(); | 74 SkipBox(); |
78 ~SkipBox() override; | 75 ~SkipBox() override; |
79 }; | 76 }; |
80 | 77 |
81 SkipBox::SkipBox() {} | 78 SkipBox::SkipBox() {} |
82 SkipBox::~SkipBox() {} | 79 SkipBox::~SkipBox() {} |
83 | 80 |
84 class BoxReaderTest : public testing::Test { | 81 class BoxReaderTest : public testing::Test { |
85 public: | 82 public: |
86 BoxReaderTest() : media_log_(new StrictMock<MockMediaLog>()) {} | 83 BoxReaderTest() : media_log_(new StrictMock<MockMediaLog>()) {} |
87 | 84 |
88 protected: | 85 protected: |
89 std::vector<uint8> GetBuf() { | 86 std::vector<uint8_t> GetBuf() { |
90 return std::vector<uint8>(kSkipBox, kSkipBox + sizeof(kSkipBox)); | 87 return std::vector<uint8_t>(kSkipBox, kSkipBox + sizeof(kSkipBox)); |
91 } | 88 } |
92 | 89 |
93 void TestTopLevelBox(const uint8* data, int size, uint32 fourCC) { | 90 void TestTopLevelBox(const uint8_t* data, int size, uint32_t fourCC) { |
94 std::vector<uint8> buf(data, data + size); | 91 std::vector<uint8_t> buf(data, data + size); |
95 | 92 |
96 bool err; | 93 bool err; |
97 scoped_ptr<BoxReader> reader( | 94 scoped_ptr<BoxReader> reader( |
98 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); | 95 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); |
99 | 96 |
100 EXPECT_FALSE(err); | 97 EXPECT_FALSE(err); |
101 EXPECT_TRUE(reader); | 98 EXPECT_TRUE(reader); |
102 EXPECT_EQ(fourCC, reader->type()); | 99 EXPECT_EQ(fourCC, reader->type()); |
103 EXPECT_EQ(reader->size(), static_cast<uint64>(size)); | 100 EXPECT_EQ(reader->size(), static_cast<uint64_t>(size)); |
104 } | 101 } |
105 | 102 |
106 scoped_refptr<StrictMock<MockMediaLog>> media_log_; | 103 scoped_refptr<StrictMock<MockMediaLog>> media_log_; |
107 }; | 104 }; |
108 | 105 |
109 TEST_F(BoxReaderTest, ExpectedOperationTest) { | 106 TEST_F(BoxReaderTest, ExpectedOperationTest) { |
110 std::vector<uint8> buf = GetBuf(); | 107 std::vector<uint8_t> buf = GetBuf(); |
111 bool err; | 108 bool err; |
112 scoped_ptr<BoxReader> reader( | 109 scoped_ptr<BoxReader> reader( |
113 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); | 110 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); |
114 EXPECT_FALSE(err); | 111 EXPECT_FALSE(err); |
115 EXPECT_TRUE(reader.get()); | 112 EXPECT_TRUE(reader.get()); |
116 | 113 |
117 SkipBox box; | 114 SkipBox box; |
118 EXPECT_TRUE(box.Parse(reader.get())); | 115 EXPECT_TRUE(box.Parse(reader.get())); |
119 EXPECT_EQ(0x01, reader->version()); | 116 EXPECT_EQ(0x01, reader->version()); |
120 EXPECT_EQ(0x020304u, reader->flags()); | 117 EXPECT_EQ(0x020304u, reader->flags()); |
121 EXPECT_EQ(0x05, box.a); | 118 EXPECT_EQ(0x05, box.a); |
122 EXPECT_EQ(0x06, box.b); | 119 EXPECT_EQ(0x06, box.b); |
123 EXPECT_EQ(0x0708, box.c); | 120 EXPECT_EQ(0x0708, box.c); |
124 EXPECT_EQ(static_cast<int32>(0xf90a0b0c), box.d); | 121 EXPECT_EQ(static_cast<int32_t>(0xf90a0b0c), box.d); |
125 EXPECT_EQ(static_cast<int32>(0xfd0e0f10), box.e); | 122 EXPECT_EQ(static_cast<int32_t>(0xfd0e0f10), box.e); |
126 | 123 |
127 EXPECT_EQ(2u, box.kids.size()); | 124 EXPECT_EQ(2u, box.kids.size()); |
128 EXPECT_EQ(0xdeadbeef, box.kids[0].val); | 125 EXPECT_EQ(0xdeadbeef, box.kids[0].val); |
129 EXPECT_EQ(0xfacecafe, box.kids[1].val); | 126 EXPECT_EQ(0xfacecafe, box.kids[1].val); |
130 | 127 |
131 // Accounting for the extra byte outside of the box above | 128 // Accounting for the extra byte outside of the box above |
132 EXPECT_EQ(buf.size(), static_cast<uint64>(reader->size() + 1)); | 129 EXPECT_EQ(buf.size(), static_cast<uint64_t>(reader->size() + 1)); |
133 } | 130 } |
134 | 131 |
135 TEST_F(BoxReaderTest, OuterTooShortTest) { | 132 TEST_F(BoxReaderTest, OuterTooShortTest) { |
136 std::vector<uint8> buf = GetBuf(); | 133 std::vector<uint8_t> buf = GetBuf(); |
137 bool err; | 134 bool err; |
138 | 135 |
139 // Create a soft failure by truncating the outer box. | 136 // Create a soft failure by truncating the outer box. |
140 scoped_ptr<BoxReader> r( | 137 scoped_ptr<BoxReader> r( |
141 BoxReader::ReadTopLevelBox(&buf[0], buf.size() - 2, media_log_, &err)); | 138 BoxReader::ReadTopLevelBox(&buf[0], buf.size() - 2, media_log_, &err)); |
142 | 139 |
143 EXPECT_FALSE(err); | 140 EXPECT_FALSE(err); |
144 EXPECT_FALSE(r.get()); | 141 EXPECT_FALSE(r.get()); |
145 } | 142 } |
146 | 143 |
147 TEST_F(BoxReaderTest, InnerTooLongTest) { | 144 TEST_F(BoxReaderTest, InnerTooLongTest) { |
148 std::vector<uint8> buf = GetBuf(); | 145 std::vector<uint8_t> buf = GetBuf(); |
149 bool err; | 146 bool err; |
150 | 147 |
151 // Make an inner box too big for its outer box. | 148 // Make an inner box too big for its outer box. |
152 buf[25] = 1; | 149 buf[25] = 1; |
153 scoped_ptr<BoxReader> reader( | 150 scoped_ptr<BoxReader> reader( |
154 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); | 151 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); |
155 | 152 |
156 SkipBox box; | 153 SkipBox box; |
157 EXPECT_FALSE(box.Parse(reader.get())); | 154 EXPECT_FALSE(box.Parse(reader.get())); |
158 } | 155 } |
159 | 156 |
160 TEST_F(BoxReaderTest, WrongFourCCTest) { | 157 TEST_F(BoxReaderTest, WrongFourCCTest) { |
161 std::vector<uint8> buf = GetBuf(); | 158 std::vector<uint8_t> buf = GetBuf(); |
162 bool err; | 159 bool err; |
163 | 160 |
164 // Set an unrecognized top-level FourCC. | 161 // Set an unrecognized top-level FourCC. |
165 buf[5] = 1; | 162 buf[5] = 1; |
166 | 163 |
167 EXPECT_MEDIA_LOG(HasSubstr("Unrecognized top-level box type s\\u0001ip")); | 164 EXPECT_MEDIA_LOG(HasSubstr("Unrecognized top-level box type s\\u0001ip")); |
168 | 165 |
169 scoped_ptr<BoxReader> reader( | 166 scoped_ptr<BoxReader> reader( |
170 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); | 167 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); |
171 EXPECT_FALSE(reader.get()); | 168 EXPECT_FALSE(reader.get()); |
172 EXPECT_TRUE(err); | 169 EXPECT_TRUE(err); |
173 } | 170 } |
174 | 171 |
175 TEST_F(BoxReaderTest, ScanChildrenTest) { | 172 TEST_F(BoxReaderTest, ScanChildrenTest) { |
176 std::vector<uint8> buf = GetBuf(); | 173 std::vector<uint8_t> buf = GetBuf(); |
177 bool err; | 174 bool err; |
178 scoped_ptr<BoxReader> reader( | 175 scoped_ptr<BoxReader> reader( |
179 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); | 176 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); |
180 | 177 |
181 EXPECT_TRUE(reader->SkipBytes(16) && reader->ScanChildren()); | 178 EXPECT_TRUE(reader->SkipBytes(16) && reader->ScanChildren()); |
182 | 179 |
183 FreeBox free; | 180 FreeBox free; |
184 EXPECT_TRUE(reader->ReadChild(&free)); | 181 EXPECT_TRUE(reader->ReadChild(&free)); |
185 EXPECT_FALSE(reader->ReadChild(&free)); | 182 EXPECT_FALSE(reader->ReadChild(&free)); |
186 EXPECT_TRUE(reader->MaybeReadChild(&free)); | 183 EXPECT_TRUE(reader->MaybeReadChild(&free)); |
187 | 184 |
188 std::vector<PsshBox> kids; | 185 std::vector<PsshBox> kids; |
189 | 186 |
190 EXPECT_TRUE(reader->ReadChildren(&kids)); | 187 EXPECT_TRUE(reader->ReadChildren(&kids)); |
191 EXPECT_EQ(2u, kids.size()); | 188 EXPECT_EQ(2u, kids.size()); |
192 kids.clear(); | 189 kids.clear(); |
193 EXPECT_FALSE(reader->ReadChildren(&kids)); | 190 EXPECT_FALSE(reader->ReadChildren(&kids)); |
194 EXPECT_TRUE(reader->MaybeReadChildren(&kids)); | 191 EXPECT_TRUE(reader->MaybeReadChildren(&kids)); |
195 } | 192 } |
196 | 193 |
197 TEST_F(BoxReaderTest, ReadAllChildrenTest) { | 194 TEST_F(BoxReaderTest, ReadAllChildrenTest) { |
198 std::vector<uint8> buf = GetBuf(); | 195 std::vector<uint8_t> buf = GetBuf(); |
199 // Modify buffer to exclude its last 'free' box | 196 // Modify buffer to exclude its last 'free' box |
200 buf[3] = 0x38; | 197 buf[3] = 0x38; |
201 bool err; | 198 bool err; |
202 scoped_ptr<BoxReader> reader( | 199 scoped_ptr<BoxReader> reader( |
203 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); | 200 BoxReader::ReadTopLevelBox(&buf[0], buf.size(), media_log_, &err)); |
204 | 201 |
205 std::vector<PsshBox> kids; | 202 std::vector<PsshBox> kids; |
206 EXPECT_TRUE(reader->SkipBytes(16) && reader->ReadAllChildren(&kids)); | 203 EXPECT_TRUE(reader->SkipBytes(16) && reader->ReadAllChildren(&kids)); |
207 EXPECT_EQ(2u, kids.size()); | 204 EXPECT_EQ(2u, kids.size()); |
208 EXPECT_EQ(kids[0].val, 0xdeadbeef); // Ensure order is preserved | 205 EXPECT_EQ(kids[0].val, 0xdeadbeef); // Ensure order is preserved |
209 } | 206 } |
210 | 207 |
211 TEST_F(BoxReaderTest, SkippingBloc) { | 208 TEST_F(BoxReaderTest, SkippingBloc) { |
212 static const uint8 kData[] = { | 209 static const uint8_t kData[] = {0x00, 0x00, 0x00, 0x09, 'b', |
213 0x00, 0x00, 0x00, 0x09, 'b', 'l', 'o', 'c', 0x00 | 210 'l', 'o', 'c', 0x00}; |
214 }; | |
215 | 211 |
216 TestTopLevelBox(kData, sizeof(kData), FOURCC_BLOC); | 212 TestTopLevelBox(kData, sizeof(kData), FOURCC_BLOC); |
217 } | 213 } |
218 | 214 |
219 TEST_F(BoxReaderTest, SkippingEmsg) { | 215 TEST_F(BoxReaderTest, SkippingEmsg) { |
220 static const uint8 kData[] = { | 216 static const uint8_t kData[] = { |
221 0x00, 0x00, 0x00, 0x24, 'e', 'm', 's', 'g', | 217 0x00, 0x00, 0x00, 0x24, 'e', 'm', 's', 'g', |
222 0x00, // version = 0 | 218 0x00, // version = 0 |
223 0x00, 0x00, 0x00, // flags = 0 | 219 0x00, 0x00, 0x00, // flags = 0 |
224 0x61, 0x00, // scheme_id_uri = "a" | 220 0x61, 0x00, // scheme_id_uri = "a" |
225 0x61, 0x00, // value = "a" | 221 0x61, 0x00, // value = "a" |
226 0x00, 0x00, 0x00, 0x01, // timescale = 1 | 222 0x00, 0x00, 0x00, 0x01, // timescale = 1 |
227 0x00, 0x00, 0x00, 0x02, // presentation_time_delta = 2 | 223 0x00, 0x00, 0x00, 0x02, // presentation_time_delta = 2 |
228 0x00, 0x00, 0x00, 0x03, // event_duration = 3 | 224 0x00, 0x00, 0x00, 0x03, // event_duration = 3 |
229 0x00, 0x00, 0x00, 0x04, // id = 4 | 225 0x00, 0x00, 0x00, 0x04, // id = 4 |
230 0x05, 0x06, 0x07, 0x08, // message_data[4] = 0x05060708 | 226 0x05, 0x06, 0x07, 0x08, // message_data[4] = 0x05060708 |
231 }; | 227 }; |
232 | 228 |
233 TestTopLevelBox(kData, sizeof(kData), FOURCC_EMSG); | 229 TestTopLevelBox(kData, sizeof(kData), FOURCC_EMSG); |
234 } | 230 } |
235 | 231 |
236 TEST_F(BoxReaderTest, SkippingUuid) { | 232 TEST_F(BoxReaderTest, SkippingUuid) { |
237 static const uint8 kData[] = { | 233 static const uint8_t kData[] = { |
238 0x00, 0x00, 0x00, 0x19, 'u', 'u', 'i', 'd', | 234 0x00, 0x00, 0x00, 0x19, 'u', 'u', 'i', 'd', |
239 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | 235 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, |
240 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, // usertype | 236 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, // usertype |
241 0x00, | 237 0x00, |
242 }; | 238 }; |
243 | 239 |
244 TestTopLevelBox(kData, sizeof(kData), FOURCC_UUID); | 240 TestTopLevelBox(kData, sizeof(kData), FOURCC_UUID); |
245 } | 241 } |
246 | 242 |
247 TEST_F(BoxReaderTest, NestedBoxWithHugeSize) { | 243 TEST_F(BoxReaderTest, NestedBoxWithHugeSize) { |
248 // This data is not a valid 'emsg' box. It is just used as a top-level box | 244 // This data is not a valid 'emsg' box. It is just used as a top-level box |
249 // as ReadTopLevelBox() has a restricted set of boxes it allows. |kData| | 245 // as ReadTopLevelBox() has a restricted set of boxes it allows. |kData| |
250 // contains all the bytes as specified by the 'emsg' header size. | 246 // contains all the bytes as specified by the 'emsg' header size. |
251 // The nested box ('junk') has a large size that was chosen to catch | 247 // The nested box ('junk') has a large size that was chosen to catch |
252 // integer overflows. The nested box should not specify more than the | 248 // integer overflows. The nested box should not specify more than the |
253 // number of remaining bytes in the enclosing box. | 249 // number of remaining bytes in the enclosing box. |
254 static const uint8 kData[] = { | 250 static const uint8_t kData[] = { |
255 0x00, 0x00, 0x00, 0x24, 'e', 'm', 's', 'g', // outer box | 251 0x00, 0x00, 0x00, 0x24, 'e', 'm', 's', 'g', // outer box |
256 0x7f, 0xff, 0xff, 0xff, 'j', 'u', 'n', 'k', // nested box | 252 0x7f, 0xff, 0xff, 0xff, 'j', 'u', 'n', 'k', // nested box |
257 0x00, 0x01, 0x00, 0xff, 0xff, 0x00, 0x3b, 0x03, // random data for rest | 253 0x00, 0x01, 0x00, 0xff, 0xff, 0x00, 0x3b, 0x03, // random data for rest |
258 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08}; | 254 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08}; |
259 | 255 |
260 bool err; | 256 bool err; |
261 scoped_ptr<BoxReader> reader( | 257 scoped_ptr<BoxReader> reader( |
262 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); | 258 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); |
263 | 259 |
264 EXPECT_FALSE(err); | 260 EXPECT_FALSE(err); |
265 EXPECT_TRUE(reader); | 261 EXPECT_TRUE(reader); |
266 EXPECT_EQ(FOURCC_EMSG, reader->type()); | 262 EXPECT_EQ(FOURCC_EMSG, reader->type()); |
267 EXPECT_FALSE(reader->ScanChildren()); | 263 EXPECT_FALSE(reader->ScanChildren()); |
268 } | 264 } |
269 | 265 |
270 TEST_F(BoxReaderTest, ScanChildrenWithInvalidChild) { | 266 TEST_F(BoxReaderTest, ScanChildrenWithInvalidChild) { |
271 // This data is not a valid 'emsg' box. It is just used as a top-level box | 267 // This data is not a valid 'emsg' box. It is just used as a top-level box |
272 // as ReadTopLevelBox() has a restricted set of boxes it allows. | 268 // as ReadTopLevelBox() has a restricted set of boxes it allows. |
273 // The nested 'elst' box is used as it includes a count of EditListEntry's. | 269 // The nested 'elst' box is used as it includes a count of EditListEntry's. |
274 // The sample specifies a large number of EditListEntry's, but only 1 is | 270 // The sample specifies a large number of EditListEntry's, but only 1 is |
275 // actually included in the box. This test verifies that the code checks | 271 // actually included in the box. This test verifies that the code checks |
276 // properly that the buffer contains the specified number of EditListEntry's | 272 // properly that the buffer contains the specified number of EditListEntry's |
277 // (does not cause an int32 overflow when checking that the bytes are | 273 // (does not cause an int32_t overflow when checking that the bytes are |
278 // available, and does not read past the end of the buffer). | 274 // available, and does not read past the end of the buffer). |
279 static const uint8 kData[] = { | 275 static const uint8_t kData[] = { |
280 0x00, 0x00, 0x00, 0x2c, 'e', 'm', 's', 'g', // outer box | 276 0x00, 0x00, 0x00, 0x2c, 'e', 'm', 's', 'g', // outer box |
281 0x00, 0x00, 0x00, 0x24, 'e', 'l', 's', 't', // nested box | 277 0x00, 0x00, 0x00, 0x24, 'e', 'l', 's', 't', // nested box |
282 0x01, 0x00, 0x00, 0x00, // version = 1, flags = 0 | 278 0x01, 0x00, 0x00, 0x00, // version = 1, flags = 0 |
283 0xff, 0xff, 0xff, 0xff, // count = max, but only 1 actually included | 279 0xff, 0xff, 0xff, 0xff, // count = max, but only 1 actually included |
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
286 | 282 |
287 bool err; | 283 bool err; |
288 scoped_ptr<BoxReader> reader( | 284 scoped_ptr<BoxReader> reader( |
289 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); | 285 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); |
290 | 286 |
291 EXPECT_FALSE(err); | 287 EXPECT_FALSE(err); |
292 EXPECT_TRUE(reader); | 288 EXPECT_TRUE(reader); |
293 EXPECT_EQ(FOURCC_EMSG, reader->type()); | 289 EXPECT_EQ(FOURCC_EMSG, reader->type()); |
294 EXPECT_TRUE(reader->ScanChildren()); | 290 EXPECT_TRUE(reader->ScanChildren()); |
295 | 291 |
296 // 'elst' specifies lots of EditListEntry's but only includes 1. Thus | 292 // 'elst' specifies lots of EditListEntry's but only includes 1. Thus |
297 // parsing it should fail. | 293 // parsing it should fail. |
298 EditList child; | 294 EditList child; |
299 EXPECT_FALSE(reader->ReadChild(&child)); | 295 EXPECT_FALSE(reader->ReadChild(&child)); |
300 } | 296 } |
301 | 297 |
302 TEST_F(BoxReaderTest, ReadAllChildrenWithInvalidChild) { | 298 TEST_F(BoxReaderTest, ReadAllChildrenWithInvalidChild) { |
303 // This data is not a valid 'emsg' box. It is just used as a top-level box | 299 // This data is not a valid 'emsg' box. It is just used as a top-level box |
304 // as ReadTopLevelBox() has a restricted set of boxes it allows. | 300 // as ReadTopLevelBox() has a restricted set of boxes it allows. |
305 // The nested 'trun' box is used as it includes a count of the number | 301 // The nested 'trun' box is used as it includes a count of the number |
306 // of samples. The data specifies a large number of samples, but only 1 | 302 // of samples. The data specifies a large number of samples, but only 1 |
307 // is actually included in the box. Verifying that the large count does not | 303 // is actually included in the box. Verifying that the large count does not |
308 // cause an int32 overflow which would allow parsing of TrackFragmentRun | 304 // cause an int32_t overflow which would allow parsing of TrackFragmentRun |
309 // to read past the end of the buffer. | 305 // to read past the end of the buffer. |
310 static const uint8 kData[] = { | 306 static const uint8_t kData[] = { |
311 0x00, 0x00, 0x00, 0x28, 'e', 'm', 's', 'g', // outer box | 307 0x00, 0x00, 0x00, 0x28, 'e', 'm', 's', 'g', // outer box |
312 0x00, 0x00, 0x00, 0x20, 't', 'r', 'u', 'n', // nested box | 308 0x00, 0x00, 0x00, 0x20, 't', 'r', 'u', 'n', // nested box |
313 0x00, 0x00, 0x0f, 0x00, // version = 0, flags = samples present | 309 0x00, 0x00, 0x0f, 0x00, // version = 0, flags = samples present |
314 0xff, 0xff, 0xff, 0xff, // count = max, but only 1 actually included | 310 0xff, 0xff, 0xff, 0xff, // count = max, but only 1 actually included |
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
317 | 313 |
318 bool err; | 314 bool err; |
319 scoped_ptr<BoxReader> reader( | 315 scoped_ptr<BoxReader> reader( |
320 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); | 316 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); |
321 | 317 |
322 EXPECT_FALSE(err); | 318 EXPECT_FALSE(err); |
323 EXPECT_TRUE(reader); | 319 EXPECT_TRUE(reader); |
324 EXPECT_EQ(FOURCC_EMSG, reader->type()); | 320 EXPECT_EQ(FOURCC_EMSG, reader->type()); |
325 | 321 |
326 // Reading the child should fail since the number of samples specified | 322 // Reading the child should fail since the number of samples specified |
327 // doesn't match what is in the box. | 323 // doesn't match what is in the box. |
328 std::vector<TrackFragmentRun> children; | 324 std::vector<TrackFragmentRun> children; |
329 EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children)); | 325 EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children)); |
330 } | 326 } |
331 | 327 |
332 } // namespace mp4 | 328 } // namespace mp4 |
333 } // namespace media | 329 } // namespace media |
OLD | NEW |