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 ()__anon7b0cfc470111::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