1 // Copyright (c) 2016 The WebM project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 #include "src/block_parser.h"
9
10 #include <cstdint>
11 #include <memory>
12 #include <type_traits>
13 #include <vector>
14
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17
18 #include "src/parser_utils.h"
19 #include "test_utils/element_parser_test.h"
20 #include "webm/id.h"
21 #include "webm/status.h"
22
23 using testing::_;
24 using testing::Between;
25 using testing::DoAll;
26 using testing::Exactly;
27 using testing::InSequence;
28 using testing::Invoke;
29 using testing::NotNull;
30 using testing::Return;
31 using testing::SetArgPointee;
32
33 using webm::Action;
34 using webm::Block;
35 using webm::BlockParser;
36 using webm::ElementParserTest;
37 using webm::FrameMetadata;
38 using webm::Id;
39 using webm::kUnknownElementSize;
40 using webm::Lacing;
41 using webm::ReadByte;
42 using webm::Reader;
43 using webm::SimpleBlock;
44 using webm::SimpleBlockParser;
45 using webm::Status;
46
47 namespace {
48
49 // Represents a single block and its expected parsing results for use in tests.
50 struct TestData {
51 // Block data.
52 std::vector<std::uint8_t> data;
53
54 // Expected results.
55 std::uint64_t expected_track_number;
56 std::int16_t expected_timecode;
57 Lacing expected_lacing;
58 bool expected_is_visible;
59 bool expected_is_key_frame;
60 bool expected_is_discardable;
61 int expected_num_frames;
62
63 std::uint64_t expected_frame_start_position;
64 std::vector<std::uint64_t> expected_frame_sizes;
65 };
66
67 // Test data for an EBML-laced block containing only one frame.
68 const TestData ebml_lacing_one_frame = {
69 // Data.
70 {
71 0x81, // Track number = 1.
72 0x00,
73 0x00, // Timecode = 0.
74 0x86, // Flags = key_frame | ebml_lacing.
75 0x00, // Lace count - 1 = 0 (1 frame).
76
77 // Lace data (1 frame).
78 // Frame 0.
79 0x00,
80 },
81
82 // Expected results.
83 1, // expected_track_number
84 0, // expected_timecode
85 Lacing::kEbml, // expected_lacing
86 true, // expected_is_visible
87 true, // expected_is_key_frame
88 false, // expected_is_discardable
89 1, // expected_num_frames
90
91 5, // expected_frame_start_position
92 // expected_frame_sizes
93 {1},
94 };
95
96 // Test data for a Xiph-laced block containing only one frame.
97 const TestData xiph_lacing_one_frame = {
98 // Data.
99 {
100 0x81, // Track number = 1.
101 0x00,
102 0x00, // Timecode = 0.
103 0x82, // Flags = key_frame | xiph_lacing.
104 0x00, // Lace count - 1 = 0 (1 frame).
105
106 // Lace data (1 frame).
107 // Frame 0.
108 0x00,
109 },
110
111 // Expected results.
112 1, // expected_track_number
113 0, // expected_timecode
114 Lacing::kXiph, // expected_lacing
115 true, // expected_is_visible
116 true, // expected_is_key_frame
117 false, // expected_is_discardable
118 1, // expected_num_frames
119
120 5, // expected_frame_start_position
121 // expected_frame_sizes
122 {1},
123 };
124
125 // Test data for a fixed-laced block containing only one frame.
126 const TestData fixed_lacing_one_frame = {
127 // Data.
128 {
129 0x81, // Track number = 1.
130 0x00,
131 0x00, // Timecode = 0.
132 0x84, // Flags = key_frame | fixed_lacing.
133 0x00, // Lace count - 1 = 0 (1 frame).
134
135 // Lace data (1 frame).
136 0x00,
137 },
138
139 // Expected results.
140 1, // expected_track_number
141 0, // expected_timecode
142 Lacing::kFixed, // expected_lacing
143 true, // expected_is_visible
144 true, // expected_is_key_frame
145 false, // expected_is_discardable
146 1, // expected_num_frames
147
148 5, // expected_frame_start_position
149 // expected_frame_sizes
150 {1},
151 };
152
153 // Test data for an EBML-laced block.
154 // clang-format off
155 const TestData ebml_lacing = {
156 // Data.
157 {
158 0x81, // Track number = 1.
159 0x00, 0x00, // Timecode = 0.
160 0x86, // Flags = key_frame | ebml_lacing.
161 0x05, // Lace count - 1 = 5 (6 frames).
162
163 // Lace data (6 frames).
164 0xFF, // Lace 0 size = 127.
165 0x5F, 0x81, // Lace 1 size = 1.
166 0xC0, // Lace 2 size = 2.
167 0xFF, // Lace 3 size = 66.
168 0x81, // Lace 4 size = 4.
169 // Lace 5 size inferred to be 5.
170
171 // Lace data (6 frames).
172 // Frame 0.
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184
185 // Frame 1.
186 0x01,
187
188 // Frame 2.
189 0x02, 0x02,
190
191 // Frame 3.
192 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
193 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
194 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
195 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
196 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
197 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
198
199 // Frame 4.
200 0x04, 0x04, 0x04, 0x04,
201
202 // Frame 5.
203 0x05, 0x05, 0x05, 0x05, 0x05,
204 },
205
206 // Expected results.
207 1, // expected_track_number
208 0, // expected_timecode
209 Lacing::kEbml, // expected_lacing
210 true, // expected_is_visible
211 true, // expected_is_key_frame
212 false, // expected_is_discardable
213 6, // expected_num_frames
214
215 11, // expected_frame_start_position
216 // expected_frame_sizes
217 {127, 1, 2, 66, 4, 5},
218 };
219
220 // Test data for a Xiph-laced block.
221 const TestData xiph_lacing = {
222 // Data.
223 {
224 0x81, // Track number = 1.
225 0x00, 0x00, // Timecode = 0.
226 0x82, // Flags = key_frame | xiph_lacing.
227 0x03, // Lace count - 1 = 3 (4 frames).
228
229 // Lace sizes.
230 0xFF, 0xFF, 0x00, // Lace 0 size = 510.
231 0xFF, 0x01, // Lace 1 size = 256.
232 0x02, // Lace 2 size = 2.
233 // Lace 3 size inferred to be 3.
234
235 // Lace data (4 frames).
236 // Frame 0.
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280
281 // Frame 1.
282 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
283 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
284 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
285 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
286 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
287 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
288 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
289 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
290 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
291 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
292 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
293 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
294 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
295 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
296 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
297 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
298 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
299 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
300 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
301 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
302 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
303 0x01, 0x01, 0x01, 0x01,
304
305 // Frame 2.
306 0x02, 0x02,
307
308 // Frame 3.
309 0x03, 0x03, 0x03,
310 },
311
312 // Expected results.
313 1, // expected_track_number
314 0, // expected_timecode
315 Lacing::kXiph, // expected_lacing
316 true, // expected_is_visible
317 true, // expected_is_key_frame
318 false, // expected_is_discardable
319 4, // expected_num_frames
320
321 11, // expected_frame_start_position
322 // expected_frame_sizes
323 {510, 256, 2, 3},
324 };
325 // clang-format on
326
327 // Test data for a fixed-laced block.
328 const TestData fixed_lacing = {
329 // Data.
330 {
331 0x81, // Track number = 1.
332 0x00, 0x00, // Timecode = 0.
333 0x84, // Flags = key_frame | fixed_lacing.
334 0x03, // Lace count - 1 = 3 (4 frames).
335
336 // Lace data (4 frames).
337 0x00, 0x00, // Frame 0.
338 0x01, 0x01, // Frame 1.
339 0x02, 0x02, // Frame 2.
340 0x03, 0x03, // Frame 3.
341 },
342
343 // Expected results.
344 1, // expected_track_number
345 0, // expected_timecode
346 Lacing::kFixed, // expected_lacing
347 true, // expected_is_visible
348 true, // expected_is_key_frame
349 false, // expected_is_discardable
350 4, // expected_num_frames
351
352 5, // expected_frame_start_position
353 // expected_frame_sizes
354 {2, 2, 2, 2},
355 };
356
357 // Test data for a block that has no lacing.
358 const TestData no_lacing = {
359 // Data.
360 {
361 0x40, 0x01, // Track number = 1.
362 0x00, 0x00, // Timecode = 0.
363 0x80, // Flags = key_frame.
364
365 // Lace data (1 frame).
366 0x00, 0x00, 0x00, // Frame 0.
367 },
368
369 // Expected results.
370 1, // expected_track_number
371 0, // expected_timecode
372 Lacing::kNone, // expected_lacing
373 true, // expected_is_visible
374 true, // expected_is_key_frame
375 false, // expected_is_discardable
376 1, // expected_num_frames
377
378 5, // expected_frame_start_position
379 // expected_frame_sizes
380 {3},
381 };
382
383 // Test data for a block that has no flags set in the header.
384 const TestData no_flags = {
385 // Data.
386 {
387 0x81, // Track number = 1.
388 0x00,
389 0x00, // Timecode = 0.
390 0x00, // Flags = 0.
391
392 // Lace data (1 frame).
393 0x00,
394 },
395
396 // Expected results.
397 1, // expected_track_number
398 0, // expected_timecode
399 Lacing::kNone, // expected_lacing
400 true, // expected_is_visible
401 false, // expected_is_key_frame
402 false, // expected_is_discardable
403 1, // expected_num_frames
404
405 4, // expected_frame_start_position
406 // expected_frame_sizes
407 {1},
408 };
409
410 // Test data for a block that has all Block (ID = Id::kBlock (0xA1)) flags set
411 // in the header (and no other flags).
412 const TestData block_flags = {
413 // Data.
414 {
415 0x82, // Track number = 2.
416 0xFE,
417 0xDC, // Timecode = -292.
418 0x08, // Flags = invisible.
419
420 // Lace data (1 frame).
421 0x00,
422 },
423
424 // Expected results.
425 2, // expected_track_number
426 -292, // expected_timecode
427 Lacing::kNone, // expected_lacing
428 false, // expected_is_visible
429 false, // expected_is_key_frame
430 false, // expected_is_discardable
431 1, // expected_num_frames
432
433 4, // expected_frame_start_position
434 // expected_frame_sizes
435 {1},
436 };
437
438 // Test data for a block that has all SimpleBlock (ID = Id::kSimpleBlock (0xA3))
439 // flags set in the header.
440 const TestData simple_block_flags = {
441 // Data.
442 {
443 0x41,
444 0x23, // Track number = 291.
445 0x12,
446 0x34, // Timecode = 4660.
447 0x89, // Flags = key_frame | invisible | discardable.
448
449 // Lace data (1 frame).
450 0x00,
451 },
452
453 // Expected results.
454 291, // expected_track_number
455 4660, // expected_timecode
456 Lacing::kNone, // expected_lacing
457 false, // expected_is_visible
458 true, // expected_is_key_frame
459 true, // expected_is_discardable
460 1, // expected_num_frames
461
462 5, // expected_frame_start_position
463 // expected_frame_sizes
464 {1},
465 };
466
467 // Checks that the Block matches the expected results in the TestData.
ValidateBlock(const TestData & test_data,const Block & actual)468 void ValidateBlock(const TestData& test_data, const Block& actual) {
469 EXPECT_EQ(test_data.expected_track_number, actual.track_number);
470 EXPECT_EQ(test_data.expected_timecode, actual.timecode);
471 EXPECT_EQ(test_data.expected_is_visible, actual.is_visible);
472 EXPECT_EQ(test_data.expected_lacing, actual.lacing);
473 EXPECT_EQ(test_data.expected_num_frames, actual.num_frames);
474 }
475
476 // Checks that the SimpleBlock matches the expected results in the TestData.
ValidateBlock(const TestData & test_data,const SimpleBlock & actual)477 void ValidateBlock(const TestData& test_data, const SimpleBlock& actual) {
478 ValidateBlock(test_data, static_cast<const Block&>(actual));
479 EXPECT_EQ(test_data.expected_is_key_frame, actual.is_key_frame);
480 EXPECT_EQ(test_data.expected_is_discardable, actual.is_discardable);
481 }
482
483 // Constructs a SimpleBlock populated with the expected results for this test.
ExpectedSimpleBlock(const TestData & test_data)484 SimpleBlock ExpectedSimpleBlock(const TestData& test_data) {
485 SimpleBlock expected;
486 expected.track_number = test_data.expected_track_number;
487 expected.timecode = test_data.expected_timecode;
488 expected.lacing = test_data.expected_lacing;
489 expected.is_visible = test_data.expected_is_visible;
490 expected.is_key_frame = test_data.expected_is_key_frame;
491 expected.is_discardable = test_data.expected_is_discardable;
492 expected.num_frames = test_data.expected_num_frames;
493 return expected;
494 }
495
496 // Simple functor that can be used for Callback::OnFrame() that will validate
497 // the frame metadata and frame byte values.
498 struct FrameHandler {
499 // The expected value for the frame metadata.
500 FrameMetadata expected_metadata;
501
502 // The expected value for each byte in the frame.
503 std::uint8_t expected_frame_byte_value;
504
505 // Can be used for Callback::OnFrame() to consume data from the reader and
506 // validate the results.
operator ()__anon460ba0540111::FrameHandler507 Status operator()(const FrameMetadata& metadata, Reader* reader,
508 std::uint64_t* bytes_remaining) const {
509 EXPECT_EQ(expected_metadata, metadata);
510
511 std::uint8_t frame_byte_value;
512 Status status;
513 do {
514 status = ReadByte(reader, &frame_byte_value);
515 if (!status.completed_ok()) {
516 break;
517 }
518
519 EXPECT_EQ(expected_frame_byte_value, frame_byte_value);
520
521 --*bytes_remaining;
522 } while (*bytes_remaining > 0);
523
524 return status;
525 }
526 };
527
528 template <typename T, Id id>
529 class BasicBlockParserTest : public ElementParserTest<T, id> {
530 public:
531 // Sets expectations for a normal (i.e. successful parse) test.
SetExpectations(const TestData & test_data,bool incremental,bool set_action)532 void SetExpectations(const TestData& test_data, bool incremental,
533 bool set_action) {
534 InSequence dummy;
535
536 const SimpleBlock expected_simple_block = ExpectedSimpleBlock(test_data);
537 const Block expected_block = ExpectedSimpleBlock(test_data);
538
539 FrameMetadata metadata = FirstFrameMetadata(test_data);
540 if (std::is_same<T, SimpleBlockParser>::value) {
541 auto& expectation = EXPECT_CALL(
542 callback_, OnSimpleBlockBegin(metadata.parent_element,
543 expected_simple_block, NotNull()));
544 if (set_action) {
545 expectation.Times(1);
546 } else {
547 expectation.WillOnce(Return(Status(Status::kOkCompleted)));
548 }
549 EXPECT_CALL(callback_, OnBlockBegin(_, _, _)).Times(0);
550 } else {
551 auto& expectation = EXPECT_CALL(
552 callback_,
553 OnBlockBegin(metadata.parent_element, expected_block, NotNull()));
554 if (set_action) {
555 expectation.Times(1);
556 } else {
557 expectation.WillOnce(Return(Status(Status::kOkCompleted)));
558 }
559 EXPECT_CALL(callback_, OnSimpleBlockBegin(_, _, _)).Times(0);
560 }
561
562 std::uint8_t expected_frame_byte_value = 0;
563 for (const std::uint64_t frame_size : test_data.expected_frame_sizes) {
564 metadata.size = frame_size;
565 const FrameHandler frame_handler = {metadata, expected_frame_byte_value};
566
567 // Incremental parsing will call OnFrame once for every byte, plus
568 // maybe one more time if the first call reads zero bytes (if the reader
569 // is blocked).
570 const int this_frame_size = static_cast<int>(frame_size);
571 EXPECT_CALL(callback_, OnFrame(metadata, NotNull(), NotNull()))
572 .Times(incremental ? Between(this_frame_size, this_frame_size + 1)
573 : Exactly(1))
574 .WillRepeatedly(Invoke(frame_handler));
575
576 metadata.position += metadata.size;
577 ++expected_frame_byte_value;
578 }
579
580 if (std::is_same<T, SimpleBlockParser>::value) {
581 EXPECT_CALL(callback_, OnSimpleBlockEnd(metadata.parent_element,
582 expected_simple_block))
583 .Times(1);
584 EXPECT_CALL(callback_, OnBlockEnd(_, _)).Times(0);
585 } else {
586 EXPECT_CALL(callback_,
587 OnBlockEnd(metadata.parent_element, expected_block))
588 .Times(1);
589 EXPECT_CALL(callback_, OnSimpleBlockEnd(_, _)).Times(0);
590 }
591 }
592
593 // Runs a single test using the provided test data.
RunTest(const TestData & test_data)594 void RunTest(const TestData& test_data) {
595 SetReaderData(test_data.data);
596 SetExpectations(test_data, false, true);
597
598 ParseAndVerify();
599
600 ValidateBlock(test_data, parser_.value());
601 }
602
603 // Same as RunTest(), except it forces parsers to parse one byte at a time.
RunIncrementalTest(const TestData & test_data)604 void RunIncrementalTest(const TestData& test_data) {
605 SetReaderData(test_data.data);
606 SetExpectations(test_data, true, true);
607
608 IncrementalParseAndVerify();
609
610 ValidateBlock(test_data, parser_.value());
611 }
612
613 // Tests invalid element sizes.
TestInvalidElementSize()614 void TestInvalidElementSize() {
615 TestInit(0, Status::kInvalidElementSize);
616 TestInit(4, Status::kInvalidElementSize);
617 TestInit(kUnknownElementSize, Status::kInvalidElementSize);
618 }
619
620 // Tests invalid blocks by feeding only the header of the block into the
621 // parser.
TestInvalidHeaderOnly(const TestData & test_data)622 void TestInvalidHeaderOnly(const TestData& test_data) {
623 EXPECT_CALL(callback_, OnFrame(_, _, _)).Times(0);
624 EXPECT_CALL(callback_, OnBlockEnd(_, _)).Times(0);
625 EXPECT_CALL(callback_, OnSimpleBlockEnd(_, _)).Times(0);
626
627 SetReaderData(test_data.data);
628
629 ParseAndExpectResult(Status::kInvalidElementValue,
630 test_data.expected_frame_start_position);
631 }
632
633 // Tests an invalid fixed-lace block that has inconsistent frame sizes.
TestInvalidFixedLaceSizes()634 void TestInvalidFixedLaceSizes() {
635 SetReaderData({
636 0x81, // Track number = 1.
637 0x00, 0x00, // Timecode = 0.
638 0x84, // Flags = key_frame | fixed_lacing.
639 0x01, // Lace count - 1 = 1 (2 frames).
640
641 // Lace data (2 frames).
642 0x00, 0x00, // Frame 0.
643 0x01, // Frame 1 (invalid: inconsistent frame size).
644 });
645
646 EXPECT_CALL(callback_, OnFrame(_, _, _)).Times(0);
647 EXPECT_CALL(callback_, OnBlockEnd(_, _)).Times(0);
648 EXPECT_CALL(callback_, OnSimpleBlockEnd(_, _)).Times(0);
649
650 ParseAndExpectResult(Status::kInvalidElementValue);
651 }
652
653 // Tests setting the action to Action::kSkip in Callback::OnSimpleBlockBegin
654 // for the SimpleBlockParser.
TestSimpleBlockSkip(const TestData & test_data)655 void TestSimpleBlockSkip(const TestData& test_data) {
656 SetReaderData(test_data.data);
657
658 const SimpleBlock expected_simple_block = ExpectedSimpleBlock(test_data);
659 const FrameMetadata metadata = FirstFrameMetadata(test_data);
660
661 EXPECT_CALL(callback_, OnSimpleBlockBegin(metadata.parent_element,
662 expected_simple_block, NotNull()))
663 .WillOnce(Return(Status(Status::kOkPartial)))
664 .WillOnce(DoAll(SetArgPointee<2>(Action::kSkip),
665 Return(Status(Status::kOkCompleted))));
666
667 EXPECT_CALL(callback_, OnFrame(_, _, _)).Times(0);
668 EXPECT_CALL(callback_, OnBlockEnd(_, _)).Times(0);
669 EXPECT_CALL(callback_, OnSimpleBlockEnd(_, _)).Times(0);
670
671 IncrementalParseAndVerify();
672 }
673
674 protected:
675 using ElementParserTest<T, id>::callback_;
676 using ElementParserTest<T, id>::IncrementalParseAndVerify;
677 using ElementParserTest<T, id>::metadata_;
678 using ElementParserTest<T, id>::ParseAndExpectResult;
679 using ElementParserTest<T, id>::ParseAndVerify;
680 using ElementParserTest<T, id>::parser_;
681 using ElementParserTest<T, id>::SetReaderData;
682 using ElementParserTest<T, id>::TestInit;
683
684 private:
685 // Gets the FrameMetadata for the very first frame in the test data.
FirstFrameMetadata(const TestData & test_data)686 FrameMetadata FirstFrameMetadata(const TestData& test_data) {
687 FrameMetadata metadata;
688 metadata.parent_element = metadata_;
689 metadata.parent_element.size = test_data.data.size();
690 metadata.position = test_data.expected_frame_start_position +
691 metadata.parent_element.position +
692 metadata.parent_element.header_size;
693 metadata.size = test_data.expected_frame_sizes[0];
694 return metadata;
695 }
696 };
697
698 class BlockParserTest : public BasicBlockParserTest<BlockParser, Id::kBlock> {};
699
TEST_F(BlockParserTest,InvalidElementSize)700 TEST_F(BlockParserTest, InvalidElementSize) { TestInvalidElementSize(); }
701
TEST_F(BlockParserTest,InvalidHeaderOnlyNoLacing)702 TEST_F(BlockParserTest, InvalidHeaderOnlyNoLacing) {
703 TestInvalidHeaderOnly(no_lacing);
704 }
705
TEST_F(BlockParserTest,InvalidHeaderOnlyFixedLacing)706 TEST_F(BlockParserTest, InvalidHeaderOnlyFixedLacing) {
707 TestInvalidHeaderOnly(fixed_lacing);
708 }
709
TEST_F(BlockParserTest,InvalidFixedLaceSizes)710 TEST_F(BlockParserTest, InvalidFixedLaceSizes) { TestInvalidFixedLaceSizes(); }
711
TEST_F(BlockParserTest,BlockNoFlags)712 TEST_F(BlockParserTest, BlockNoFlags) { RunTest(no_flags); }
713
TEST_F(BlockParserTest,BlockFlags)714 TEST_F(BlockParserTest, BlockFlags) { RunTest(block_flags); }
715
TEST_F(BlockParserTest,EbmlLacingOneFrame)716 TEST_F(BlockParserTest, EbmlLacingOneFrame) { RunTest(ebml_lacing_one_frame); }
717
TEST_F(BlockParserTest,EbmlLacing)718 TEST_F(BlockParserTest, EbmlLacing) { RunTest(ebml_lacing); }
719
TEST_F(BlockParserTest,XiphLacingOneFrame)720 TEST_F(BlockParserTest, XiphLacingOneFrame) { RunTest(xiph_lacing_one_frame); }
721
TEST_F(BlockParserTest,XiphLacing)722 TEST_F(BlockParserTest, XiphLacing) { RunTest(xiph_lacing); }
723
TEST_F(BlockParserTest,FixedLacingOneFrame)724 TEST_F(BlockParserTest, FixedLacingOneFrame) {
725 RunTest(fixed_lacing_one_frame);
726 }
727
TEST_F(BlockParserTest,FixedLacing)728 TEST_F(BlockParserTest, FixedLacing) { RunTest(fixed_lacing); }
729
TEST_F(BlockParserTest,NoLacing)730 TEST_F(BlockParserTest, NoLacing) { RunTest(no_lacing); }
731
TEST_F(BlockParserTest,BlockWithPositionAndHeaderSize)732 TEST_F(BlockParserTest, BlockWithPositionAndHeaderSize) {
733 metadata_.position = 15;
734 metadata_.header_size = 3;
735 RunTest(no_lacing);
736 }
737
TEST_F(BlockParserTest,IncrementalBlockFlags)738 TEST_F(BlockParserTest, IncrementalBlockFlags) {
739 RunIncrementalTest(block_flags);
740 }
741
TEST_F(BlockParserTest,IncrementalEbmlLacingOneFrame)742 TEST_F(BlockParserTest, IncrementalEbmlLacingOneFrame) {
743 RunIncrementalTest(ebml_lacing_one_frame);
744 }
745
TEST_F(BlockParserTest,IncrementalEbmlLacing)746 TEST_F(BlockParserTest, IncrementalEbmlLacing) {
747 RunIncrementalTest(ebml_lacing);
748 }
749
TEST_F(BlockParserTest,IncrementalXiphLacingOneFrame)750 TEST_F(BlockParserTest, IncrementalXiphLacingOneFrame) {
751 RunIncrementalTest(xiph_lacing_one_frame);
752 }
753
TEST_F(BlockParserTest,IncrementalXiphLacing)754 TEST_F(BlockParserTest, IncrementalXiphLacing) {
755 RunIncrementalTest(xiph_lacing);
756 }
757
TEST_F(BlockParserTest,IncrementalFixedLacingOneFrame)758 TEST_F(BlockParserTest, IncrementalFixedLacingOneFrame) {
759 RunIncrementalTest(fixed_lacing_one_frame);
760 }
761
TEST_F(BlockParserTest,IncrementalFixedLacing)762 TEST_F(BlockParserTest, IncrementalFixedLacing) {
763 RunIncrementalTest(fixed_lacing);
764 }
765
TEST_F(BlockParserTest,DefaultActionIsRead)766 TEST_F(BlockParserTest, DefaultActionIsRead) {
767 SetReaderData(fixed_lacing_one_frame.data);
768 SetExpectations(fixed_lacing_one_frame, false, false);
769 ParseAndVerify();
770 ValidateBlock(fixed_lacing_one_frame, parser_.value());
771 }
772
TEST_F(BlockParserTest,IncrementalNoLacing)773 TEST_F(BlockParserTest, IncrementalNoLacing) { RunIncrementalTest(no_lacing); }
774
775 class SimpleBlockParserTest
776 : public BasicBlockParserTest<SimpleBlockParser, Id::kSimpleBlock> {};
777
TEST_F(SimpleBlockParserTest,InvalidElementSize)778 TEST_F(SimpleBlockParserTest, InvalidElementSize) { TestInvalidElementSize(); }
779
TEST_F(SimpleBlockParserTest,InvalidHeaderOnlyNoLacing)780 TEST_F(SimpleBlockParserTest, InvalidHeaderOnlyNoLacing) {
781 TestInvalidHeaderOnly(no_lacing);
782 }
783
TEST_F(SimpleBlockParserTest,InvalidHeaderOnlyFixedLacing)784 TEST_F(SimpleBlockParserTest, InvalidHeaderOnlyFixedLacing) {
785 TestInvalidHeaderOnly(fixed_lacing);
786 }
787
TEST_F(SimpleBlockParserTest,InvalidFixedLaceSizes)788 TEST_F(SimpleBlockParserTest, InvalidFixedLaceSizes) {
789 TestInvalidFixedLaceSizes();
790 }
791
TEST_F(SimpleBlockParserTest,SimpleBlockSkip)792 TEST_F(SimpleBlockParserTest, SimpleBlockSkip) {
793 TestSimpleBlockSkip(no_flags);
794 }
795
TEST_F(SimpleBlockParserTest,SimpleBlockNoFlags)796 TEST_F(SimpleBlockParserTest, SimpleBlockNoFlags) { RunTest(no_flags); }
797
TEST_F(SimpleBlockParserTest,SimpleBlockFlags)798 TEST_F(SimpleBlockParserTest, SimpleBlockFlags) { RunTest(simple_block_flags); }
799
TEST_F(SimpleBlockParserTest,EbmlLacingOneFrame)800 TEST_F(SimpleBlockParserTest, EbmlLacingOneFrame) {
801 RunTest(ebml_lacing_one_frame);
802 }
803
TEST_F(SimpleBlockParserTest,EbmlLacing)804 TEST_F(SimpleBlockParserTest, EbmlLacing) { RunTest(ebml_lacing); }
805
TEST_F(SimpleBlockParserTest,XiphLacingOneFrame)806 TEST_F(SimpleBlockParserTest, XiphLacingOneFrame) {
807 RunTest(xiph_lacing_one_frame);
808 }
809
TEST_F(SimpleBlockParserTest,XiphLacing)810 TEST_F(SimpleBlockParserTest, XiphLacing) { RunTest(xiph_lacing); }
811
TEST_F(SimpleBlockParserTest,FixedLacingOneFrame)812 TEST_F(SimpleBlockParserTest, FixedLacingOneFrame) {
813 RunTest(fixed_lacing_one_frame);
814 }
815
TEST_F(SimpleBlockParserTest,FixedLacing)816 TEST_F(SimpleBlockParserTest, FixedLacing) { RunTest(fixed_lacing); }
817
TEST_F(SimpleBlockParserTest,NoLacing)818 TEST_F(SimpleBlockParserTest, NoLacing) { RunTest(no_lacing); }
819
TEST_F(BlockParserTest,SimpleBlockWithPositionAndHeaderSize)820 TEST_F(BlockParserTest, SimpleBlockWithPositionAndHeaderSize) {
821 metadata_.position = 16;
822 metadata_.header_size = 4;
823 RunTest(no_lacing);
824 }
825
TEST_F(SimpleBlockParserTest,IncrementalSimpleBlockFlags)826 TEST_F(SimpleBlockParserTest, IncrementalSimpleBlockFlags) {
827 RunIncrementalTest(simple_block_flags);
828 }
829
TEST_F(SimpleBlockParserTest,IncrementalEbmlLacingOneFrame)830 TEST_F(SimpleBlockParserTest, IncrementalEbmlLacingOneFrame) {
831 RunIncrementalTest(ebml_lacing_one_frame);
832 }
833
TEST_F(SimpleBlockParserTest,IncrementalEbmlLacing)834 TEST_F(SimpleBlockParserTest, IncrementalEbmlLacing) {
835 RunIncrementalTest(ebml_lacing);
836 }
837
TEST_F(SimpleBlockParserTest,IncrementalXiphLacingOneFrame)838 TEST_F(SimpleBlockParserTest, IncrementalXiphLacingOneFrame) {
839 RunIncrementalTest(xiph_lacing_one_frame);
840 }
841
TEST_F(SimpleBlockParserTest,IncrementalXiphLacing)842 TEST_F(SimpleBlockParserTest, IncrementalXiphLacing) {
843 RunIncrementalTest(xiph_lacing);
844 }
845
TEST_F(SimpleBlockParserTest,IncrementalFixedLacingOneFrame)846 TEST_F(SimpleBlockParserTest, IncrementalFixedLacingOneFrame) {
847 RunIncrementalTest(fixed_lacing_one_frame);
848 }
849
TEST_F(SimpleBlockParserTest,IncrementalFixedLacing)850 TEST_F(SimpleBlockParserTest, IncrementalFixedLacing) {
851 RunIncrementalTest(fixed_lacing);
852 }
853
TEST_F(SimpleBlockParserTest,IncrementalNoLacing)854 TEST_F(SimpleBlockParserTest, IncrementalNoLacing) {
855 RunIncrementalTest(no_lacing);
856 }
857
TEST_F(SimpleBlockParserTest,DefaultActionIsRead)858 TEST_F(SimpleBlockParserTest, DefaultActionIsRead) {
859 SetReaderData(fixed_lacing_one_frame.data);
860 SetExpectations(fixed_lacing_one_frame, false, false);
861 ParseAndVerify();
862 ValidateBlock(fixed_lacing_one_frame, parser_.value());
863 }
864
865 } // namespace
866