@@ -214,41 +214,49 @@ ebml_master_elements! {
214214 } ,
215215}
216216
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+
217226struct 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 > ,
225229 /// Maximum size in octets of all element IDs
226230 max_id_length : u8 ,
227231 /// Maximum size in octets of all element data sizes
228232 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`
230234 ///
231235 /// This is set with [`ElementReader::lock`], and is used to prevent
232236 /// the reader from reading past the end of the current master element.
233237 locked : bool ,
238+ /// The depth at which we are locked to
239+ lock_depth : u8 ,
240+ lock_len : VInt ,
234241}
235242
236243impl Default for ElementReaderContext {
237244 fn default ( ) -> Self {
238245 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 ) ,
243248 // https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxidlength-element
244249 max_id_length : 4 ,
245250 // https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxsizelength-element
246251 max_size_length : 8 ,
247252 locked : false ,
253+ lock_depth : 0 ,
254+ lock_len : VInt :: ZERO ,
248255 }
249256 }
250257}
251258
259+ #[ derive( Debug ) ]
252260pub ( crate ) enum ElementReaderYield {
253261 Master ( ( ElementIdent , VInt ) ) ,
254262 Child ( ( ChildElementDescriptor , VInt ) ) ,
@@ -268,8 +276,9 @@ impl ElementReaderYield {
268276
269277 pub fn size ( & self ) -> Option < u64 > {
270278 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+ } ,
273282 ElementReaderYield :: Unknown ( header) => Some ( header. size . value ( ) ) ,
274283 _ => None ,
275284 }
@@ -286,8 +295,19 @@ where
286295 R : Read ,
287296{
288297 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+
289308 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 ) ) ;
291311 Ok ( ret)
292312 }
293313}
@@ -311,16 +331,64 @@ where
311331 self . ctx . max_size_length = len
312332 }
313333
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 )
317341 }
318342
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" ) ;
322368 }
323369
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+
324392 let header = ElementHeader :: read (
325393 & mut self . reader ,
326394 self . ctx . max_id_length ,
@@ -331,35 +399,34 @@ where
331399 return Ok ( ElementReaderYield :: Unknown ( header) ) ;
332400 } ;
333401
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 ) ) )
341405 }
342406
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" )
350410 }
411+
412+ self . exhaust_current_master ( ) ?;
413+
414+ self . ctx . depth -= 1 ;
415+ let _ = self . ctx . masters . pop ( ) ;
416+
417+ Ok ( ( ) )
351418 }
352419
353420 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 {
355422 return self . goto_next_master ( ) ;
356423 } ;
357424
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+ }
362428
429+ if self . current_master_length ( ) == 0 {
363430 return self . goto_next_master ( ) ;
364431 }
365432
@@ -374,13 +441,12 @@ where
374441 } ;
375442
376443 if child. data_type == ElementDataType :: Master {
377- self . store_previous_master ( ) ;
378- self . ctx . current_master = Some (
444+ self . push_new_master (
379445 * master_elements ( )
380446 . get ( & header. id )
381447 . expect ( "Nested master elements should be defined at this level." ) ,
382- ) ;
383- self . ctx . master_length = header . size ;
448+ header . size ,
449+ ) ? ;
384450
385451 // We encountered a nested master element
386452 return Ok ( ElementReaderYield :: Master ( ( child. ident , header. size ) ) ) ;
@@ -389,11 +455,22 @@ where
389455 Ok ( ElementReaderYield :: Child ( ( * child, header. size ) ) )
390456 }
391457
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 ) {
393469 self . ctx . locked = true ;
470+ self . ctx . lock_len = self . current_master_length ( ) ;
394471 }
395472
396- fn unlock ( & mut self ) {
473+ pub ( crate ) fn unlock ( & mut self ) {
397474 self . ctx . locked = false ;
398475 }
399476
@@ -403,13 +480,20 @@ where
403480 }
404481
405482 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+
406490 std:: io:: copy ( & mut self . by_ref ( ) . take ( length) , & mut std:: io:: sink ( ) ) ?;
407491 Ok ( ( ) )
408492 }
409493
410494 pub ( crate ) fn skip_element ( & mut self , element_header : ElementHeader ) -> Result < ( ) > {
411495 log:: debug!(
412- "Encountered unknown EBML element in header : {:X}" ,
496+ "Encountered unknown EBML element: {:X}, skipping " ,
413497 element_header. id. 0
414498 ) ;
415499 self . skip ( element_header. size . value ( ) ) ?;
@@ -445,6 +529,16 @@ where
445529 Ok ( u64:: from_be_bytes ( buf) )
446530 }
447531
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+
448542 pub ( crate ) fn read_float ( & mut self , element_length : u64 ) -> Result < f64 > {
449543 // https://www.rfc-editor.org/rfc/rfc8794.html#section-7.3
450544 // A Float Element MUST declare a length of either zero octets (0 bit),
@@ -513,18 +607,16 @@ where
513607 self . reader . skip_element ( header) ?;
514608 self . next ( )
515609 } ,
516- Ok ( ElementReaderYield :: Eof ) => Ok ( None ) ,
517610 Err ( e) => Err ( e) ,
518611 element => element. map ( Some ) ,
519612 }
520613 }
521614
522615 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 ) ;
525618
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
528620 }
529621}
530622
0 commit comments