@@ -214,41 +214,49 @@ ebml_master_elements! {
214
214
} ,
215
215
}
216
216
217
+ #[ derive( Debug ) ]
218
+ struct MasterElementContext {
219
+ element : MasterElement ,
220
+ remaining_length : VInt ,
221
+ }
222
+
223
+ const MAX_DEPTH : u8 = 16 ;
224
+ const ROOT_DEPTH : u8 = 1 ;
225
+
217
226
struct ElementReaderContext {
218
- /// Previous master element
219
- previous_master : Option < MasterElement > ,
220
- previous_master_length : VInt ,
221
- /// Current master element
222
- current_master : Option < MasterElement > ,
223
- /// Remaining length of the master element
224
- master_length : VInt ,
227
+ depth : u8 ,
228
+ masters : Vec < MasterElementContext > ,
225
229
/// Maximum size in octets of all element IDs
226
230
max_id_length : u8 ,
227
231
/// Maximum size in octets of all element data sizes
228
232
max_size_length : u8 ,
229
- /// Whether the reader is locked to the current master element
233
+ /// Whether the reader is locked to the master element at `lock_depth`
230
234
///
231
235
/// This is set with [`ElementReader::lock`], and is used to prevent
232
236
/// the reader from reading past the end of the current master element.
233
237
locked : bool ,
238
+ /// The depth at which we are locked to
239
+ lock_depth : u8 ,
240
+ lock_len : VInt ,
234
241
}
235
242
236
243
impl Default for ElementReaderContext {
237
244
fn default ( ) -> Self {
238
245
Self {
239
- previous_master : None ,
240
- previous_master_length : VInt :: ZERO ,
241
- current_master : None ,
242
- master_length : VInt :: ZERO ,
246
+ depth : 0 ,
247
+ masters : Vec :: with_capacity ( MAX_DEPTH as usize ) ,
243
248
// https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxidlength-element
244
249
max_id_length : 4 ,
245
250
// https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxsizelength-element
246
251
max_size_length : 8 ,
247
252
locked : false ,
253
+ lock_depth : 0 ,
254
+ lock_len : VInt :: ZERO ,
248
255
}
249
256
}
250
257
}
251
258
259
+ #[ derive( Debug ) ]
252
260
pub ( crate ) enum ElementReaderYield {
253
261
Master ( ( ElementIdent , VInt ) ) ,
254
262
Child ( ( ChildElementDescriptor , VInt ) ) ,
@@ -268,8 +276,9 @@ impl ElementReaderYield {
268
276
269
277
pub fn size ( & self ) -> Option < u64 > {
270
278
match self {
271
- ElementReaderYield :: Master ( ( _, size) ) => Some ( size. value ( ) ) ,
272
- ElementReaderYield :: Child ( ( _, size) ) => Some ( size. value ( ) ) ,
279
+ ElementReaderYield :: Master ( ( _, size) ) | ElementReaderYield :: Child ( ( _, size) ) => {
280
+ Some ( size. value ( ) )
281
+ } ,
273
282
ElementReaderYield :: Unknown ( header) => Some ( header. size . value ( ) ) ,
274
283
_ => None ,
275
284
}
@@ -286,8 +295,19 @@ where
286
295
R : Read ,
287
296
{
288
297
fn read ( & mut self , buf : & mut [ u8 ] ) -> std:: io:: Result < usize > {
298
+ if self . ctx . locked {
299
+ let lock_len = self . ctx . lock_len . value ( ) ;
300
+ if buf. len ( ) > lock_len as usize {
301
+ return Err ( std:: io:: Error :: new (
302
+ std:: io:: ErrorKind :: UnexpectedEof ,
303
+ "Cannot read past the end of the current master element" ,
304
+ ) ) ;
305
+ }
306
+ }
307
+
289
308
let ret = self . reader . read ( buf) ?;
290
- self . ctx . master_length = self . ctx . master_length . saturating_sub ( ret as u64 ) ;
309
+ let len = self . current_master_length ( ) ;
310
+ self . set_current_master_length ( len. saturating_sub ( ret as u64 ) ) ;
291
311
Ok ( ret)
292
312
}
293
313
}
@@ -311,16 +331,64 @@ where
311
331
self . ctx . max_size_length = len
312
332
}
313
333
314
- fn store_previous_master ( & mut self ) {
315
- self . ctx . previous_master = self . ctx . current_master ;
316
- self . ctx . previous_master_length = self . ctx . master_length ;
334
+ fn current_master ( & self ) -> Option < MasterElement > {
335
+ if self . ctx . depth == 0 {
336
+ assert ! ( self . ctx. masters. is_empty( ) ) ;
337
+ return None ;
338
+ }
339
+
340
+ Some ( self . ctx . masters [ ( self . ctx . depth - 1 ) as usize ] . element )
317
341
}
318
342
319
- fn goto_next_master ( & mut self ) -> Result < ElementReaderYield > {
320
- if self . ctx . master_length != 0 {
321
- self . skip ( self . ctx . master_length . value ( ) ) ?;
343
+ fn current_master_length ( & self ) -> VInt {
344
+ if self . ctx . depth == 0 {
345
+ assert ! ( self . ctx. masters. is_empty( ) ) ;
346
+ return VInt :: ZERO ;
347
+ }
348
+
349
+ self . ctx . masters [ ( self . ctx . depth - 1 ) as usize ] . remaining_length
350
+ }
351
+
352
+ fn set_current_master_length ( & mut self , length : VInt ) {
353
+ if self . ctx . depth == 0 {
354
+ assert ! ( self . ctx. masters. is_empty( ) ) ;
355
+ return ;
356
+ }
357
+
358
+ if self . ctx . locked {
359
+ self . ctx . lock_len = length;
360
+ }
361
+
362
+ self . ctx . masters [ ( self . ctx . depth - 1 ) as usize ] . remaining_length = length;
363
+ }
364
+
365
+ fn push_new_master ( & mut self , master : MasterElement , size : VInt ) -> Result < ( ) > {
366
+ if self . ctx . depth == MAX_DEPTH {
367
+ decode_err ! ( @BAIL Ebml , "Maximum depth reached" ) ;
322
368
}
323
369
370
+ // If we are at the root level, we do not increment the depth
371
+ // since we are not actually inside a master element.
372
+ // For example, we are moving from \EBML to \Segment.
373
+ let at_root_level = self . ctx . depth == ROOT_DEPTH && self . current_master_length ( ) == 0 ;
374
+ if at_root_level {
375
+ assert_eq ! ( self . ctx. masters. len( ) , 1 ) ;
376
+ self . ctx . masters . clear ( ) ;
377
+ } else {
378
+ self . ctx . depth += 1 ;
379
+ }
380
+
381
+ self . ctx . masters . push ( MasterElementContext {
382
+ element : master,
383
+ remaining_length : size,
384
+ } ) ;
385
+
386
+ Ok ( ( ) )
387
+ }
388
+
389
+ fn goto_next_master ( & mut self ) -> Result < ElementReaderYield > {
390
+ self . exhaust_current_master ( ) ?;
391
+
324
392
let header = ElementHeader :: read (
325
393
& mut self . reader ,
326
394
self . ctx . max_id_length ,
@@ -331,35 +399,34 @@ where
331
399
return Ok ( ElementReaderYield :: Unknown ( header) ) ;
332
400
} ;
333
401
334
- self . store_previous_master ( ) ;
335
- self . ctx . current_master = Some ( * master) ;
336
- self . ctx . master_length = header. size ;
337
- Ok ( ElementReaderYield :: Master ( (
338
- master. id ,
339
- self . ctx . master_length ,
340
- ) ) )
402
+ self . push_new_master ( * master, header. size ) ?;
403
+
404
+ Ok ( ElementReaderYield :: Master ( ( master. id , header. size ) ) )
341
405
}
342
406
343
- pub ( crate ) fn goto_previous_master ( & mut self ) -> Result < ( ) > {
344
- if let Some ( previous_master) = self . ctx . previous_master {
345
- self . ctx . current_master = Some ( previous_master) ;
346
- self . ctx . master_length = self . ctx . previous_master_length ;
347
- Ok ( ( ) )
348
- } else {
349
- decode_err ! ( @BAIL Ebml , "Expected a parent element to be available" )
407
+ fn goto_previous_master ( & mut self ) -> Result < ( ) > {
408
+ if self . ctx . depth == 0 || self . ctx . depth == self . ctx . lock_depth {
409
+ decode_err ! ( @BAIL Ebml , "Cannot go to previous master element, already at root" )
350
410
}
411
+
412
+ self . exhaust_current_master ( ) ?;
413
+
414
+ self . ctx . depth -= 1 ;
415
+ let _ = self . ctx . masters . pop ( ) ;
416
+
417
+ Ok ( ( ) )
351
418
}
352
419
353
420
pub ( crate ) fn next ( & mut self ) -> Result < ElementReaderYield > {
354
- let Some ( current_master) = self . ctx . current_master else {
421
+ let Some ( current_master) = self . current_master ( ) else {
355
422
return self . goto_next_master ( ) ;
356
423
} ;
357
424
358
- if self . ctx . master_length == 0 {
359
- if self . ctx . locked {
360
- return Ok ( ElementReaderYield :: Eof ) ;
361
- }
425
+ if self . ctx . locked && self . ctx . lock_len == 0 {
426
+ return Ok ( ElementReaderYield :: Eof ) ;
427
+ }
362
428
429
+ if self . current_master_length ( ) == 0 {
363
430
return self . goto_next_master ( ) ;
364
431
}
365
432
@@ -374,13 +441,12 @@ where
374
441
} ;
375
442
376
443
if child. data_type == ElementDataType :: Master {
377
- self . store_previous_master ( ) ;
378
- self . ctx . current_master = Some (
444
+ self . push_new_master (
379
445
* master_elements ( )
380
446
. get ( & header. id )
381
447
. expect ( "Nested master elements should be defined at this level." ) ,
382
- ) ;
383
- self . ctx . master_length = header . size ;
448
+ header . size ,
449
+ ) ? ;
384
450
385
451
// We encountered a nested master element
386
452
return Ok ( ElementReaderYield :: Master ( ( child. ident , header. size ) ) ) ;
@@ -389,11 +455,22 @@ where
389
455
Ok ( ElementReaderYield :: Child ( ( * child, header. size ) ) )
390
456
}
391
457
392
- fn lock ( & mut self ) {
458
+ pub ( crate ) fn exhaust_current_master ( & mut self ) -> Result < ( ) > {
459
+ let master_length = self . current_master_length ( ) . value ( ) ;
460
+ if master_length == 0 {
461
+ return Ok ( ( ) ) ;
462
+ }
463
+
464
+ self . skip ( master_length) ?;
465
+ Ok ( ( ) )
466
+ }
467
+
468
+ pub ( crate ) fn lock ( & mut self ) {
393
469
self . ctx . locked = true ;
470
+ self . ctx . lock_len = self . current_master_length ( ) ;
394
471
}
395
472
396
- fn unlock ( & mut self ) {
473
+ pub ( crate ) fn unlock ( & mut self ) {
397
474
self . ctx . locked = false ;
398
475
}
399
476
@@ -403,13 +480,20 @@ where
403
480
}
404
481
405
482
pub ( crate ) fn skip ( & mut self , length : u64 ) -> Result < ( ) > {
483
+ log:: trace!( "Skipping {} bytes" , length) ;
484
+
485
+ let current_master_length = self . current_master_length ( ) ;
486
+ if length > current_master_length. value ( ) {
487
+ decode_err ! ( @BAIL Ebml , "Cannot skip past the end of the current master element" )
488
+ }
489
+
406
490
std:: io:: copy ( & mut self . by_ref ( ) . take ( length) , & mut std:: io:: sink ( ) ) ?;
407
491
Ok ( ( ) )
408
492
}
409
493
410
494
pub ( crate ) fn skip_element ( & mut self , element_header : ElementHeader ) -> Result < ( ) > {
411
495
log:: debug!(
412
- "Encountered unknown EBML element in header : {:X}" ,
496
+ "Encountered unknown EBML element: {:X}, skipping " ,
413
497
element_header. id. 0
414
498
) ;
415
499
self . skip ( element_header. size . value ( ) ) ?;
@@ -445,6 +529,16 @@ where
445
529
Ok ( u64:: from_be_bytes ( buf) )
446
530
}
447
531
532
+ /// Same as `read_unsigned_int`, but will warn if the value is out of range.
533
+ pub ( crate ) fn read_flag ( & mut self , element_length : u64 ) -> Result < bool > {
534
+ let val = self . read_unsigned_int ( element_length) ?;
535
+ if val > 1 {
536
+ log:: warn!( "Flag value `{}` is out of range, assuming true" , val) ;
537
+ }
538
+
539
+ Ok ( val != 0 )
540
+ }
541
+
448
542
pub ( crate ) fn read_float ( & mut self , element_length : u64 ) -> Result < f64 > {
449
543
// https://www.rfc-editor.org/rfc/rfc8794.html#section-7.3
450
544
// A Float Element MUST declare a length of either zero octets (0 bit),
@@ -513,18 +607,16 @@ where
513
607
self . reader . skip_element ( header) ?;
514
608
self . next ( )
515
609
} ,
516
- Ok ( ElementReaderYield :: Eof ) => Ok ( None ) ,
517
610
Err ( e) => Err ( e) ,
518
611
element => element. map ( Some ) ,
519
612
}
520
613
}
521
614
522
615
pub ( crate ) fn master_exhausted ( & self ) -> bool {
523
- self . reader . ctx . master_length == 0
524
- }
616
+ let lock_depth = self . reader . ctx . lock_depth ;
617
+ assert ! ( lock_depth < self . reader . ctx . depth ) ;
525
618
526
- pub ( crate ) fn inner ( & mut self ) -> & mut ElementReader < R > {
527
- self . reader
619
+ self . reader . ctx . masters [ lock_depth as usize ] . remaining_length == 0
528
620
}
529
621
}
530
622
0 commit comments